@@ -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