1
1
import * as path from "path" ;
2
2
import * as semver from "semver" ;
3
3
import * as constants from "../constants" ;
4
- import { BaseUpdateController } from "./base- update-controller" ;
4
+ import { UpdateControllerBase } from "./update-controller-base " ;
5
5
6
- export class MigrateController extends BaseUpdateController implements IMigrateController {
6
+ export class MigrateController extends UpdateControllerBase implements IMigrateController {
7
7
constructor (
8
8
protected $fs : IFileSystem ,
9
9
protected $platformCommandHelper : IPlatformCommandHelper ,
@@ -12,6 +12,7 @@ export class MigrateController extends BaseUpdateController implements IMigrateC
12
12
protected $packageManager : IPackageManager ,
13
13
private $devicePlatformsConstants : Mobile . IDevicePlatformsConstants ,
14
14
private $logger : ILogger ,
15
+ private $errors : IErrors ,
15
16
private $addPlatformService : IAddPlatformService ,
16
17
private $pluginsService : IPluginsService ,
17
18
private $projectDataService : IProjectDataService ) {
@@ -28,15 +29,15 @@ export class MigrateController extends BaseUpdateController implements IMigrateC
28
29
] ;
29
30
30
31
static readonly migrationDependencies : IMigrationDependency [ ] = [
31
- { packageName : constants . TNS_CORE_MODULES_NAME , isDev : false , verifiedVersion : "6.0.0-next-2019-06-10-092158-01" } ,
32
- { packageName : constants . TNS_CORE_MODULES_WIDGETS_NAME , isDev : false , verifiedVersion : "6.0.0-next-2019-06-10-092158-01" } ,
32
+ { packageName : constants . TNS_CORE_MODULES_NAME , verifiedVersion : "6.0.0-next-2019-06-10-092158-01" } ,
33
+ { packageName : constants . TNS_CORE_MODULES_WIDGETS_NAME , verifiedVersion : "6.0.0-next-2019-06-10-092158-01" } ,
33
34
{ packageName : "node-sass" , isDev : true , verifiedVersion : "4.12.0" } ,
34
35
{ packageName : "typescript" , isDev : true , verifiedVersion : "3.4.1" } ,
35
36
{ packageName : "less" , isDev : true , verifiedVersion : "3.9.0" } ,
36
37
{ packageName : "nativescript-dev-sass" , isDev : true , replaceWith : "node-sass" } ,
37
38
{ packageName : "nativescript-dev-typescript" , isDev : true , replaceWith : "typescript" } ,
38
39
{ packageName : "nativescript-dev-less" , isDev : true , replaceWith : "less" } ,
39
- { packageName : constants . WEBPACK_PLUGIN_NAME , isDev : true , shouldAdd : true , verifiedVersion : "0.25.0-webpack-2019-06-11-105349-01" } ,
40
+ { packageName : constants . WEBPACK_PLUGIN_NAME , isDev : true , shouldAddIfMissing : true , verifiedVersion : "0.25.0-webpack-2019-06-11-105349-01" } ,
40
41
{ packageName : "nativescript-camera" , verifiedVersion : "4.5.0" } ,
41
42
{ packageName : "nativescript-geolocation" , verifiedVersion : "5.1.0" } ,
42
43
{ packageName : "nativescript-imagepicker" , verifiedVersion : "6.2.0" } ,
@@ -50,16 +51,16 @@ export class MigrateController extends BaseUpdateController implements IMigrateC
50
51
{ packageName : "nativescript-ui-autocomplete" , verifiedVersion : "5.0.0-androidx-110619" } ,
51
52
{ packageName : "nativescript-datetimepicker" , verifiedVersion : "1.1.0" } ,
52
53
//TODO update with compatible with webpack only hooks
53
- { packageName : "kinvey-nativescript-sdk" , verifiedVersion : "4.1.0 " } ,
54
+ { packageName : "kinvey-nativescript-sdk" , verifiedVersion : "4.2.1 " } ,
54
55
//TODO update with compatible with webpack only hooks
55
- { packageName : "nativescript-plugin-firebase" , verifiedVersion : "8.3.2 " } ,
56
+ { packageName : "nativescript-plugin-firebase" , verifiedVersion : "9.0.1 " } ,
56
57
//TODO update with no prerelease version compatible with webpack only hooks
57
58
{ packageName : "nativescript-vue" , verifiedVersion : "2.3.0-rc.0" } ,
58
59
{ packageName : "nativescript-permissions" , verifiedVersion : "1.3.0" } ,
59
60
{ packageName : "nativescript-cardview" , verifiedVersion : "3.2.0" }
60
61
] ;
61
62
62
- static readonly tempFolder : string = ".migration_backup" ;
63
+ static readonly backupFolder : string = ".migration_backup" ;
63
64
static readonly migrateFailMessage : string = "Could not migrate the project!" ;
64
65
static readonly backupFailMessage : string = "Could not backup project folders!" ;
65
66
@@ -72,42 +73,50 @@ export class MigrateController extends BaseUpdateController implements IMigrateC
72
73
73
74
public async migrate ( { projectDir} : { projectDir : string } ) : Promise < void > {
74
75
const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
75
- const tmpDir = path . join ( projectDir , MigrateController . tempFolder ) ;
76
+ const backupDir = path . join ( projectDir , MigrateController . backupFolder ) ;
76
77
77
78
try {
78
79
this . $logger . info ( "Backup project configuration." ) ;
79
- this . backup ( MigrateController . folders , tmpDir , projectData ) ;
80
+ this . backup ( MigrateController . folders , backupDir , projectData . projectDir ) ;
80
81
this . $logger . info ( "Backup project configuration complete." ) ;
81
82
} catch ( error ) {
82
83
this . $logger . error ( MigrateController . backupFailMessage ) ;
83
- this . $fs . deleteDirectory ( tmpDir ) ;
84
+ this . $fs . deleteDirectory ( backupDir ) ;
84
85
return ;
85
86
}
86
87
87
88
try {
88
89
await this . cleanUpProject ( projectData ) ;
89
90
await this . migrateDependencies ( projectData ) ;
90
91
} catch ( error ) {
91
- this . restoreBackup ( MigrateController . folders , tmpDir , projectData ) ;
92
+ this . restoreBackup ( MigrateController . folders , backupDir , projectData . projectDir ) ;
92
93
this . $logger . error ( MigrateController . migrateFailMessage ) ;
93
94
}
94
95
}
95
96
96
97
public async shouldMigrate ( { projectDir} : IProjectDir ) : Promise < boolean > {
97
98
const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
99
+
98
100
for ( let i = 0 ; i < MigrateController . migrationDependencies . length ; i ++ ) {
99
101
const dependency = MigrateController . migrationDependencies [ i ] ;
100
- const collection = dependency . isDev ? projectData . devDependencies : projectData . dependencies ;
101
- if ( dependency . replaceWith && collection && collection [ dependency . packageName ] ) {
102
+ const hasDependency = this . hasDependency ( dependency , projectData ) ;
103
+
104
+ if ( hasDependency && dependency . replaceWith ) {
105
+ return true ;
106
+ }
107
+
108
+ if ( hasDependency && await this . shouldMigrateDependencyVersion ( dependency , projectData ) ) {
102
109
return true ;
103
110
}
104
111
105
- if ( ! this . shouldSkipMigrationDependency ( dependency , projectData ) && await this . shouldMigrateDependencyVersion ( dependency , projectData ) ) {
112
+ if ( ! hasDependency && dependency . shouldAddIfMissing ) {
106
113
return true ;
107
114
}
108
115
}
116
+
109
117
for ( const platform in this . $devicePlatformsConstants ) {
110
- if ( await this . shouldUpdateRuntimeVersion ( { targetVersion : this . verifiedPlatformVersions [ platform . toLowerCase ( ) ] , platform, projectData, shouldAdd : true } ) ) {
118
+ const hasRuntimeDependency = this . hasRuntimeDependency ( { platform, projectData} ) ;
119
+ if ( ! hasRuntimeDependency || await this . shouldUpdateRuntimeVersion ( { targetVersion : this . verifiedPlatformVersions [ platform . toLowerCase ( ) ] , platform, projectData} ) ) {
111
120
return true ;
112
121
}
113
122
}
@@ -125,27 +134,39 @@ export class MigrateController extends BaseUpdateController implements IMigrateC
125
134
}
126
135
127
136
private async migrateDependencies ( projectData : IProjectData ) : Promise < void > {
128
- this . $logger . info ( "Start migrating dependencies." ) ;
137
+ this . $logger . info ( "Start dependencies migration ." ) ;
129
138
for ( let i = 0 ; i < MigrateController . migrationDependencies . length ; i ++ ) {
130
139
const dependency = MigrateController . migrationDependencies [ i ] ;
131
- if ( this . shouldSkipMigrationDependency ( dependency , projectData ) ) {
132
- continue ;
133
- }
140
+ const hasDependency = this . hasDependency ( dependency , projectData ) ;
134
141
135
- if ( dependency . replaceWith ) {
142
+ if ( hasDependency && dependency . replaceWith ) {
136
143
this . $pluginsService . removeFromPackageJson ( dependency . packageName , dependency . isDev , projectData . projectDir ) ;
137
144
const replacementDep = _ . find ( MigrateController . migrationDependencies , migrationPackage => migrationPackage . packageName === dependency . replaceWith ) ;
145
+ if ( ! replacementDep ) {
146
+ this . $errors . failWithoutHelp ( "Failed to find replacement dependency." ) ;
147
+ }
138
148
this . $logger . info ( `Replacing '${ dependency . packageName } ' with '${ replacementDep . packageName } '.` , ) ;
139
149
this . $pluginsService . addToPackageJson ( replacementDep . packageName , replacementDep . verifiedVersion , replacementDep . isDev , projectData . projectDir ) ;
140
- } else if ( await this . shouldMigrateDependencyVersion ( dependency , projectData ) ) {
150
+ continue ;
151
+ }
152
+
153
+ if ( hasDependency && await this . shouldMigrateDependencyVersion ( dependency , projectData ) ) {
141
154
this . $logger . info ( `Updating '${ dependency . packageName } ' to compatible version '${ dependency . verifiedVersion } '` ) ;
142
155
this . $pluginsService . addToPackageJson ( dependency . packageName , dependency . verifiedVersion , dependency . isDev , projectData . projectDir ) ;
156
+ continue ;
157
+ }
158
+
159
+ if ( ! hasDependency && dependency . shouldAddIfMissing ) {
160
+ this . $logger . info ( `Adding '${ dependency . packageName } ' with version '${ dependency . verifiedVersion } '` ) ;
161
+ this . $pluginsService . addToPackageJson ( dependency . packageName , dependency . verifiedVersion , dependency . isDev , projectData . projectDir ) ;
162
+ continue ;
143
163
}
144
164
}
145
165
146
166
for ( const platform in this . $devicePlatformsConstants ) {
147
167
const lowercasePlatform = platform . toLowerCase ( ) ;
148
- if ( await this . shouldUpdateRuntimeVersion ( { targetVersion : this . verifiedPlatformVersions [ lowercasePlatform ] , platform, projectData, shouldAdd : true } ) ) {
168
+ const hasRuntimeDependency = this . hasRuntimeDependency ( { platform, projectData} ) ;
169
+ if ( ! hasRuntimeDependency || await this . shouldUpdateRuntimeVersion ( { targetVersion : this . verifiedPlatformVersions [ lowercasePlatform ] , platform, projectData} ) ) {
149
170
const verifiedPlatformVersion = this . verifiedPlatformVersions [ lowercasePlatform ] ;
150
171
const platformData = this . $platformsDataService . getPlatformData ( lowercasePlatform , projectData ) ;
151
172
this . $logger . info ( `Updating ${ platform } platform to version '${ verifiedPlatformVersion } '.` ) ;
@@ -166,38 +187,15 @@ export class MigrateController extends BaseUpdateController implements IMigrateC
166
187
167
188
private async shouldMigrateDependencyVersion ( dependency : IMigrationDependency , projectData : IProjectData ) : Promise < boolean > {
168
189
const collection = dependency . isDev ? projectData . devDependencies : projectData . dependencies ;
169
- if (
170
- collection &&
171
- collection [ dependency . packageName ]
172
- ) {
173
- const maxSatisfyingVersion = await this . getMaxDependencyVersion ( dependency . packageName , collection [ dependency . packageName ] ) ;
174
- if ( maxSatisfyingVersion ) {
175
- const isPrereleaseVersion = semver . prerelease ( maxSatisfyingVersion ) ;
176
- const coerceMaxSatisfying = semver . coerce ( maxSatisfyingVersion ) . version ;
177
- const coerceVerifiedVersion = semver . coerce ( dependency . verifiedVersion ) . version ;
178
- //This makes sure that if the user has a prerelease 6.0.0-next-2019-06-10-092158-01 version we will update it to 6.0.0
179
- if ( isPrereleaseVersion ) {
180
- if ( semver . gt ( coerceMaxSatisfying , coerceVerifiedVersion ) ) {
181
- return false ;
182
- }
183
-
184
- //TODO This should be removed once we update the verified versions to no prerelease versions
185
- if ( semver . eq ( maxSatisfyingVersion , dependency . verifiedVersion ) ) {
186
- return false ;
187
- }
188
- } else if ( semver . gte ( coerceMaxSatisfying , coerceVerifiedVersion ) ) {
189
- return false ;
190
- }
191
- }
192
- }
190
+ const maxSatisfyingVersion = await this . getMaxDependencyVersion ( dependency . packageName , collection [ dependency . packageName ] ) ;
193
191
194
- return true ;
192
+ return ! ( maxSatisfyingVersion && semver . gte ( maxSatisfyingVersion , dependency . verifiedVersion ) ) ;
195
193
}
196
194
197
- private shouldSkipMigrationDependency ( dependency : IMigrationDependency , projectData : IProjectData ) {
198
- if ( ! dependency . shouldAdd ) {
199
- return this . shouldSkipDependency ( dependency , projectData ) ;
200
- }
195
+ protected async shouldUpdateRuntimeVersion ( { targetVersion , platform , projectData } : { targetVersion : string , platform : string , projectData : IProjectData } ) : Promise < boolean > {
196
+ const maxRuntimeVersion = await this . getMaxRuntimeVersion ( { platform , projectData } ) ;
197
+
198
+ return ! ( maxRuntimeVersion && semver . gte ( maxRuntimeVersion , targetVersion ) ) ;
201
199
}
202
200
}
203
201
0 commit comments