nativescript
Version:
Command-line interface for building NativeScript projects
174 lines • 7.97 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.UpdateController = void 0;
const semver = require("semver");
const constants = require("../constants");
const update_controller_base_1 = require("./update-controller-base");
const yok_1 = require("../common/yok");
const constants_1 = require("../constants");
const color_1 = require("../color");
class UpdateController extends update_controller_base_1.UpdateControllerBase {
constructor($fs, $platformsDataService, $platformCommandHelper, $packageInstallationManager, $packageManager, $pluginsService, $pacoteService, $logger, $errors, $projectDataService, $projectBackupService, $projectCleanupService, $terminalSpinnerService) {
super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager, $pacoteService);
this.$fs = $fs;
this.$platformsDataService = $platformsDataService;
this.$platformCommandHelper = $platformCommandHelper;
this.$packageInstallationManager = $packageInstallationManager;
this.$packageManager = $packageManager;
this.$pluginsService = $pluginsService;
this.$pacoteService = $pacoteService;
this.$logger = $logger;
this.$errors = $errors;
this.$projectDataService = $projectDataService;
this.$projectBackupService = $projectBackupService;
this.$projectCleanupService = $projectCleanupService;
this.$terminalSpinnerService = $terminalSpinnerService;
}
async update(updateOptions) {
this.spinner = this.$terminalSpinnerService.createSpinner();
const projectData = this.$projectDataService.getProjectData(updateOptions.projectDir);
updateOptions.version = updateOptions.version || constants_1.PackageVersion.LATEST;
// back up project files and folders
this.spinner.info("Backing up project files before update");
await this.backupProject();
this.spinner.succeed("Project files have been backed up");
// clean up project files
this.spinner.info("Cleaning up project files before update");
await this.cleanUpProject();
this.spinner.succeed("Project files have been cleaned up");
// update dependencies
this.spinner.info("Updating project dependencies");
await this.updateDependencies(projectData, updateOptions.version);
this.spinner.succeed("Project dependencies have been updated");
this.spinner.succeed("Update complete.");
this.$logger.info("");
this.$logger.printMarkdown("Project has been successfully updated. The next step is to run `ns run <platform>` to ensure everything is working properly." +
"\n\nPlease note that you may need additional changes to complete the update.");
}
async shouldUpdate(updateOptions) {
const projectData = this.$projectDataService.getProjectData(updateOptions.projectDir);
updateOptions.version = updateOptions.version || constants_1.PackageVersion.LATEST;
for (const dependency of UpdateController.updatableDependencies) {
this.$logger.trace(`Checking if ${dependency.packageName} needs to be updated...`);
const desiredVersion = await this.getVersionFromTagOrVersion(dependency.packageName, updateOptions.version);
if (typeof desiredVersion === "boolean") {
this.$logger.trace(`Package ${dependency.packageName} does not have version/tag ${updateOptions.version}. Skipping.`);
continue;
}
const shouldUpdate = await this.shouldUpdateDependency(projectData, dependency, desiredVersion);
if (shouldUpdate) {
this.$logger.trace(`shouldUpdate is true because '${dependency.packageName} needs to be updated.'`);
return true;
}
}
return false;
}
async updateDependencies(projectData, version) {
for (const dependency of UpdateController.updatableDependencies) {
await this.updateDependency(projectData, dependency, version);
}
}
async updateDependency(projectData, dependency, version) {
if (!this.hasDependency(dependency, projectData)) {
return;
}
const desiredVersion = await this.getVersionFromTagOrVersion(dependency.packageName, version);
if (typeof desiredVersion === "boolean") {
this.$logger.info(` - ${color_1.color.yellow(dependency.packageName)} does not have version/tag ${color_1.color.green(version)}. ` +
color_1.color.yellow("Skipping."));
return;
}
const shouldUpdate = await this.shouldUpdateDependency(projectData, dependency, desiredVersion);
if (!shouldUpdate) {
return;
}
// check if the coerced version is the same as desired and prefix it with a ~
// for example:
// 8.0.0 -> ~8.0.0
// 8.0.8-next-XXX -> 8.0.8-next-XXX
const updatedVersion = (() => {
if (desiredVersion === version) {
return desiredVersion;
}
if (semver.coerce(desiredVersion).version === desiredVersion) {
return `~${desiredVersion}`;
}
return desiredVersion;
})();
this.$pluginsService.addToPackageJson(dependency.packageName, updatedVersion, dependency.isDev, projectData.projectDir);
this.$logger.info(` - ${color_1.color.yellow(dependency.packageName)} has been updated to ${color_1.color.green(updatedVersion)}`);
}
async shouldUpdateDependency(projectData, dependency, desiredVersion) {
const installedVersion = await this.$packageInstallationManager.getInstalledDependencyVersion(dependency.packageName, projectData.projectDir);
if (!installedVersion) {
return false;
}
return installedVersion != desiredVersion;
}
async getVersionFromTagOrVersion(packageName, versionOrTag) {
if (semver.valid(versionOrTag) || semver.validRange(versionOrTag)) {
return versionOrTag;
}
const version = await this.$packageManager.getTagVersion(packageName, versionOrTag);
if (!version) {
return false;
}
return version;
}
async backupProject() {
const backup = this.$projectBackupService.getBackup("migration");
backup.addPaths([...UpdateController.pathsToBackup]);
try {
return backup.create();
}
catch (error) {
this.spinner.fail(`Project backup failed.`);
backup.remove();
this.$errors.fail(`Project backup failed. Error is: ${error.message}`);
}
}
async cleanUpProject() {
await this.$projectCleanupService.clean([
constants.HOOKS_DIR_NAME,
constants.PLATFORMS_DIR_NAME,
constants.NODE_MODULES_FOLDER_NAME,
constants.PACKAGE_LOCK_JSON_FILE_NAME,
]);
}
}
exports.UpdateController = UpdateController;
UpdateController.updatableDependencies = [
// dependencies
{
packageName: "@nativescript/core",
},
// devDependencies
{
packageName: "@nativescript/webpack",
isDev: true,
},
{
packageName: "@nativescript/types",
isDev: true,
},
// runtimes
{
packageName: "@nativescript/ios",
isDev: true,
},
{
packageName: "@nativescript/android",
isDev: true,
},
];
UpdateController.backupFolderName = ".migration_backup";
UpdateController.pathsToBackup = [
constants.LIB_DIR_NAME,
constants.HOOKS_DIR_NAME,
constants.WEBPACK_CONFIG_NAME,
constants.PACKAGE_JSON_FILE_NAME,
constants.PACKAGE_LOCK_JSON_FILE_NAME,
constants.CONFIG_NS_FILE_NAME,
];
yok_1.injector.register("updateController", UpdateController);
//# sourceMappingURL=update-controller.js.map