@@ -6,14 +6,15 @@ import { UpdateControllerBase } from "./update-controller-base";
66interface IPackage {
77 name : string ;
88 alias ?: string ;
9+ isDev ?: boolean ;
910}
1011
1112export class UpdateController extends UpdateControllerBase implements IUpdateController {
1213 static readonly updatableDependencies : IPackage [ ] = [
1314 { name : constants . SCOPED_TNS_CORE_MODULES , alias : constants . TNS_CORE_MODULES_NAME } ,
1415 { name : constants . TNS_CORE_MODULES_NAME } ,
1516 { name : constants . TNS_CORE_MODULES_WIDGETS_NAME } ,
16- { name : constants . WEBPACK_PLUGIN_NAME } ] ;
17+ { name : constants . WEBPACK_PLUGIN_NAME , isDev : true } ] ;
1718 static readonly folders : string [ ] = [
1819 constants . LIB_DIR_NAME ,
1920 constants . HOOKS_DIR_NAME ,
@@ -60,11 +61,16 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon
6061 await this . updateProject ( projectData , updateOptions . version ) ;
6162 } catch ( error ) {
6263 this . restoreBackup ( UpdateController . folders , backupDir , projectData . projectDir ) ;
63- this . $logger . error ( UpdateController . updateFailMessage ) ;
64+ this . $logger . error ( ` ${ UpdateController . updateFailMessage } Reason is: ${ error . message } ` ) ;
6465 }
6566 }
6667
6768 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+
6874 const projectData = this . $projectDataService . getProjectData ( projectDir ) ;
6975 const templateManifest = await this . getTemplateManifest ( projectData , version ) ;
7076 const dependencies = this . getUpdatableDependencies ( templateManifest . dependencies ) ;
@@ -103,7 +109,14 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon
103109 }
104110
105111 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+
107120 const dependencies = this . getUpdatableDependencies ( templateManifest . dependencies ) ;
108121 const devDependencies = this . getUpdatableDependencies ( templateManifest . devDependencies ) ;
109122
@@ -127,6 +140,49 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon
127140 } ) ;
128141 }
129142
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+
130186 private async updateDependencies ( { dependencies, areDev, projectData } : { dependencies : IDictionary < string > , areDev : boolean , projectData : IProjectData } ) {
131187 for ( const dependency in dependencies ) {
132188 const templateVersion = dependencies [ dependency ] ;
0 commit comments