@@ -6,14 +6,15 @@ import { UpdateControllerBase } from "./update-controller-base";
6
6
interface IPackage {
7
7
name : string ;
8
8
alias ?: string ;
9
+ isDev ?: boolean ;
9
10
}
10
11
11
12
export class UpdateController extends UpdateControllerBase implements IUpdateController {
12
13
static readonly updatableDependencies : IPackage [ ] = [
13
14
{ name : constants . SCOPED_TNS_CORE_MODULES , alias : constants . TNS_CORE_MODULES_NAME } ,
14
15
{ name : constants . TNS_CORE_MODULES_NAME } ,
15
16
{ name : constants . TNS_CORE_MODULES_WIDGETS_NAME } ,
16
- { name : constants . WEBPACK_PLUGIN_NAME } ] ;
17
+ { name : constants . WEBPACK_PLUGIN_NAME , isDev : true } ] ;
17
18
static readonly folders : string [ ] = [
18
19
constants . LIB_DIR_NAME ,
19
20
constants . HOOKS_DIR_NAME ,
@@ -60,11 +61,16 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon
60
61
await this . updateProject ( projectData , updateOptions . version ) ;
61
62
} catch ( error ) {
62
63
this . restoreBackup ( UpdateController . folders , backupDir , projectData . projectDir ) ;
63
- this . $logger . error ( UpdateController . updateFailMessage ) ;
64
+ this . $logger . error ( ` ${ UpdateController . updateFailMessage } Reason is: ${ error . message } ` ) ;
64
65
}
65
66
}
66
67
67
68
public async shouldUpdate ( { projectDir, version } : { projectDir : string , version ?: string } ) : Promise < boolean > {
69
+ if ( version && ! semver . valid ( version ) && ! semver . validRange ( version ) ) {
70
+ // probably npm tag here
71
+ return true ;
72
+ }
73
+
68
74
const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
69
75
const templateManifest = await this . getTemplateManifest ( projectData , version ) ;
70
76
const dependencies = this . getUpdatableDependencies ( templateManifest . dependencies ) ;
@@ -103,7 +109,14 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon
103
109
}
104
110
105
111
private async updateProject ( projectData : IProjectData , version : string ) : Promise < void > {
106
- const templateManifest = await this . getTemplateManifest ( projectData , version ) ;
112
+ let templateManifest : any = { } ;
113
+
114
+ if ( ! version || semver . valid ( version ) || semver . validRange ( version ) ) {
115
+ templateManifest = await this . getTemplateManifest ( projectData , version ) ;
116
+ } else {
117
+ templateManifest = await this . constructTemplateManifestForTag ( version ) ;
118
+ }
119
+
107
120
const dependencies = this . getUpdatableDependencies ( templateManifest . dependencies ) ;
108
121
const devDependencies = this . getUpdatableDependencies ( templateManifest . devDependencies ) ;
109
122
@@ -127,6 +140,49 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon
127
140
} ) ;
128
141
}
129
142
143
+ private async constructTemplateManifestForTag ( tag : string ) : Promise < any > {
144
+ this . $logger . trace ( `Will construct manually template manifest for tag ${ tag } ` ) ;
145
+
146
+ const templateManifest : any = { } ;
147
+ templateManifest . dependencies = { } ;
148
+ templateManifest . devDependencies = { } ;
149
+ for ( const updatableDependency of UpdateController . updatableDependencies ) {
150
+ const version = await this . getVersionFromTag ( updatableDependency . name , tag ) ;
151
+ if ( ! version ) {
152
+ this . $errors . fail ( `Unable to execute update as package '${ updatableDependency . name } ' does not have version or tag '${ tag } '` ) ;
153
+ }
154
+
155
+ const dictionaryToModify = updatableDependency . isDev ? templateManifest . devDependencies : templateManifest . dependencies ;
156
+ dictionaryToModify [ updatableDependency . name ] = version ;
157
+ if ( updatableDependency . alias ) {
158
+ const aliasVersion = await this . getVersionFromTag ( updatableDependency . name , tag ) ;
159
+ dictionaryToModify [ updatableDependency . alias ] = aliasVersion ;
160
+ }
161
+ }
162
+
163
+ templateManifest . nativescript = {
164
+ [ constants . TNS_ANDROID_RUNTIME_NAME ] : {
165
+ version : await this . getVersionFromTag ( constants . TNS_ANDROID_RUNTIME_NAME , tag )
166
+ } ,
167
+ [ constants . TNS_IOS_RUNTIME_NAME ] : {
168
+ version : await this . $packageManager . getTagVersion ( constants . TNS_IOS_RUNTIME_NAME , tag )
169
+ }
170
+ } ;
171
+
172
+ this . $logger . trace ( `Manually constructed template manifest for tag ${ tag } . Content is: ${ JSON . stringify ( templateManifest , null , 2 ) } ` ) ;
173
+
174
+ return templateManifest ;
175
+ }
176
+
177
+ private async getVersionFromTag ( packageName : string , tag : string ) : Promise < string > {
178
+ const version = await this . $packageManager . getTagVersion ( packageName , tag ) ;
179
+ if ( ! version ) {
180
+ this . $errors . fail ( `Unable to execute update as package ${ packageName } does not have version/tag ${ tag } . Please enter valid version or npm tag.` ) ;
181
+ }
182
+
183
+ return version ;
184
+ }
185
+
130
186
private async updateDependencies ( { dependencies, areDev, projectData } : { dependencies : IDictionary < string > , areDev : boolean , projectData : IProjectData } ) {
131
187
for ( const dependency in dependencies ) {
132
188
const templateVersion = dependencies [ dependency ] ;
0 commit comments