From 1c73c8fa0f45a9ca0562d7deeeb6a468cd5b5f77 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 3 Jul 2019 08:41:41 +0300 Subject: [PATCH 01/69] feat: validate the version of nativescript-dev-webpack on each command --- lib/common/services/commands-service.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/common/services/commands-service.ts b/lib/common/services/commands-service.ts index b4bb6566d0..294ccd6fba 100644 --- a/lib/common/services/commands-service.ts +++ b/lib/common/services/commands-service.ts @@ -28,7 +28,8 @@ export class CommandsService implements ICommandsService { private $helpService: IHelpService, private $extensibilityService: IExtensibilityService, private $optionsTracker: IOptionsTracker, - private $projectDataService: IProjectDataService) { + private $projectDataService: IProjectDataService, + private $bundleValidatorHelper: IBundleValidatorHelper) { } public allCommands(opts: { includeDevCommands: boolean }): string[] { @@ -115,6 +116,8 @@ export class CommandsService implements ICommandsService { const dashedOptions = command ? command.dashedOptions : null; this.$options.validateOptions(dashedOptions, projectData); + + this.$bundleValidatorHelper.validate(projectData, "1.0.0"); } return this.canExecuteCommand(commandName, commandArguments); From ac63ef68f0e951961fc6eb624b775d311d17aaa2 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 3 Jul 2019 08:44:01 +0300 Subject: [PATCH 02/69] fix: remove bundle plugin validation from commands As we've already moved the logic for validation the version of nativescript-dev-webpack plugin to commandsService, there is no need to validate it again from commands. --- lib/commands/build.ts | 10 ++-------- lib/commands/debug.ts | 5 ----- lib/commands/deploy.ts | 2 -- lib/commands/preview.ts | 3 --- lib/helpers/livesync-command-helper.ts | 6 ------ 5 files changed, 2 insertions(+), 24 deletions(-) diff --git a/lib/commands/build.ts b/lib/commands/build.ts index 6acdb2c8f0..c665231967 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -9,7 +9,6 @@ export abstract class BuildCommandBase extends ValidatePlatformCommandBase { protected $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, protected $buildController: IBuildController, $platformValidationService: IPlatformValidationService, - private $bundleValidatorHelper: IBundleValidatorHelper, private $buildDataService: IBuildDataService, protected $logger: ILogger) { super($options, $platformsDataService, $platformValidationService, $projectData); @@ -33,8 +32,6 @@ export abstract class BuildCommandBase extends ValidatePlatformCommandBase { if (!this.$platformValidationService.isPlatformSupportedForOS(platform, this.$projectData)) { this.$errors.fail(`Applications for platform ${platform} can not be built on this OS`); } - - this.$bundleValidatorHelper.validate(this.$projectData); } protected async validateArgs(args: string[], platform: string): Promise { @@ -65,10 +62,9 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, $buildController: IBuildController, $platformValidationService: IPlatformValidationService, - $bundleValidatorHelper: IBundleValidatorHelper, $logger: ILogger, $buildDataService: IBuildDataService) { - super($options, $errors, $projectData, $platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $bundleValidatorHelper, $buildDataService, $logger); + super($options, $errors, $projectData, $platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); } public async execute(args: string[]): Promise { @@ -101,11 +97,10 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, $buildController: IBuildController, $platformValidationService: IPlatformValidationService, - $bundleValidatorHelper: IBundleValidatorHelper, protected $androidBundleValidatorHelper: IAndroidBundleValidatorHelper, $buildDataService: IBuildDataService, protected $logger: ILogger) { - super($options, $errors, $projectData, platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $bundleValidatorHelper, $buildDataService, $logger); + super($options, $errors, $projectData, platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); } public async execute(args: string[]): Promise { @@ -122,7 +117,6 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { public async canExecute(args: string[]): Promise { const platform = this.$devicePlatformsConstants.Android; - super.validatePlatform(platform); this.$androidBundleValidatorHelper.validateRuntimeVersion(this.$projectData); let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true } }); if (result.canExecute) { diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts index 3317b632df..f606d9b418 100644 --- a/lib/commands/debug.ts +++ b/lib/commands/debug.ts @@ -1,12 +1,10 @@ import { cache } from "../common/decorators"; import { ValidatePlatformCommandBase } from "./command-base"; -import { LiveSyncCommandHelper } from "../helpers/livesync-command-helper"; export class DebugPlatformCommand extends ValidatePlatformCommandBase implements ICommand { public allowedParameters: ICommandParameter[] = []; constructor(private platform: string, - private $bundleValidatorHelper: IBundleValidatorHelper, protected $devicesService: Mobile.IDevicesService, $platformValidationService: IPlatformValidationService, $projectData: IProjectData, @@ -64,9 +62,6 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements this.$errors.fail("--release flag is not applicable to this command"); } - const minSupportedWebpackVersion = this.$options.hmr ? LiveSyncCommandHelper.MIN_SUPPORTED_WEBPACK_VERSION_WITH_HMR : null; - this.$bundleValidatorHelper.validate(this.$projectData, minSupportedWebpackVersion); - const result = await super.canExecuteCommandBase(this.platform, { validateOptions: true, notConfiguredEnvOptions: { hideCloudBuildOption: true, hideSyncToPreviewAppOption: true } }); return result; } diff --git a/lib/commands/deploy.ts b/lib/commands/deploy.ts index aa7f613e95..ae414976c6 100644 --- a/lib/commands/deploy.ts +++ b/lib/commands/deploy.ts @@ -17,7 +17,6 @@ export class DeployOnDeviceCommand extends ValidatePlatformCommandBase implement private $errors: IErrors, private $mobileHelper: Mobile.IMobileHelper, $platformsDataService: IPlatformsDataService, - private $bundleValidatorHelper: IBundleValidatorHelper, private $deployCommandHelper: DeployCommandHelper, private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper) { super($options, $platformsDataService, $platformValidationService, $projectData); @@ -31,7 +30,6 @@ export class DeployOnDeviceCommand extends ValidatePlatformCommandBase implement public async canExecute(args: string[]): Promise { this.$androidBundleValidatorHelper.validateNoAab(); - this.$bundleValidatorHelper.validate(this.$projectData); if (!args || !args.length || args.length > 1) { return false; } diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index a8bffb0bc4..a6a4e2bb4a 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -2,10 +2,8 @@ import { DEVICE_LOG_EVENT_NAME } from "../common/constants"; export class PreviewCommand implements ICommand { public allowedParameters: ICommandParameter[] = []; - private static MIN_SUPPORTED_WEBPACK_VERSION = "0.17.0"; constructor(private $analyticsService: IAnalyticsService, - private $bundleValidatorHelper: IBundleValidatorHelper, private $errors: IErrors, private $logger: ILogger, private $previewAppController: IPreviewAppController, @@ -43,7 +41,6 @@ export class PreviewCommand implements ICommand { } await this.$networkConnectivityValidator.validate(); - this.$bundleValidatorHelper.validate(this.$projectData, PreviewCommand.MIN_SUPPORTED_WEBPACK_VERSION); return true; } } diff --git a/lib/helpers/livesync-command-helper.ts b/lib/helpers/livesync-command-helper.ts index ac58ac0976..ea2fbc1e5d 100644 --- a/lib/helpers/livesync-command-helper.ts +++ b/lib/helpers/livesync-command-helper.ts @@ -2,8 +2,6 @@ import { RunOnDeviceEvents } from "../constants"; import { DeployController } from "../controllers/deploy-controller"; export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { - public static MIN_SUPPORTED_WEBPACK_VERSION_WITH_HMR = "0.17.0"; - constructor( private $buildDataService: IBuildDataService, private $projectData: IProjectData, @@ -15,7 +13,6 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { private $injector: IInjector, private $buildController: IBuildController, private $analyticsService: IAnalyticsService, - private $bundleValidatorHelper: IBundleValidatorHelper, private $errors: IErrors, private $iOSSimulatorLogProvider: Mobile.IiOSSimulatorLogProvider, private $cleanupService: ICleanupService, @@ -133,9 +130,6 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { result[availablePlatform.toLowerCase()] = validateOutput; } - const minSupportedWebpackVersion = this.$options.hmr ? LiveSyncCommandHelper.MIN_SUPPORTED_WEBPACK_VERSION_WITH_HMR : null; - this.$bundleValidatorHelper.validate(this.$projectData, minSupportedWebpackVersion); - return result; } From 5dc21badf26d3e1afe060dae0dd931c1442760bb Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 3 Jul 2019 09:13:30 +0300 Subject: [PATCH 03/69] chore: fix unit tests --- test/platform-commands.ts | 3 +++ test/plugins-service.ts | 3 +++ 2 files changed, 6 insertions(+) diff --git a/test/platform-commands.ts b/test/platform-commands.ts index 0a3808baa5..8c65ae494f 100644 --- a/test/platform-commands.ts +++ b/test/platform-commands.ts @@ -187,6 +187,9 @@ function createTestInjector() { testInjector.register("addPlatformService", {}); testInjector.register("platformController", {}); testInjector.register("platformCommandHelper", PlatformCommandHelper); + testInjector.register("bundleValidatorHelper", { + validate: () => ({}) + }); return testInjector; } diff --git a/test/plugins-service.ts b/test/plugins-service.ts index cb44b1436f..d299ce44f8 100644 --- a/test/plugins-service.ts +++ b/test/plugins-service.ts @@ -150,6 +150,9 @@ function createTestInjector() { testInjector.register("cleanupService", { setShouldDispose: (shouldDispose: boolean): void => undefined }); + testInjector.register("bundleValidatorHelper", { + validate: () => ({}) + }); return testInjector; } From da1870e196f15ebcc510b9eb4b548b5c8263077a Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 3 Jul 2019 17:17:25 +0300 Subject: [PATCH 04/69] fix: validate the version of nativescript-dev-webpack plugin from prepare-controller --- lib/commands/preview.ts | 2 ++ lib/common/services/commands-service.ts | 5 +---- lib/controllers/prepare-controller.ts | 5 ++++- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index a6a4e2bb4a..f891b5fca9 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -4,6 +4,7 @@ export class PreviewCommand implements ICommand { public allowedParameters: ICommandParameter[] = []; constructor(private $analyticsService: IAnalyticsService, + private $bundleValidatorHelper: IBundleValidatorHelper, private $errors: IErrors, private $logger: ILogger, private $previewAppController: IPreviewAppController, @@ -41,6 +42,7 @@ export class PreviewCommand implements ICommand { } await this.$networkConnectivityValidator.validate(); + this.$bundleValidatorHelper.validate(this.$projectData, "1.0.0"); return true; } } diff --git a/lib/common/services/commands-service.ts b/lib/common/services/commands-service.ts index 294ccd6fba..b4bb6566d0 100644 --- a/lib/common/services/commands-service.ts +++ b/lib/common/services/commands-service.ts @@ -28,8 +28,7 @@ export class CommandsService implements ICommandsService { private $helpService: IHelpService, private $extensibilityService: IExtensibilityService, private $optionsTracker: IOptionsTracker, - private $projectDataService: IProjectDataService, - private $bundleValidatorHelper: IBundleValidatorHelper) { + private $projectDataService: IProjectDataService) { } public allCommands(opts: { includeDevCommands: boolean }): string[] { @@ -116,8 +115,6 @@ export class CommandsService implements ICommandsService { const dashedOptions = command ? command.dashedOptions : null; this.$options.validateOptions(dashedOptions, projectData); - - this.$bundleValidatorHelper.validate(projectData, "1.0.0"); } return this.canExecuteCommand(commandName, commandArguments); diff --git a/lib/controllers/prepare-controller.ts b/lib/controllers/prepare-controller.ts index 29b9be2b2a..402538101c 100644 --- a/lib/controllers/prepare-controller.ts +++ b/lib/controllers/prepare-controller.ts @@ -17,6 +17,7 @@ export class PrepareController extends EventEmitter { private persistedData: IFilesChangeEventData[] = []; constructor( + private $bundleValidatorHelper: IBundleValidatorHelper, private $platformController: IPlatformController, public $hooksService: IHooksService, private $logger: ILogger, @@ -32,12 +33,14 @@ export class PrepareController extends EventEmitter { @performanceLog() @hook("prepare") public async prepare(prepareData: IPrepareData): Promise { + const projectData = this.$projectDataService.getProjectData(prepareData.projectDir); + this.$bundleValidatorHelper.validate(projectData, "1.0.0"); + await this.$platformController.addPlatformIfNeeded(prepareData); this.$logger.info("Preparing project..."); let result = null; - const projectData = this.$projectDataService.getProjectData(prepareData.projectDir); const platformData = this.$platformsDataService.getPlatformData(prepareData.platform, projectData); if (prepareData.watch) { From 6aeac225f5263f8cd3c9f1cc73e8f7c6330b271e Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 3 Jul 2019 17:20:01 +0300 Subject: [PATCH 05/69] fix: don't show the help on run command when the version of nativescript-dev-webpack is lower than 1.0.0 --- lib/common/mobile/mobile-core/devices-service.ts | 7 ++++--- lib/services/project-changes-service.ts | 5 ++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/common/mobile/mobile-core/devices-service.ts b/lib/common/mobile/mobile-core/devices-service.ts index 4a139363a6..347f5d5c52 100644 --- a/lib/common/mobile/mobile-core/devices-service.ts +++ b/lib/common/mobile/mobile-core/devices-service.ts @@ -444,6 +444,7 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi } } catch (err) { err.deviceIdentifier = device.deviceInfo.identifier; + this.$logger.trace(`Error while executing action on device ${device.deviceInfo.identifier}. The error is ${err}`); errors.push(err); } } @@ -454,9 +455,9 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi preErrorMsg = "Multiple errors were thrown:" + EOL; } - const singleError = (new Error(`${preErrorMsg}${errors.map(e => e.message || e).join(EOL)}`)); - singleError.allErrors = errors; - throw singleError; + const errorMessage = `${preErrorMsg}${errors.map(e => e.message || e).join(EOL)}`; + const suppressCommandHelp = _.some(errors, (e: any) => e.suppressCommandHelp); + this.$errors.fail({ formatStr: errorMessage, suppressCommandHelp }); } return result; diff --git a/lib/services/project-changes-service.ts b/lib/services/project-changes-service.ts index c539525cc7..a82a9a009c 100644 --- a/lib/services/project-changes-service.ts +++ b/lib/services/project-changes-service.ts @@ -1,7 +1,6 @@ import * as path from "path"; import { NativePlatformStatus, PACKAGE_JSON_FILE_NAME, APP_GRADLE_FILE_NAME, BUILD_XCCONFIG_FILE_NAME, PLATFORMS_DIR_NAME } from "../constants"; import { getHash, hook } from "../common/helpers"; -import { PrepareData } from "../data/prepare-data"; const prepareInfoFileName = ".nsprepareinfo"; @@ -51,7 +50,7 @@ export class ProjectChangesService implements IProjectChangesService { } @hook("checkForChanges") - public async checkForChanges(platformData: IPlatformData, projectData: IProjectData, prepareData: PrepareData): Promise { + public async checkForChanges(platformData: IPlatformData, projectData: IProjectData, prepareData: IPrepareData): Promise { this._changesInfo = new ProjectChangesInfo(); const isNewPrepareInfo = await this.ensurePrepareInfo(platformData, projectData, prepareData); if (!isNewPrepareInfo) { @@ -158,7 +157,7 @@ export class ProjectChangesService implements IProjectChangesService { await this.savePrepareInfo(platformData, projectData, null); } - private async ensurePrepareInfo(platformData: IPlatformData, projectData: IProjectData, prepareData: PrepareData): Promise { + private async ensurePrepareInfo(platformData: IPlatformData, projectData: IProjectData, prepareData: IPrepareData): Promise { this._prepareInfo = this.getPrepareInfo(platformData); if (this._prepareInfo) { const prepareInfoFile = path.join(platformData.projectRoot, prepareInfoFileName); From 7f708a44b9e70198a99b9b4b1c5275f035d7962e Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 3 Jul 2019 18:03:18 +0300 Subject: [PATCH 06/69] fix: preview and run do not work correctly In case there are multiple devices with the same platform, `run command` fails with error `Cannot read property hasNativeChanges of undefined`. The problem is that we return incorrect prepare data. Also we have a problem in `tns preview` when multiple platforms are used - all files are send multiple times to each device as we have too many started webpack processes (in case you scan fast with devices) and we are also adding handler of the prepare ready event per each device instead per platform. Fix this by handling the event only once per platform --- lib/controllers/prepare-controller.ts | 42 +++++++++++------------ lib/controllers/preview-app-controller.ts | 6 ++-- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/lib/controllers/prepare-controller.ts b/lib/controllers/prepare-controller.ts index 29b9be2b2a..65806d30a7 100644 --- a/lib/controllers/prepare-controller.ts +++ b/lib/controllers/prepare-controller.ts @@ -1,4 +1,3 @@ -import * as child_process from "child_process"; import * as choki from "chokidar"; import { hook } from "../common/helpers"; import { performanceLog } from "../common/decorators"; @@ -7,7 +6,7 @@ import * as path from "path"; import { PREPARE_READY_EVENT_NAME, WEBPACK_COMPILATION_COMPLETE, PACKAGE_JSON_FILE_NAME, PLATFORMS_DIR_NAME } from "../constants"; interface IPlatformWatcherData { - webpackCompilerProcess: child_process.ChildProcess; + hasWebpackCompilerProcess: boolean; nativeFilesWatcher: choki.FSWatcher; } @@ -63,9 +62,9 @@ export class PrepareController extends EventEmitter { this.watchersData[projectDir][platformLowerCase].nativeFilesWatcher = null; } - if (this.watchersData && this.watchersData[projectDir] && this.watchersData[projectDir][platformLowerCase] && this.watchersData[projectDir][platformLowerCase].webpackCompilerProcess) { + if (this.watchersData && this.watchersData[projectDir] && this.watchersData[projectDir][platformLowerCase] && this.watchersData[projectDir][platformLowerCase].hasWebpackCompilerProcess) { await this.$webpackCompilerService.stopWebpackCompiler(platform); - this.watchersData[projectDir][platformLowerCase].webpackCompilerProcess = null; + this.watchersData[projectDir][platformLowerCase].hasWebpackCompilerProcess = false; } } @@ -78,38 +77,39 @@ export class PrepareController extends EventEmitter { if (!this.watchersData[projectData.projectDir][platformData.platformNameLowerCase]) { this.watchersData[projectData.projectDir][platformData.platformNameLowerCase] = { nativeFilesWatcher: null, - webpackCompilerProcess: null + hasWebpackCompilerProcess: false }; - await this.startJSWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial compilation - const hasNativeChanges = await this.startNativeWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial prepare - const result = { platform: platformData.platformNameLowerCase, hasNativeChanges }; + } - const hasPersistedDataWithNativeChanges = this.persistedData.find(data => data.platform === result.platform && data.hasNativeChanges); - if (hasPersistedDataWithNativeChanges) { - result.hasNativeChanges = true; - } + await this.startJSWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial compilation + const hasNativeChanges = await this.startNativeWatcherWithPrepare(platformData, projectData, prepareData); // -> start watcher + initial prepare + const result = { platform: platformData.platformNameLowerCase, hasNativeChanges }; - // TODO: Do not persist this in `this` context. Also it should be per platform. - this.isInitialPrepareReady = true; + const hasPersistedDataWithNativeChanges = this.persistedData.find(data => data.platform === result.platform && data.hasNativeChanges); + if (hasPersistedDataWithNativeChanges) { + result.hasNativeChanges = true; + } - if (this.persistedData && this.persistedData.length) { - this.emitPrepareEvent({ files: [], hasOnlyHotUpdateFiles: false, hasNativeChanges: result.hasNativeChanges, hmrData: null, platform: platformData.platformNameLowerCase }); - } + // TODO: Do not persist this in `this` context. Also it should be per platform. + this.isInitialPrepareReady = true; - return result; + if (this.persistedData && this.persistedData.length) { + this.emitPrepareEvent({ files: [], hasOnlyHotUpdateFiles: false, hasNativeChanges: result.hasNativeChanges, hmrData: null, platform: platformData.platformNameLowerCase }); } + + return result; } private async startJSWatcherWithPrepare(platformData: IPlatformData, projectData: IProjectData, prepareData: IPrepareData): Promise { - if (!this.watchersData[projectData.projectDir][platformData.platformNameLowerCase].webpackCompilerProcess) { + if (!this.watchersData[projectData.projectDir][platformData.platformNameLowerCase].hasWebpackCompilerProcess) { this.$webpackCompilerService.on(WEBPACK_COMPILATION_COMPLETE, data => { if (data.platform.toLowerCase() === platformData.platformNameLowerCase) { this.emitPrepareEvent({ ...data, hasNativeChanges: false }); } }); - const childProcess = await this.$webpackCompilerService.compileWithWatch(platformData, projectData, prepareData); - this.watchersData[projectData.projectDir][platformData.platformNameLowerCase].webpackCompilerProcess = childProcess; + this.watchersData[projectData.projectDir][platformData.platformNameLowerCase].hasWebpackCompilerProcess = true; + await this.$webpackCompilerService.compileWithWatch(platformData, projectData, prepareData); } } diff --git a/lib/controllers/preview-app-controller.ts b/lib/controllers/preview-app-controller.ts index c1883a76bf..cdd90f39de 100644 --- a/lib/controllers/preview-app-controller.ts +++ b/lib/controllers/preview-app-controller.ts @@ -79,8 +79,10 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon this.platformPrepareHandlers[device.platform] = true; // TODO: Remove the handler once the preview operation for this platform is stopped - this.$prepareController.on(PREPARE_READY_EVENT_NAME, async currentPrepareData => { - await this.handlePrepareReadyEvent(data, currentPrepareData.hmrData, currentPrepareData.files, device.platform); + this.$prepareController.on(PREPARE_READY_EVENT_NAME, async (currentPrepareData: IFilesChangeEventData) => { + if (currentPrepareData.platform.toLowerCase() === device.platform.toLowerCase()) { + await this.handlePrepareReadyEvent(data, currentPrepareData.hmrData, currentPrepareData.files, device.platform); + } }); } From 33c51925e6f2a08fa5dcaa77543bd8c61e1dc22e Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 3 Jul 2019 18:08:26 +0300 Subject: [PATCH 07/69] fix: remove incorrect spam message the message is shown every time when we want to show a line from device logs and we are with trace level --- lib/services/ios-log-filter.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/services/ios-log-filter.ts b/lib/services/ios-log-filter.ts index 4201ea6165..dfc0a7578c 100644 --- a/lib/services/ios-log-filter.ts +++ b/lib/services/ios-log-filter.ts @@ -13,13 +13,11 @@ export class IOSLogFilter implements Mobile.IPlatformLogFilter { private partialLine: string = null; - constructor(private $logger: ILogger, - private $loggingLevels: Mobile.ILoggingLevels) { + constructor(private $loggingLevels: Mobile.ILoggingLevels) { } public filterData(data: string, loggingOptions: Mobile.IDeviceLogOptions = {}): string { const specifiedLogLevel = (loggingOptions.logLevel || '').toUpperCase(); - this.$logger.trace("Logging options", loggingOptions); if (specifiedLogLevel !== this.$loggingLevels.info || !data) { return data; From 5c2e869524a4713e9968cf15202aad73969fe2f4 Mon Sep 17 00:00:00 2001 From: fatme Date: Thu, 4 Jul 2019 08:29:00 +0300 Subject: [PATCH 08/69] chore: fix unit tests --- test/controllers/prepare-controller.ts | 4 ++++ test/platform-commands.ts | 3 --- test/plugins-service.ts | 3 --- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/test/controllers/prepare-controller.ts b/test/controllers/prepare-controller.ts index ef0b4a0fd0..78b4af2d43 100644 --- a/test/controllers/prepare-controller.ts +++ b/test/controllers/prepare-controller.ts @@ -54,6 +54,10 @@ function createTestInjector(data: { hasNativeChanges: boolean }): IInjector { isFileInIgnoreList: () => false }); + injector.register("bundleValidatorHelper", { + validate: () => ({}) + }); + const prepareController: PrepareController = injector.resolve("prepareController"); prepareController.emit = (eventName: string, eventData: any) => { emittedEventNames.push(eventName); diff --git a/test/platform-commands.ts b/test/platform-commands.ts index 8c65ae494f..0a3808baa5 100644 --- a/test/platform-commands.ts +++ b/test/platform-commands.ts @@ -187,9 +187,6 @@ function createTestInjector() { testInjector.register("addPlatformService", {}); testInjector.register("platformController", {}); testInjector.register("platformCommandHelper", PlatformCommandHelper); - testInjector.register("bundleValidatorHelper", { - validate: () => ({}) - }); return testInjector; } diff --git a/test/plugins-service.ts b/test/plugins-service.ts index d299ce44f8..cb44b1436f 100644 --- a/test/plugins-service.ts +++ b/test/plugins-service.ts @@ -150,9 +150,6 @@ function createTestInjector() { testInjector.register("cleanupService", { setShouldDispose: (shouldDispose: boolean): void => undefined }); - testInjector.register("bundleValidatorHelper", { - validate: () => ({}) - }); return testInjector; } From 5a4591c839eb7e07491881aaaea2fc76379d665f Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Thu, 4 Jul 2019 11:16:08 +0300 Subject: [PATCH 09/69] fix: before-preview-sync hook has incorrect args The `before-preview-sync` hook has incorrect args - instead of having `hookArgs`, it has an object with data. This causes issues in all plugins which are using it. Get back the correct structure and add `projectData` as it is being used by kinvey-nativescript-sdk's hook. --- lib/controllers/preview-app-controller.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/controllers/preview-app-controller.ts b/lib/controllers/preview-app-controller.ts index cdd90f39de..41381e6305 100644 --- a/lib/controllers/preview-app-controller.ts +++ b/lib/controllers/preview-app-controller.ts @@ -25,7 +25,8 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon private $previewDevicesService: IPreviewDevicesService, private $previewQrCodeService: IPreviewQrCodeService, private $previewSdkService: IPreviewSdkService, - private $prepareDataService: PrepareDataService + private $prepareDataService: PrepareDataService, + private $projectDataService: IProjectDataService ) { super(); } public async startPreview(data: IPreviewAppLiveSyncData): Promise { @@ -66,7 +67,8 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon }); } - await this.$hooksService.executeBeforeHooks("preview-sync", { ...data, platform: device.platform }); + const projectData = this.$projectDataService.getProjectData(data.projectDir); + await this.$hooksService.executeBeforeHooks("preview-sync", { hookArgs: { ...data, platform: device.platform, projectData } }); if (data.useHotModuleReload) { this.$hmrStatusService.attachToHmrStatusEvent(); From ea6eccc4ba05a83672555af3f7b9a371a0828fd0 Mon Sep 17 00:00:00 2001 From: fatme Date: Thu, 4 Jul 2019 15:00:02 +0300 Subject: [PATCH 10/69] fix: remove prepareReadyHandler on run command and don't provide deviceDescriptors as param to sync method --- lib/controllers/run-controller.ts | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/lib/controllers/run-controller.ts b/lib/controllers/run-controller.ts index 1237555a06..8a83b81849 100644 --- a/lib/controllers/run-controller.ts +++ b/lib/controllers/run-controller.ts @@ -4,6 +4,8 @@ import { cache, performanceLog } from "../common/decorators"; import { EventEmitter } from "events"; export class RunController extends EventEmitter implements IRunController { + private prepareReadyEventHandler: any = null; + constructor( protected $analyticsService: IAnalyticsService, private $buildController: IBuildController, @@ -45,9 +47,10 @@ export class RunController extends EventEmitter implements IRunController { this.$hmrStatusService.attachToHmrStatusEvent(); } - this.$prepareController.on(PREPARE_READY_EVENT_NAME, async data => { - await this.syncChangedDataOnDevices(data, projectData, liveSyncInfo, deviceDescriptors); - }); + if (!this.prepareReadyEventHandler) { + this.prepareReadyEventHandler = async (data: any) => await this.syncChangedDataOnDevices(data, projectData, liveSyncInfo); + this.$prepareController.on(PREPARE_READY_EVENT_NAME, this.prepareReadyEventHandler.bind(this)); + } await this.syncInitialDataOnDevices(projectData, liveSyncInfo, deviceDescriptorsForInitialSync); @@ -58,6 +61,11 @@ export class RunController extends EventEmitter implements IRunController { const { projectDir, deviceIdentifiers, stopOptions } = data; const liveSyncProcessInfo = this.$liveSyncProcessDataService.getPersistedData(projectDir); if (liveSyncProcessInfo && !liveSyncProcessInfo.isStopped) { + if (this.prepareReadyEventHandler) { + this.removeListener(PREPARE_READY_EVENT_NAME, this.prepareReadyEventHandler); + this.prepareReadyEventHandler = null; + } + // In case we are coming from error during livesync, the current action is the one that erred (but we are still executing it), // so we cannot await it as this will cause infinite loop. const shouldAwaitPendingOperation = !stopOptions || stopOptions.shouldAwaitAllActions; @@ -313,10 +321,11 @@ export class RunController extends EventEmitter implements IRunController { await this.addActionToChain(projectData.projectDir, () => this.$devicesService.execute(deviceAction, (device: Mobile.IDevice) => _.some(deviceDescriptors, deviceDescriptor => deviceDescriptor.identifier === device.deviceInfo.identifier))); } - private async syncChangedDataOnDevices(data: IFilesChangeEventData, projectData: IProjectData, liveSyncInfo: ILiveSyncInfo, deviceDescriptors: ILiveSyncDeviceDescriptor[]): Promise { + private async syncChangedDataOnDevices(data: IFilesChangeEventData, projectData: IProjectData, liveSyncInfo: ILiveSyncInfo): Promise { const rebuiltInformation: IDictionary<{ packageFilePath: string, platform: string, isEmulator: boolean }> = { }; const deviceAction = async (device: Mobile.IDevice) => { + const deviceDescriptors = this.$liveSyncProcessDataService.getDeviceDescriptors(projectData.projectDir); const deviceDescriptor = _.find(deviceDescriptors, dd => dd.identifier === device.deviceInfo.identifier); const platformData = this.$platformsDataService.getPlatformData(data.platform, projectData); const prepareData = this.$prepareDataService.getPrepareData(liveSyncInfo.projectDir, device.deviceInfo.platform, From 317f10b2e446e54c79e910aceba7e0464602590f Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 5 Jul 2019 10:39:56 +0300 Subject: [PATCH 11/69] fix: fix shouldBuild method when release cloud build is executed --- lib/controllers/build-controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/controllers/build-controller.ts b/lib/controllers/build-controller.ts index a5e0bbf2f2..ae421bd8d7 100644 --- a/lib/controllers/build-controller.ts +++ b/lib/controllers/build-controller.ts @@ -87,12 +87,12 @@ export class BuildController extends EventEmitter implements IBuildController { const projectData = this.$projectDataService.getProjectData(buildData.projectDir); const platformData = this.$platformsDataService.getPlatformData(buildData.platform, projectData); const outputPath = buildData.outputPath || platformData.getBuildOutputPath(buildData); + const changesInfo = this.$projectChangesService.currentChanges || await this.$projectChangesService.checkForChanges(platformData, projectData, buildData); - if (buildData.release && this.$projectChangesService.currentChanges.hasChanges) { + if (buildData.release && changesInfo.hasChanges) { return true; } - const changesInfo = this.$projectChangesService.currentChanges || await this.$projectChangesService.checkForChanges(platformData, projectData, buildData); if (changesInfo.changesRequireBuild) { return true; } From 79525a85448c01e03afb294cdbd2bba7e7f4d8c6 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 5 Jul 2019 11:06:07 +0300 Subject: [PATCH 12/69] fix: iOS device logs are not using source maps initially When you run your app on iOS device for the first time, we execute full sync operation with a zip file. This does not gets in our logic for setting source maps of the transferred files and CLI does not use its logic to parse device logs and show the exact lines from original files. Fix this by setting the source maps in this case. --- lib/services/livesync/ios-livesync-service.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/services/livesync/ios-livesync-service.ts b/lib/services/livesync/ios-livesync-service.ts index fddd52e561..92162beeb2 100644 --- a/lib/services/livesync/ios-livesync-service.ts +++ b/lib/services/livesync/ios-livesync-service.ts @@ -32,7 +32,9 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I const tempZip = temp.path({ prefix: "sync", suffix: ".zip" }); this.$logger.trace("Creating zip file: " + tempZip); - await this.$fs.zipFiles(tempZip, this.$fs.enumerateFilesInDirectorySync(projectFilesPath), (res) => { + const filesToTransfer = this.$fs.enumerateFilesInDirectorySync(projectFilesPath); + + await this.$fs.zipFiles(tempZip, filesToTransfer, (res) => { return path.join(APP_FOLDER_NAME, path.relative(projectFilesPath, res)); }); @@ -43,6 +45,8 @@ export class IOSLiveSyncService extends PlatformLiveSyncServiceBase implements I deviceProjectRootPath: await deviceAppData.getDeviceProjectRootPath() }]); + await deviceAppData.device.applicationManager.setTransferredAppFiles(filesToTransfer); + return { deviceAppData, isFullSync: true, From 2160190aba9b1bf5d0c486d016b871a6555fbb5e Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 5 Jul 2019 10:42:57 +0300 Subject: [PATCH 13/69] fix: execute checkForChanges before syncing changed files --- lib/controllers/run-controller.ts | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/controllers/run-controller.ts b/lib/controllers/run-controller.ts index 8a83b81849..e2f1100685 100644 --- a/lib/controllers/run-controller.ts +++ b/lib/controllers/run-controller.ts @@ -25,6 +25,7 @@ export class RunController extends EventEmitter implements IRunController { private $prepareController: IPrepareController, private $prepareDataService: IPrepareDataService, private $prepareNativePlatformService: IPrepareNativePlatformService, + private $projectChangesService: IProjectChangesService, protected $projectDataService: IProjectDataService ) { super(); @@ -48,7 +49,18 @@ export class RunController extends EventEmitter implements IRunController { } if (!this.prepareReadyEventHandler) { - this.prepareReadyEventHandler = async (data: any) => await this.syncChangedDataOnDevices(data, projectData, liveSyncInfo); + this.prepareReadyEventHandler = async (data: IFilesChangeEventData) => { + if (data.hasNativeChanges) { + const platformData = this.$platformsDataService.getPlatformData(data.platform, projectData); + const prepareData = this.$prepareDataService.getPrepareData(liveSyncInfo.projectDir, data.platform, { ...liveSyncInfo, watch: !liveSyncInfo.skipWatcher }); + const changesInfo = await this.$projectChangesService.checkForChanges(platformData, projectData, prepareData); + if (changesInfo.hasChanges) { + await this.syncChangedDataOnDevices(data, projectData, liveSyncInfo); + } + } else { + await this.syncChangedDataOnDevices(data, projectData, liveSyncInfo); + } + }; this.$prepareController.on(PREPARE_READY_EVENT_NAME, this.prepareReadyEventHandler.bind(this)); } From 943b3bd4b2b379e2d71728faadfb865c9e06125a Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 5 Jul 2019 13:21:05 +0300 Subject: [PATCH 14/69] fix: fix call projectChangesService.checkForChanges regardless if skipNativePlatform is provided --- lib/controllers/build-controller.ts | 4 ---- lib/services/platform/prepare-native-platform-service.ts | 5 ++--- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/lib/controllers/build-controller.ts b/lib/controllers/build-controller.ts index ae421bd8d7..fc94dab0fa 100644 --- a/lib/controllers/build-controller.ts +++ b/lib/controllers/build-controller.ts @@ -89,10 +89,6 @@ export class BuildController extends EventEmitter implements IBuildController { const outputPath = buildData.outputPath || platformData.getBuildOutputPath(buildData); const changesInfo = this.$projectChangesService.currentChanges || await this.$projectChangesService.checkForChanges(platformData, projectData, buildData); - if (buildData.release && changesInfo.hasChanges) { - return true; - } - if (changesInfo.changesRequireBuild) { return true; } diff --git a/lib/services/platform/prepare-native-platform-service.ts b/lib/services/platform/prepare-native-platform-service.ts index 6b3549cb3f..1a9276beee 100644 --- a/lib/services/platform/prepare-native-platform-service.ts +++ b/lib/services/platform/prepare-native-platform-service.ts @@ -15,12 +15,11 @@ export class PrepareNativePlatformService implements IPrepareNativePlatformServi @hook('prepareNativeApp') public async prepareNativePlatform(platformData: IPlatformData, projectData: IProjectData, prepareData: IPrepareData): Promise { const { nativePrepare, release } = prepareData; + const changesInfo = await this.$projectChangesService.checkForChanges(platformData, projectData, prepareData); if (nativePrepare && nativePrepare.skipNativePrepare) { - return false; + return changesInfo.hasChanges; } - const changesInfo = await this.$projectChangesService.checkForChanges(platformData, projectData, prepareData); - const hasNativeModulesChange = !changesInfo || changesInfo.nativeChanged; const hasConfigChange = !changesInfo || changesInfo.configChanged; const hasChangesRequirePrepare = !changesInfo || changesInfo.changesRequirePrepare; From 342307fcee30b3cc372349ba741a85914f44e32c Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 5 Jul 2019 13:46:21 +0300 Subject: [PATCH 15/69] fix: remove from prepareReady event when we really stop the livesync process --- lib/controllers/run-controller.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/controllers/run-controller.ts b/lib/controllers/run-controller.ts index e2f1100685..bb46da92e5 100644 --- a/lib/controllers/run-controller.ts +++ b/lib/controllers/run-controller.ts @@ -73,10 +73,6 @@ export class RunController extends EventEmitter implements IRunController { const { projectDir, deviceIdentifiers, stopOptions } = data; const liveSyncProcessInfo = this.$liveSyncProcessDataService.getPersistedData(projectDir); if (liveSyncProcessInfo && !liveSyncProcessInfo.isStopped) { - if (this.prepareReadyEventHandler) { - this.removeListener(PREPARE_READY_EVENT_NAME, this.prepareReadyEventHandler); - this.prepareReadyEventHandler = null; - } // In case we are coming from error during livesync, the current action is the one that erred (but we are still executing it), // so we cannot await it as this will cause infinite loop. @@ -114,6 +110,11 @@ export class RunController extends EventEmitter implements IRunController { liveSyncProcessInfo.deviceDescriptors = []; + if (this.prepareReadyEventHandler) { + this.removeListener(PREPARE_READY_EVENT_NAME, this.prepareReadyEventHandler); + this.prepareReadyEventHandler = null; + } + const projectData = this.$projectDataService.getProjectData(projectDir); await this.$hooksService.executeAfterHooks('watch', { hookArgs: { From 668baa9e0033ac98b503a040eba6da267ab70684 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 5 Jul 2019 13:59:13 +0300 Subject: [PATCH 16/69] fix: migrate command failure should be handled correctly In case migrate command fails to migrate the project, currently it shows some generic message without saying what is the actual error. Also the command exits with code 0, which is indication it had succeeded. Fix this by failing with more descriptive error message and exit code that is not 0. --- lib/controllers/migrate-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 67da41c784..ed27332327 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -108,7 +108,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC await this.migrateDependencies(projectData); } catch (error) { this.restoreBackup(MigrateController.folders, backupDir, projectData.projectDir); - this.$logger.error(MigrateController.migrateFailMessage); + this.$errors.failWithoutHelp(`${MigrateController.migrateFailMessage} The error is: ${error}`); } } From 786e9fc6a024e2bf0dad08a3596a7ec73ef695b6 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 5 Jul 2019 14:10:19 +0300 Subject: [PATCH 17/69] fix: show the actual error when hook fails When hook throws an error, there's no easy way to find exactly what is failing as CLI overwrites the error and its callstack. As it is not trivial solution to stop CLI of doing this, when a hook fails, just log the error with its callstack. We know these errors always lead to stopage of CLI process, so we can safely print them. --- lib/common/services/hooks-service.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/common/services/hooks-service.ts b/lib/common/services/hooks-service.ts index 1362aa9a64..a455e1cdda 100644 --- a/lib/common/services/hooks-service.ts +++ b/lib/common/services/hooks-service.ts @@ -117,7 +117,7 @@ export class HooksService implements IHooksService { this.$logger.trace(`Validating ${hookName} arguments.`); - const invalidArguments = this.validateHookArguments(hookEntryPoint); + const invalidArguments = this.validateHookArguments(hookEntryPoint, hook.fullPath); if (invalidArguments.length) { this.$logger.warn(`${hook.fullPath} will NOT be executed because it has invalid arguments - ${invalidArguments.join(", ").grey}.`); @@ -144,6 +144,8 @@ export class HooksService implements IHooksService { if (err && _.isBoolean(err.stopExecution) && err.errorAsWarning === true) { this.$logger.warn(err.message || err); } else { + // Print the actual error with its callstack, so it is easy to find out which hooks is causing troubles. + this.$logger.error(err); throw err || new Error(`Failed to execute hook: ${hook.fullPath}.`); } } @@ -266,7 +268,7 @@ export class HooksService implements IHooksService { } } - private validateHookArguments(hookConstructor: Function): string[] { + private validateHookArguments(hookConstructor: Function, hookFullPath: string): string[] { const invalidArguments: string[] = []; // We need to annotate the hook in order to have the arguments of the constructor. @@ -278,7 +280,7 @@ export class HooksService implements IHooksService { this.$injector.resolve(argument); } } catch (err) { - this.$logger.trace(`Cannot resolve ${argument}, reason: ${err}`); + this.$logger.trace(`Cannot resolve ${argument} of hook ${hookFullPath}, reason: ${err}`); invalidArguments.push(argument); } }); From 54adedcee5c7db9aa97e63b690d70521f26186b1 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Fri, 5 Jul 2019 14:37:44 +0300 Subject: [PATCH 18/69] fix: make the update command behave similar to the logic before 6.0.0 --- lib/controllers/update-controller.ts | 73 ++++++++++++++++------------ lib/package-manager.ts | 3 ++ 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/lib/controllers/update-controller.ts b/lib/controllers/update-controller.ts index eefccb519f..8e662ce5b8 100644 --- a/lib/controllers/update-controller.ts +++ b/lib/controllers/update-controller.ts @@ -4,6 +4,20 @@ import * as constants from "../constants"; import { UpdateControllerBase } from "./update-controller-base"; export class UpdateController extends UpdateControllerBase implements IUpdateController { + private getTemplateManifest: Function; + static readonly updatableDependencies: string[] = [constants.TNS_CORE_MODULES_NAME, constants.TNS_CORE_MODULES_WIDGETS_NAME]; + static readonly folders: string[] = [ + constants.LIB_DIR_NAME, + constants.HOOKS_DIR_NAME, + constants.WEBPACK_CONFIG_NAME, + constants.PACKAGE_JSON_FILE_NAME, + constants.PACKAGE_LOCK_JSON_FILE_NAME + ]; + + static readonly backupFolder: string = ".update_backup"; + static readonly updateFailMessage: string = "Could not update the project!"; + static readonly backupFailMessage: string = "Could not backup project folders!"; + constructor( protected $fs: IFileSystem, protected $platformsDataService: IPlatformsDataService, @@ -16,23 +30,11 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon private $pluginsService: IPluginsService, private $pacoteService: IPacoteService, private $projectDataService: IProjectDataService) { - super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager); - this.getTemplateManifest = _.memoize(this._getTemplateManifest, (...args) => { - return args.join("@"); - }); + super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager); + this.getTemplateManifest = _.memoize(this._getTemplateManifest, (...args) => { + return args.join("@"); + }); } - private getTemplateManifest: Function; - static readonly folders: string[] = [ - constants.LIB_DIR_NAME, - constants.HOOKS_DIR_NAME, - constants.WEBPACK_CONFIG_NAME, - constants.PACKAGE_JSON_FILE_NAME, - constants.PACKAGE_LOCK_JSON_FILE_NAME - ]; - - static readonly backupFolder: string = ".update_backup"; - static readonly updateFailMessage: string = "Could not update the project!"; - static readonly backupFailMessage: string = "Could not backup project folders!"; public async update(updateOptions: IUpdateOptions): Promise { const projectData = this.$projectDataService.getProjectData(updateOptions.projectDir); @@ -55,16 +57,16 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon } } - public async shouldUpdate({projectDir, version}: {projectDir: string, version?: string}): Promise { + public async shouldUpdate({ projectDir, version }: { projectDir: string, version?: string }): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); const templateName = this.getTemplateName(projectData); const templateManifest = await this.getTemplateManifest(templateName, version); - const dependencies = templateManifest.dependencies; - const devDependencies = templateManifest.devDependencies; + const dependencies = this.getUpdatableDependencies(templateManifest.dependencies); + const devDependencies = this.getUpdatableDependencies(templateManifest.devDependencies); if ( - await this.hasDependenciesToUpdate({dependencies, areDev: false, projectData}) || - await this.hasDependenciesToUpdate({dependencies: devDependencies, areDev: true, projectData}) + await this.hasDependenciesToUpdate({ dependencies, areDev: false, projectData }) || + await this.hasDependenciesToUpdate({ dependencies: devDependencies, areDev: true, projectData }) ) { return true; } @@ -93,12 +95,14 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon private async updateProject(projectData: IProjectData, version: string): Promise { const templateName = this.getTemplateName(projectData); const templateManifest = await this.getTemplateManifest(templateName, version); + const dependencies = this.getUpdatableDependencies(templateManifest.dependencies); + const devDependencies = this.getUpdatableDependencies(templateManifest.devDependencies); this.$logger.info("Start updating dependencies."); - await this.updateDependencies({ dependencies: templateManifest.dependencies, areDev: false, projectData}); + await this.updateDependencies({ dependencies, areDev: false, projectData }); this.$logger.info("Finished updating dependencies."); this.$logger.info("Start updating devDependencies."); - await this.updateDependencies({ dependencies: templateManifest.devDependencies, areDev: true, projectData}); + await this.updateDependencies({ dependencies: devDependencies, areDev: true, projectData }); this.$logger.info("Finished updating devDependencies."); this.$logger.info("Start updating runtimes."); @@ -114,7 +118,7 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon }); } - private async updateDependencies( {dependencies, areDev, projectData} : {dependencies: IDictionary, areDev: boolean, projectData: IProjectData}) { + private async updateDependencies({ dependencies, areDev, projectData }: { dependencies: IDictionary, areDev: boolean, projectData: IProjectData }) { for (const dependency in dependencies) { const templateVersion = dependencies[dependency]; if (!this.hasDependency({ packageName: dependency, isDev: areDev }, projectData)) { @@ -134,11 +138,10 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon const projectVersion = dependencies[dependency] || devDependencies[dependency]; const maxSatisfyingTargetVersion = await this.getMaxDependencyVersion(dependency, targetVersion); const maxSatisfyingProjectVersion = await this.getMaxDependencyVersion(dependency, projectVersion); - return maxSatisfyingProjectVersion && maxSatisfyingTargetVersion && semver.gt(maxSatisfyingTargetVersion, maxSatisfyingProjectVersion); } - private async hasDependenciesToUpdate({dependencies, areDev, projectData}: {dependencies: IDictionary, areDev: boolean, projectData:IProjectData}) { + private async hasDependenciesToUpdate({ dependencies, areDev, projectData }: { dependencies: IDictionary, areDev: boolean, projectData: IProjectData }) { for (const dependency in dependencies) { const templateVersion = dependencies[dependency]; if (!this.hasDependency({ packageName: dependency, isDev: areDev }, projectData)) { @@ -165,26 +168,32 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon } private async shouldUpdateRuntimeVersion(templateRuntimeVersion: string, frameworkPackageName: string, platform: string, projectData: IProjectData): Promise { - const hasRuntimeDependency = this.hasRuntimeDependency({platform, projectData}); + const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); if (!hasRuntimeDependency) { return false; } const maxTemplateRuntimeVersion = await this.getMaxDependencyVersion(frameworkPackageName, templateRuntimeVersion); - const maxRuntimeVersion = await this.getMaxRuntimeVersion({platform, projectData}); + const maxRuntimeVersion = await this.getMaxRuntimeVersion({ platform, projectData }); return maxTemplateRuntimeVersion && maxRuntimeVersion && semver.gt(maxTemplateRuntimeVersion, maxRuntimeVersion); } - private async _getTemplateManifest(templateName: string, version: string) { - let packageVersion = version ? version : await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); - packageVersion = semver.valid(version) ? version : await this.$packageManager.getTagVersion(templateName, packageVersion); - packageVersion = packageVersion ? packageVersion : await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); + private async _getTemplateManifest(templateName: string, version?: string) { + const packageVersion = semver.valid(version) || + await this.$packageManager.getTagVersion(templateName, version) || + await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); return await this.$pacoteService.manifest(`${templateName}@${packageVersion}`, { fullMetadata: true }); } + private getUpdatableDependencies(dependencies: IDictionary): IDictionary { + return _.pickBy(dependencies, (value, key) => { + return UpdateController.updatableDependencies.indexOf(key) > -1; + }); + } + private getTemplateName(projectData: IProjectData) { let template; switch (projectData.projectType) { diff --git a/lib/package-manager.ts b/lib/package-manager.ts index 9359699f41..391825edaf 100644 --- a/lib/package-manager.ts +++ b/lib/package-manager.ts @@ -72,6 +72,9 @@ export class PackageManager implements IPackageManager { public async getTagVersion(packageName: string, tag: string): Promise { let version: string = null; + if (!tag) { + return null; + } try { const result = await this.view(packageName, { "dist-tags": true }); From e5eb03214a5dee57ba9205e50a85ff7f08c773f3 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 5 Jul 2019 16:13:26 +0300 Subject: [PATCH 19/69] fix: fix cloud deploy command Currently `tns cloud deploy` command starts local build as the provided buildAction through deviceDescriptor is not executed from deployController. --- lib/controllers/deploy-controller.ts | 8 +++++--- lib/helpers/deploy-command-helper.ts | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/controllers/deploy-controller.ts b/lib/controllers/deploy-controller.ts index 1574926ea4..8f9497617e 100644 --- a/lib/controllers/deploy-controller.ts +++ b/lib/controllers/deploy-controller.ts @@ -1,16 +1,18 @@ export class DeployController { constructor( - private $buildController: IBuildController, private $deviceInstallAppService: IDeviceInstallAppService, - private $devicesService: Mobile.IDevicesService + private $devicesService: Mobile.IDevicesService, + private $prepareController: IPrepareController ) { } public async deploy(data: IDeployData): Promise { const { buildData, deviceDescriptors } = data; const executeAction = async (device: Mobile.IDevice) => { - const packageFilePath = await this.$buildController.prepareAndBuild({ ...buildData, buildForDevice: !device.isEmulator }); + await this.$prepareController.prepare(buildData); + const deviceDescriptor = _.find(deviceDescriptors, dd => dd.identifier === device.deviceInfo.identifier); + const packageFilePath = await deviceDescriptor.buildAction(); await this.$deviceInstallAppService.installOnDevice(device, { ...buildData, buildForDevice: !device.isEmulator }, packageFilePath); }; diff --git a/lib/helpers/deploy-command-helper.ts b/lib/helpers/deploy-command-helper.ts index ffc6ac0a89..607c3e8c77 100644 --- a/lib/helpers/deploy-command-helper.ts +++ b/lib/helpers/deploy-command-helper.ts @@ -36,7 +36,7 @@ export class DeployCommandHelper { const buildAction = additionalOptions && additionalOptions.buildPlatform ? additionalOptions.buildPlatform.bind(additionalOptions.buildPlatform, d.deviceInfo.platform, buildData, this.$projectData) : - this.$buildController.prepareAndBuild.bind(this.$buildController, d.deviceInfo.platform, buildData, this.$projectData); + this.$buildController.build.bind(this.$buildController, d.deviceInfo.platform, buildData, this.$projectData); const info: ILiveSyncDeviceDescriptor = { identifier: d.deviceInfo.identifier, From b29248e46b1c0b374a602e4f313deddd85962285 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 5 Jul 2019 17:09:31 +0300 Subject: [PATCH 20/69] fix: migrate fails when karma.config.js is missing In case you've installed `nativescript-unit-test-runner` , but you've not used `tns test init`, `tns migrate` command fails with error: `Could not migrate the project! The error is: Error: ENOENT: no such file or directory, open '/.migration_backup/karma.conf.js'` Skip the migration of the `karma.conf.js` file in case it is missing. Also, ensure `karma-webpack` is always added by the migration when `nativescript-unit-test-runner` is migrated. --- lib/controllers/migrate-controller.ts | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index ed27332327..33a9ccded4 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -286,23 +286,26 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC private async migrateUnitTestRunner(projectData: IProjectData, migrationBackupDirPath: string): Promise { // Migrate karma.conf.js - const oldKarmaContent = this.$fs.readText(path.join(migrationBackupDirPath, constants.KARMA_CONFIG_NAME)); + const pathToKarmaConfig = path.join(migrationBackupDirPath, constants.KARMA_CONFIG_NAME); + if (this.$fs.exists(pathToKarmaConfig)) { + const oldKarmaContent = this.$fs.readText(pathToKarmaConfig); - const regExp = /frameworks:\s+\[([\S\s]*?)\]/g; - const matches = regExp.exec(oldKarmaContent); - const frameworks = (matches && matches[1] && matches[1].trim()) || '["jasmine"]'; + const regExp = /frameworks:\s+\[([\S\s]*?)\]/g; + const matches = regExp.exec(oldKarmaContent); + const frameworks = (matches && matches[1] && matches[1].trim()) || '["jasmine"]'; - const testsDir = path.join(projectData.appDirectoryPath, 'tests'); - const relativeTestsDir = path.relative(projectData.projectDir, testsDir); - const testFiles = `'${fromWindowsRelativePathToUnix(relativeTestsDir)}/**/*.*'`; + const testsDir = path.join(projectData.appDirectoryPath, 'tests'); + const relativeTestsDir = path.relative(projectData.projectDir, testsDir); + const testFiles = `'${fromWindowsRelativePathToUnix(relativeTestsDir)}/**/*.*'`; - const karmaConfTemplate = this.$resources.readText('test/karma.conf.js'); - const karmaConf = _.template(karmaConfTemplate)({ frameworks, testFiles }); - this.$fs.writeFile(path.join(projectData.projectDir, constants.KARMA_CONFIG_NAME), karmaConf); + const karmaConfTemplate = this.$resources.readText('test/karma.conf.js'); + const karmaConf = _.template(karmaConfTemplate)({ frameworks, testFiles }); + this.$fs.writeFile(path.join(projectData.projectDir, constants.KARMA_CONFIG_NAME), karmaConf); + } // Dependencies to migrate const dependencies = [ - { packageName: "karma-webpack", verifiedVersion: "3.0.5", isDev: true, shouldAddIfMissing: !this.hasDependency({ packageName: "karma-webpack", isDev: true }, projectData) }, + { packageName: "karma-webpack", verifiedVersion: "3.0.5", isDev: true, shouldAddIfMissing: true }, { packageName: "karma-jasmine", verifiedVersion: "2.0.1", isDev: true }, { packageName: "karma-mocha", verifiedVersion: "1.3.0", isDev: true }, { packageName: "karma-chai", verifiedVersion: "0.1.0", isDev: true }, From 5db1afc240d13827ccbbfce3af8f24d3c5bb4fa1 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 5 Jul 2019 17:58:36 +0300 Subject: [PATCH 21/69] fix: pass correct data to build controller from deploy command --- lib/helpers/deploy-command-helper.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/helpers/deploy-command-helper.ts b/lib/helpers/deploy-command-helper.ts index 607c3e8c77..25f9feb78b 100644 --- a/lib/helpers/deploy-command-helper.ts +++ b/lib/helpers/deploy-command-helper.ts @@ -36,7 +36,7 @@ export class DeployCommandHelper { const buildAction = additionalOptions && additionalOptions.buildPlatform ? additionalOptions.buildPlatform.bind(additionalOptions.buildPlatform, d.deviceInfo.platform, buildData, this.$projectData) : - this.$buildController.build.bind(this.$buildController, d.deviceInfo.platform, buildData, this.$projectData); + this.$buildController.build.bind(this.$buildController, buildData); const info: ILiveSyncDeviceDescriptor = { identifier: d.deviceInfo.identifier, From fe3a348e186eae4cae33002ace9391c8db39441c Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Fri, 5 Jul 2019 17:58:55 +0300 Subject: [PATCH 22/69] fix: print full error with stacktrace when action on device fails --- lib/common/mobile/mobile-core/devices-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/mobile/mobile-core/devices-service.ts b/lib/common/mobile/mobile-core/devices-service.ts index 347f5d5c52..ea8a843657 100644 --- a/lib/common/mobile/mobile-core/devices-service.ts +++ b/lib/common/mobile/mobile-core/devices-service.ts @@ -444,7 +444,7 @@ export class DevicesService extends EventEmitter implements Mobile.IDevicesServi } } catch (err) { err.deviceIdentifier = device.deviceInfo.identifier; - this.$logger.trace(`Error while executing action on device ${device.deviceInfo.identifier}. The error is ${err}`); + this.$logger.trace(`Error while executing action on device ${device.deviceInfo.identifier}. The error is`, err); errors.push(err); } } From 527b4f0274ed32c104f4853b59782059dab02650 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Mon, 8 Jul 2019 09:47:10 +0300 Subject: [PATCH 23/69] fix: migrate android App_Resources on `tns migrate` --- lib/controllers/migrate-controller.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 33a9ccded4..0a0e5e90ea 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -12,6 +12,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC protected $platformsDataService: IPlatformsDataService, protected $packageInstallationManager: IPackageInstallationManager, protected $packageManager: IPackageManager, + private $androidResourcesMigrationService: IAndroidResourcesMigrationService, private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, private $logger: ILogger, private $errors: IErrors, @@ -103,6 +104,8 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC this.$logger.trace(`Error during auto-generated files handling. ${(error && error.message) || error}`); } + await this.migrateOldAndroidAppResources(projectData); + try { await this.cleanUpProject(projectData); await this.migrateDependencies(projectData); @@ -112,6 +115,14 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC } } + private async migrateOldAndroidAppResources(projectData: IProjectData) { + const appResourcesPath = projectData.getAppResourcesDirectoryPath(); + if (!this.$androidResourcesMigrationService.hasMigrated(appResourcesPath)) { + this.$logger.info("Migrate old Android App_Resources structure."); + await this.$androidResourcesMigrationService.migrate(appResourcesPath); + } + } + public async shouldMigrate({ projectDir }: IProjectDir): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); @@ -134,6 +145,10 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC if (!hasDependency && dependency.shouldAddIfMissing) { return true; } + + if (!this.$androidResourcesMigrationService.hasMigrated(projectData.getAppResourcesDirectoryPath())) { + return true; + } } for (const platform in this.$devicePlatformsConstants) { From 3c2cdf7b6e5de7a6b5c5e2a5c8f290a71aa24d1d Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Mon, 8 Jul 2019 09:57:06 +0300 Subject: [PATCH 24/69] fix(migrate): show warning for `nativescript-dev-less` as its not supported out of the box in the Bundle workflow --- lib/controllers/migrate-controller.ts | 23 ++++++++++++++--------- lib/definitions/migrate.d.ts | 2 ++ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 0a0e5e90ea..6341fe77a0 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -43,10 +43,9 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.0-rc-2019-06-28-175837-02" }, { packageName: "node-sass", isDev: true, verifiedVersion: "4.12.0" }, { packageName: "typescript", isDev: true, verifiedVersion: "3.4.1" }, - { packageName: "less", isDev: true, verifiedVersion: "3.9.0" }, { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: "typescript" }, - { packageName: "nativescript-dev-less", isDev: true, replaceWith: "less" }, + { packageName: "nativescript-dev-less", isDev: true, remove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-02-161545-02" }, { packageName: "nativescript-camera", verifiedVersion: "4.5.0" }, { packageName: "nativescript-geolocation", verifiedVersion: "5.1.0" }, @@ -134,7 +133,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC return true; } - if (hasDependency && dependency.replaceWith) { + if (hasDependency && (dependency.replaceWith || dependency.remove)) { return true; } @@ -259,15 +258,21 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC private async migrateDependency(dependency: IMigrationDependency, projectData: IProjectData): Promise { const hasDependency = this.hasDependency(dependency, projectData); + if (dependency.warning) { + this.$logger.warn(dependency.warning); + } - if (hasDependency && dependency.replaceWith) { + if (hasDependency && (dependency.replaceWith || dependency.remove)) { this.$pluginsService.removeFromPackageJson(dependency.packageName, projectData.projectDir); - const replacementDep = _.find(this.migrationDependencies, migrationPackage => migrationPackage.packageName === dependency.replaceWith); - if (!replacementDep) { - this.$errors.failWithoutHelp("Failed to find replacement dependency."); + if (dependency.replaceWith) { + const replacementDep = _.find(this.migrationDependencies, migrationPackage => migrationPackage.packageName === dependency.replaceWith); + if (!replacementDep) { + this.$errors.failWithoutHelp("Failed to find replacement dependency."); + } + this.$logger.info(`Replacing '${dependency.packageName}' with '${replacementDep.packageName}'.`); + this.$pluginsService.addToPackageJson(replacementDep.packageName, replacementDep.verifiedVersion, replacementDep.isDev, projectData.projectDir); } - this.$logger.info(`Replacing '${dependency.packageName}' with '${replacementDep.packageName}'.`); - this.$pluginsService.addToPackageJson(replacementDep.packageName, replacementDep.verifiedVersion, replacementDep.isDev, projectData.projectDir); + return; } diff --git a/lib/definitions/migrate.d.ts b/lib/definitions/migrate.d.ts index 418364c9b8..3d5ec4e488 100644 --- a/lib/definitions/migrate.d.ts +++ b/lib/definitions/migrate.d.ts @@ -11,6 +11,8 @@ interface IDependency { interface IMigrationDependency extends IDependency { shouldRemove?: boolean; replaceWith?: string; + remove?: boolean; + warning?: string; verifiedVersion?: string; shouldAddIfMissing?: boolean; shouldMigrateAction?: (projectData: IProjectData) => boolean; From 1672adcbebae01f3fa77367f738fa6370902c200 Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 8 Jul 2019 10:36:43 +0300 Subject: [PATCH 25/69] fix: fix deploy with provision Currently buildData is provided through deviceDescriptor so no need to provide it as a separate argument. --- lib/controllers/deploy-controller.ts | 6 +++--- lib/definitions/run.d.ts | 1 - lib/helpers/deploy-command-helper.ts | 7 ++----- lib/helpers/livesync-command-helper.ts | 11 +++-------- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/lib/controllers/deploy-controller.ts b/lib/controllers/deploy-controller.ts index 8f9497617e..8c51ac20c3 100644 --- a/lib/controllers/deploy-controller.ts +++ b/lib/controllers/deploy-controller.ts @@ -7,13 +7,13 @@ export class DeployController { ) { } public async deploy(data: IDeployData): Promise { - const { buildData, deviceDescriptors } = data; + const { deviceDescriptors } = data; const executeAction = async (device: Mobile.IDevice) => { - await this.$prepareController.prepare(buildData); const deviceDescriptor = _.find(deviceDescriptors, dd => dd.identifier === device.deviceInfo.identifier); + await this.$prepareController.prepare(deviceDescriptor.buildData); const packageFilePath = await deviceDescriptor.buildAction(); - await this.$deviceInstallAppService.installOnDevice(device, { ...buildData, buildForDevice: !device.isEmulator }, packageFilePath); + await this.$deviceInstallAppService.installOnDevice(device, { ...deviceDescriptor.buildData, buildForDevice: !device.isEmulator }, packageFilePath); }; await this.$devicesService.execute(executeAction, (device: Mobile.IDevice) => _.some(deviceDescriptors, deviceDescriptor => deviceDescriptor.identifier === device.deviceInfo.identifier)); diff --git a/lib/definitions/run.d.ts b/lib/definitions/run.d.ts index 3dfe93169a..f0b9091065 100644 --- a/lib/definitions/run.d.ts +++ b/lib/definitions/run.d.ts @@ -8,7 +8,6 @@ declare global { } interface IDeployData { - buildData: IBuildData; deviceDescriptors: ILiveSyncDeviceDescriptor[]; } diff --git a/lib/helpers/deploy-command-helper.ts b/lib/helpers/deploy-command-helper.ts index 25f9feb78b..2ebc056765 100644 --- a/lib/helpers/deploy-command-helper.ts +++ b/lib/helpers/deploy-command-helper.ts @@ -32,7 +32,7 @@ export class DeployCommandHelper { projectDir: this.$projectData.projectDir }); - const buildData = this.$buildDataService.getBuildData(this.$projectData.projectDir, d.deviceInfo.platform, { ...this.$options, outputPath, buildForDevice: !d.isEmulator }); + const buildData = this.$buildDataService.getBuildData(this.$projectData.projectDir, d.deviceInfo.platform, { ...this.$options.argv, outputPath, buildForDevice: !d.isEmulator, skipWatcher: !this.$options.watch }); const buildAction = additionalOptions && additionalOptions.buildPlatform ? additionalOptions.buildPlatform.bind(additionalOptions.buildPlatform, d.deviceInfo.platform, buildData, this.$projectData) : @@ -50,10 +50,7 @@ export class DeployCommandHelper { return info; }); - await this.$deployController.deploy({ - buildData: this.$buildDataService.getBuildData(this.$projectData.projectDir, platform, { ...this.$options.argv, skipWatcher: !this.$options.watch }), - deviceDescriptors - }); + await this.$deployController.deploy({ deviceDescriptors }); } } $injector.register("deployCommandHelper", DeployCommandHelper); diff --git a/lib/helpers/livesync-command-helper.ts b/lib/helpers/livesync-command-helper.ts index ea2fbc1e5d..fcc6d26076 100644 --- a/lib/helpers/livesync-command-helper.ts +++ b/lib/helpers/livesync-command-helper.ts @@ -100,7 +100,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { const { liveSyncInfo, deviceDescriptors } = await this.executeLiveSyncOperationCore(devices, platform, additionalOptions); if (this.$options.release) { - await this.runInRelease(platform, deviceDescriptors, liveSyncInfo); + await this.runInRelease(platform, deviceDescriptors); return; } @@ -160,7 +160,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { return { liveSyncInfo, deviceDescriptors }; } - private async runInRelease(platform: string, deviceDescriptors: ILiveSyncDeviceDescriptor[], liveSyncInfo: ILiveSyncInfo): Promise { + private async runInRelease(platform: string, deviceDescriptors: ILiveSyncDeviceDescriptor[]): Promise { await this.$devicesService.initialize({ platform, deviceId: this.$options.device, @@ -169,12 +169,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { sdk: this.$options.sdk }); - const buildData = this.$buildDataService.getBuildData(liveSyncInfo.projectDir, platform, { ...this.$options.argv, clean: true, watch: false }); - - await this.$deployController.deploy({ - buildData, - deviceDescriptors - }); + await this.$deployController.deploy({ deviceDescriptors }); for (const deviceDescriptor of deviceDescriptors) { const device = this.$devicesService.getDeviceByIdentifier(deviceDescriptor.identifier); From 6d0185f5ae3a842444d16bcc1c5f0eb75d787181 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Mon, 8 Jul 2019 11:20:33 +0300 Subject: [PATCH 26/69] fix(migrate): remove useLegacyWorkflow property from `nsconfig` as its not respected anymore --- lib/controllers/migrate-controller.ts | 7 +-- lib/definitions/migrate.d.ts | 1 - lib/definitions/project.d.ts | 28 +++++------ lib/project-data.ts | 2 - lib/services/project-data-service.ts | 47 ++++++++++++++++++- test/options.ts | 67 --------------------------- test/stubs.ts | 5 +- 7 files changed, 68 insertions(+), 89 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 6341fe77a0..89e9111c90 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -45,7 +45,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: "typescript", isDev: true, verifiedVersion: "3.4.1" }, { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: "typescript" }, - { packageName: "nativescript-dev-less", isDev: true, remove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, + { packageName: "nativescript-dev-less", isDev: true, shouldRemove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-02-161545-02" }, { packageName: "nativescript-camera", verifiedVersion: "4.5.0" }, { packageName: "nativescript-geolocation", verifiedVersion: "5.1.0" }, @@ -133,7 +133,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC return true; } - if (hasDependency && (dependency.replaceWith || dependency.remove)) { + if (hasDependency && (dependency.replaceWith || dependency.shouldRemove)) { return true; } @@ -160,6 +160,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC private async cleanUpProject(projectData: IProjectData): Promise { this.$logger.info("Clean old project artefacts."); + this.$projectDataService.removeNsConfigProperty(projectData.projectDir, "useLegacyWorkflow"); this.$fs.deleteDirectory(path.join(projectData.projectDir, constants.HOOKS_DIR_NAME)); this.$fs.deleteDirectory(path.join(projectData.projectDir, constants.PLATFORMS_DIR_NAME)); this.$fs.deleteDirectory(path.join(projectData.projectDir, constants.NODE_MODULES_FOLDER_NAME)); @@ -262,7 +263,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC this.$logger.warn(dependency.warning); } - if (hasDependency && (dependency.replaceWith || dependency.remove)) { + if (hasDependency && (dependency.replaceWith || dependency.shouldRemove)) { this.$pluginsService.removeFromPackageJson(dependency.packageName, projectData.projectDir); if (dependency.replaceWith) { const replacementDep = _.find(this.migrationDependencies, migrationPackage => migrationPackage.packageName === dependency.replaceWith); diff --git a/lib/definitions/migrate.d.ts b/lib/definitions/migrate.d.ts index 3d5ec4e488..fca836ae31 100644 --- a/lib/definitions/migrate.d.ts +++ b/lib/definitions/migrate.d.ts @@ -11,7 +11,6 @@ interface IDependency { interface IMigrationDependency extends IDependency { shouldRemove?: boolean; replaceWith?: string; - remove?: boolean; warning?: string; verifiedVersion?: string; shouldAddIfMissing?: boolean; diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index 601017812b..5ff3dea171 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -74,7 +74,6 @@ interface INsConfig { appPath?: string; appResourcesPath?: string; shared?: boolean; - useLegacyWorkflow?: boolean; previewAppSchema?: string; } @@ -101,11 +100,6 @@ interface IProjectData extends ICreateProjectData { */ isShared: boolean; - /** - * Defines if the project has hmr enabled by default - */ - useLegacyWorkflow: boolean; - /** * Defines the schema for the preview app */ @@ -150,6 +144,14 @@ interface IProjectDataService { */ removeNSProperty(projectDir: string, propertyName: string): void; + /** + * Removes a property from `nsconfig.json`. + * @param {string} projectDir The project directory - the place where the `nsconfig.json` is located. + * @param {string} propertyName The name of the property to be removed. + * @returns {void} + */ + removeNsConfigProperty(projectDir: string, propertyName: string): void; + /** * Removes dependency from package.json * @param {string} projectDir The project directory - the place where the root package.json is located. @@ -192,12 +194,12 @@ interface IProjectDataService { */ getAppExecutableFiles(projectDir: string): string[]; - /** - * Returns a value from `nativescript` key in project's package.json. - * @param {string} jsonData The project directory - the place where the root package.json is located. - * @param {string} propertyName The name of the property to be checked in `nativescript` key. - * @returns {any} The value of the property. - */ + /** + * Returns a value from `nativescript` key in project's package.json. + * @param {string} jsonData The project directory - the place where the root package.json is located. + * @param {string} propertyName The name of the property to be checked in `nativescript` key. + * @returns {any} The value of the property. + */ getNSValueFromContent(jsonData: Object, propertyName: string): any; } @@ -496,7 +498,7 @@ interface IRemoveExtensionsOptions { pbxProjPath: string } -interface IRemoveWatchAppOptions extends IRemoveExtensionsOptions{} +interface IRemoveWatchAppOptions extends IRemoveExtensionsOptions { } interface IRubyFunction { functionName: string; diff --git a/lib/project-data.ts b/lib/project-data.ts index 538651f0db..935d1a497e 100644 --- a/lib/project-data.ts +++ b/lib/project-data.ts @@ -61,7 +61,6 @@ export class ProjectData implements IProjectData { public buildXcconfigPath: string; public podfilePath: string; public isShared: boolean; - public useLegacyWorkflow: boolean; public previewAppSchema: string; constructor(private $fs: IFileSystem, @@ -137,7 +136,6 @@ export class ProjectData implements IProjectData { this.buildXcconfigPath = path.join(this.appResourcesDirectoryPath, this.$devicePlatformsConstants.iOS, constants.BUILD_XCCONFIG_FILE_NAME); this.podfilePath = path.join(this.appResourcesDirectoryPath, this.$devicePlatformsConstants.iOS, constants.PODFILE_NAME); this.isShared = !!(this.nsConfig && this.nsConfig.shared); - this.useLegacyWorkflow = this.nsConfig && this.nsConfig.useLegacyWorkflow; this.previewAppSchema = this.nsConfig && this.nsConfig.previewAppSchema; return; } diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 71788a5ffb..78f4664ecd 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -1,5 +1,7 @@ import * as path from "path"; import { ProjectData } from "../project-data"; +import * as constants from "../constants"; +import { parseJson } from "../common/helpers"; import { exported } from "../common/decorators"; import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER, @@ -125,6 +127,12 @@ export class ProjectDataService implements IProjectDataService { }; } + public removeNsConfigProperty(projectDir: string, propertyName: string): void { + this.$logger.trace(`Removing "${propertyName}" property from nsconfig.`); + this.updateNsConfigValue(projectDir, null, [propertyName]); + this.$logger.trace(`"${propertyName}" property successfully removed.`); + } + @exported("projectDataService") public async getAndroidAssetsStructure(opts: IProjectDir): Promise { // TODO: Use image-size package to get the width and height of an image. @@ -180,6 +188,43 @@ export class ProjectDataService implements IProjectDataService { return files; } + private refreshProjectData(projectDir: string) { + if (this.projectDataCache[projectDir]) { + this.projectDataCache[projectDir].initializeProjectData(projectDir); + } + } + + private updateNsConfigValue(projectDir: string, updateObject?: INsConfig, propertiesToRemove?: string[]): void { + const nsConfigPath = path.join(projectDir, constants.CONFIG_NS_FILE_NAME); + const currentNsConfig = this.getNsConfig(nsConfigPath); + let newNsConfig = currentNsConfig; + if (updateObject) { + newNsConfig = _.assign(newNsConfig || this.getNsConfigDefaultObject(), updateObject); + } + + if (newNsConfig && propertiesToRemove && propertiesToRemove.length) { + newNsConfig = _.omit(newNsConfig, propertiesToRemove); + } + + if (newNsConfig) { + this.$fs.writeJson(nsConfigPath, newNsConfig); + this.refreshProjectData(projectDir); + } + } + + private getNsConfig(nsConfigPath: string): INsConfig { + let result: INsConfig = null; + if (this.$fs.exists(nsConfigPath)) { + const nsConfigContent = this.$fs.readText(nsConfigPath); + try { + result = parseJson(nsConfigContent); + } catch (e) { + // invalid nsconfig => null + } + } + + return result; + } private getImageDefinitions(): IImageDefinitionsStructure { const pathToImageDefinitions = path.join(__dirname, "..", "..", CLI_RESOURCES_DIR_NAME, AssetConstants.assets, AssetConstants.imageDefinitionsFileName); @@ -334,7 +379,7 @@ export class ProjectDataService implements IProjectDataService { } private getNsConfigDefaultObject(data?: Object): INsConfig { - const config: INsConfig = { useLegacyWorkflow: false }; + const config: INsConfig = {}; Object.assign(config, data); return config; diff --git a/test/options.ts b/test/options.ts index 0e21876dd5..e45bdbcb9d 100644 --- a/test/options.ts +++ b/test/options.ts @@ -263,73 +263,6 @@ describe("options", () => { }); describe("setupOptions", () => { - const testCases = [ - { - name: "no options are provided", - args: [], - data: [ - { useLegacyWorkflow: undefined, expectedHmr: true, expectedBundle: true }, - { useLegacyWorkflow: false, expectedHmr: true, expectedBundle: true }, - { useLegacyWorkflow: true, expectedHmr: true, expectedBundle: true } - ] - }, - { - name: " --hmr is provided", - args: ["--hmr"], - data: [ - { useLegacyWorkflow: undefined, expectedHmr: true, expectedBundle: true }, - { useLegacyWorkflow: false, expectedHmr: true, expectedBundle: true }, - { useLegacyWorkflow: true, expectedHmr: true, expectedBundle: true } - ] - }, - { - name: " --no-hmr is provided", - args: ["--no-hmr"], - data: [ - { useLegacyWorkflow: undefined, expectedHmr: false, expectedBundle: true }, - { useLegacyWorkflow: false, expectedHmr: false, expectedBundle: true }, - { useLegacyWorkflow: true, expectedHmr: false, expectedBundle: true } - ] - }, - { - name: " --bundle is provided", - args: ["--bundle"], - data: [ - { useLegacyWorkflow: undefined, expectedHmr: true, expectedBundle: true }, - { useLegacyWorkflow: false, expectedHmr: true, expectedBundle: true }, - { useLegacyWorkflow: true, expectedHmr: true, expectedBundle: true } - ] - }, - { - name: " --release is provided", - args: ["--release"], - data: [ - { useLegacyWorkflow: undefined, expectedHmr: false, expectedBundle: true }, - { useLegacyWorkflow: false, expectedHmr: false, expectedBundle: true }, - { useLegacyWorkflow: true, expectedHmr: false, expectedBundle: true } - ] - } - ]; - - _.each([undefined, false, true], useLegacyWorkflow => { - _.each(testCases, testCase => { - it(`should pass correctly when ${testCase.name} and useLegacyWorkflow is ${useLegacyWorkflow}`, () => { - (testCase.args || []).forEach(arg => process.argv.push(arg)); - - const options: any = createOptions(testInjector); - const projectData = { useLegacyWorkflow }; - options.setupOptions(projectData); - - (testCase.args || []).forEach(arg => process.argv.pop()); - - const data = testCase.data.find(item => item.useLegacyWorkflow === useLegacyWorkflow); - - assert.equal(!!options.argv.hmr, !!data.expectedHmr); - assert.equal(!!options.argv.bundle, !!data.expectedBundle); - }); - }); - }); - const testCasesExpectingToThrow = [ { name: "--release --hmr", diff --git a/test/stubs.ts b/test/stubs.ts index e79f58b4a8..8f540ef255 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -327,7 +327,6 @@ export class ProjectDataStub implements IProjectData { public buildXcconfigPath: string; public podfilePath: string; public isShared: boolean; - public useLegacyWorkflow: boolean; public previewAppSchema: string; public initializeProjectData(projectDir?: string): void { @@ -507,6 +506,8 @@ export class ProjectDataService implements IProjectDataService { removeNSProperty(propertyName: string): void { } + removeNsConfigProperty(projectDir: string, propertyName: string): void { } + removeDependency(dependencyName: string): void { } getProjectData(projectDir: string): IProjectData { @@ -532,7 +533,7 @@ export class ProjectDataService implements IProjectDataService { return []; } - getNSValueFromContent(): any {} + getNSValueFromContent(): any { } } export class ProjectHelperStub implements IProjectHelper { From 5e93dead90239d9a9ac46b7659b6d1a305261b12 Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 8 Jul 2019 11:34:37 +0300 Subject: [PATCH 27/69] fix: fix preview from Sidekick Currently CLI doesn't detach the PREPARE_READY_EVENT on stopPreview and this led to executing multiple times the livesync operation from sidekick. --- lib/controllers/preview-app-controller.ts | 25 +++++++++++------------ 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/lib/controllers/preview-app-controller.ts b/lib/controllers/preview-app-controller.ts index 41381e6305..bedfde8326 100644 --- a/lib/controllers/preview-app-controller.ts +++ b/lib/controllers/preview-app-controller.ts @@ -9,8 +9,8 @@ import { PrepareDataService } from "../services/prepare-data-service"; import { PreviewAppLiveSyncEvents } from "../services/livesync/playground/preview-app-constants"; export class PreviewAppController extends EventEmitter implements IPreviewAppController { + private prepareReadyEventHandler: any = null; private deviceInitializationPromise: IDictionary = {}; - private platformPrepareHandlers: IDictionary = {}; private promise = Promise.resolve(); constructor( @@ -41,6 +41,10 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon public async stopPreview(): Promise { this.$previewSdkService.stop(); this.$previewDevicesService.updateConnectedDevices([]); + if (this.prepareReadyEventHandler) { + this.removeListener(PREPARE_READY_EVENT_NAME, this.prepareReadyEventHandler); + this.prepareReadyEventHandler = null; + } } private async previewCore(data: IPreviewAppLiveSyncData): Promise { @@ -76,17 +80,11 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon await this.$previewAppPluginsService.comparePluginsOnDevice(data, device); - if (!this.platformPrepareHandlers[device.platform]) { - // TODO: Unset this property once the preview operation for this platform is stopped - this.platformPrepareHandlers[device.platform] = true; - - // TODO: Remove the handler once the preview operation for this platform is stopped - this.$prepareController.on(PREPARE_READY_EVENT_NAME, async (currentPrepareData: IFilesChangeEventData) => { - if (currentPrepareData.platform.toLowerCase() === device.platform.toLowerCase()) { - await this.handlePrepareReadyEvent(data, currentPrepareData.hmrData, currentPrepareData.files, device.platform); - } - }); - + if (!this.prepareReadyEventHandler) { + this.prepareReadyEventHandler = async (currentPrepareData: IFilesChangeEventData) => { + await this.handlePrepareReadyEvent(data, currentPrepareData); + }; + this.$prepareController.on(PREPARE_READY_EVENT_NAME, this.prepareReadyEventHandler.bind(this)); } data.env = data.env || {}; @@ -115,9 +113,10 @@ export class PreviewAppController extends EventEmitter implements IPreviewAppCon } @performanceLog() - private async handlePrepareReadyEvent(data: IPreviewAppLiveSyncData, hmrData: IPlatformHmrData, files: string[], platform: string) { + private async handlePrepareReadyEvent(data: IPreviewAppLiveSyncData, currentPrepareData: IFilesChangeEventData) { await this.promise .then(async () => { + const { hmrData, files, platform } = currentPrepareData; const platformHmrData = _.cloneDeep(hmrData); this.promise = this.syncFilesForPlatformSafe(data, { filesToSync: files }, platform); From 552c9dfced45f992c6a0a8d95bfebb9aa56750ac Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 8 Jul 2019 12:10:01 +0300 Subject: [PATCH 28/69] chore: update the versions of dependencies from migrate command --- lib/controllers/migrate-controller.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 89e9111c90..e2180b4345 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -38,7 +38,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC ]; private migrationDependencies: IMigrationDependency[] = [ - { packageName: constants.TNS_CORE_MODULES_NAME, verifiedVersion: "6.0.0-rc-2019-06-28-175837-02" }, + { packageName: constants.TNS_CORE_MODULES_NAME, verifiedVersion: "6.0.0-rc-2019-07-08-111131-01" }, { packageName: constants.TNS_CORE_MODULES_WIDGETS_NAME, verifiedVersion: "6.0.0" }, { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.0-rc-2019-06-28-175837-02" }, { packageName: "node-sass", isDev: true, verifiedVersion: "4.12.0" }, @@ -46,7 +46,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: "typescript" }, { packageName: "nativescript-dev-less", isDev: true, shouldRemove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, - { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-02-161545-02" }, + { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-08-114453-02" }, { packageName: "nativescript-camera", verifiedVersion: "4.5.0" }, { packageName: "nativescript-geolocation", verifiedVersion: "5.1.0" }, { packageName: "nativescript-imagepicker", verifiedVersion: "6.2.0" }, @@ -68,7 +68,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: "nativescript-permissions", verifiedVersion: "1.3.0" }, { packageName: "nativescript-cardview", verifiedVersion: "3.2.0" }, { - packageName: "nativescript-unit-test-runner", verifiedVersion: "0.6.3", + packageName: "nativescript-unit-test-runner", verifiedVersion: "0.6.4", shouldMigrateAction: (projectData: IProjectData) => this.hasDependency({ packageName: "nativescript-unit-test-runner", isDev: false }, projectData), migrateAction: this.migrateUnitTestRunner.bind(this) } From f869e464cf66fed699ae99300b136891e2232f69 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Mon, 8 Jul 2019 14:10:43 +0300 Subject: [PATCH 29/69] chore: fix pr comments --- lib/controllers/migrate-controller.ts | 4 +- lib/definitions/project.d.ts | 2 +- lib/services/project-data-service.ts | 4 +- test/services/project-data-service.ts | 73 +++++++++++++++++++++++++-- test/stubs.ts | 2 +- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index e2180b4345..6c71445c32 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -46,7 +46,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: "typescript" }, { packageName: "nativescript-dev-less", isDev: true, shouldRemove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, - { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-08-114453-02" }, + { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-08-135456-03" }, { packageName: "nativescript-camera", verifiedVersion: "4.5.0" }, { packageName: "nativescript-geolocation", verifiedVersion: "5.1.0" }, { packageName: "nativescript-imagepicker", verifiedVersion: "6.2.0" }, @@ -160,7 +160,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC private async cleanUpProject(projectData: IProjectData): Promise { this.$logger.info("Clean old project artefacts."); - this.$projectDataService.removeNsConfigProperty(projectData.projectDir, "useLegacyWorkflow"); + this.$projectDataService.removeNSConfigProperty(projectData.projectDir, "useLegacyWorkflow"); this.$fs.deleteDirectory(path.join(projectData.projectDir, constants.HOOKS_DIR_NAME)); this.$fs.deleteDirectory(path.join(projectData.projectDir, constants.PLATFORMS_DIR_NAME)); this.$fs.deleteDirectory(path.join(projectData.projectDir, constants.NODE_MODULES_FOLDER_NAME)); diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index 5ff3dea171..56c9e23ee4 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -150,7 +150,7 @@ interface IProjectDataService { * @param {string} propertyName The name of the property to be removed. * @returns {void} */ - removeNsConfigProperty(projectDir: string, propertyName: string): void; + removeNSConfigProperty(projectDir: string, propertyName: string): void; /** * Removes dependency from package.json diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 78f4664ecd..b9edeb98f0 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -127,7 +127,7 @@ export class ProjectDataService implements IProjectDataService { }; } - public removeNsConfigProperty(projectDir: string, propertyName: string): void { + public removeNSConfigProperty(projectDir: string, propertyName: string): void { this.$logger.trace(`Removing "${propertyName}" property from nsconfig.`); this.updateNsConfigValue(projectDir, null, [propertyName]); this.$logger.trace(`"${propertyName}" property successfully removed.`); @@ -219,7 +219,7 @@ export class ProjectDataService implements IProjectDataService { try { result = parseJson(nsConfigContent); } catch (e) { - // invalid nsconfig => null + this.$logger.trace("The `nsconfig` content is not a valid JSON. Parse error: ", e); } } diff --git a/test/services/project-data-service.ts b/test/services/project-data-service.ts index 98c304e431..2499c4b280 100644 --- a/test/services/project-data-service.ts +++ b/test/services/project-data-service.ts @@ -2,10 +2,11 @@ import { Yok } from "../../lib/common/yok"; import { assert } from "chai"; import { ProjectDataService } from "../../lib/services/project-data-service"; import { LoggerStub, ProjectDataStub } from "../stubs"; -import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER, PACKAGE_JSON_FILE_NAME, AssetConstants, ProjectTypes } from '../../lib/constants'; +import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER, PACKAGE_JSON_FILE_NAME, CONFIG_NS_FILE_NAME, AssetConstants, ProjectTypes } from '../../lib/constants'; import { DevicePlatformsConstants } from "../../lib/common/mobile/device-platforms-constants"; import { basename, join } from "path"; import { FileSystem } from "../../lib/common/file-system"; +import { regExpEscape } from "../../lib/common/helpers"; const CLIENT_NAME_KEY_IN_PROJECT_FILE = "nativescript"; @@ -41,7 +42,7 @@ const testData: any = [ } ]; -const createTestInjector = (readTextData?: string): IInjector => { +const createTestInjector = (packageJsonContent?: string, nsConfigContent?: string): IInjector => { const testInjector = new Yok(); testInjector.register("projectData", ProjectDataStub); testInjector.register("staticConfig", { @@ -55,10 +56,14 @@ const createTestInjector = (readTextData?: string): IInjector => { }, readText: (filename: string, encoding?: IReadFileOptions | string): string => { - return readTextData; + if (filename.indexOf("package.json") > -1) { + return packageJsonContent; + } else if (filename.indexOf("nsconfig.json") > -1) { + return nsConfigContent; + } }, - exists: (filePath: string): boolean => basename(filePath) === PACKAGE_JSON_FILE_NAME, + exists: (filePath: string): boolean => (basename(filePath) === PACKAGE_JSON_FILE_NAME || basename(filePath) === CONFIG_NS_FILE_NAME), readJson: (filePath: string): any => null, @@ -245,6 +250,66 @@ describe("projectDataService", () => { }); }); + describe("removeNSConfigProperty", () => { + + const generateExpectedDataFromTestData = (currentTestData: any) => { + const props = currentTestData.propertyName.split(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER); + props.splice(props.length - 1, 1); + + const data: any = {}; + let currentData: any = data; + + _.each(props, (prop) => { + currentData = currentData[prop] = {}; + }); + + return data; + }; + + _.each(testData, currentTestData => { + + it(currentTestData.description, () => { + const testInjector = createTestInjector(null, generateFileContentFromTestData(currentTestData, true)); + const fs: IFileSystem = testInjector.resolve("fs"); + + let dataPassedToWriteJson: any = null; + fs.writeJson = (filename: string, data: any, space?: string, encoding?: string): void => { + dataPassedToWriteJson = data; + }; + + const projectDataService: IProjectDataService = testInjector.resolve("projectDataService"); + const propDelimiterRegExp = new RegExp(regExpEscape(NATIVESCRIPT_PROPS_INTERNAL_DELIMITER), "g"); + const propertySelector = currentTestData.propertyName.replace(propDelimiterRegExp, "."); + projectDataService.removeNSConfigProperty("projectDir", propertySelector); + + assert.deepEqual(dataPassedToWriteJson, generateExpectedDataFromTestData(currentTestData)); + }); + + }); + + it("removes only the selected property", () => { + const initialData: any = {}; + initialData[CLIENT_NAME_KEY_IN_PROJECT_FILE] = { + "root": { + "id": "1", + "constantItem": "myValue" + } + }; + + const testInjector = createTestInjector(JSON.stringify(initialData)); + const fs: IFileSystem = testInjector.resolve("fs"); + + let dataPassedToWriteJson: any = null; + fs.writeJson = (filename: string, data: any, space?: string, encoding?: string): void => { + dataPassedToWriteJson = data; + }; + + const projectDataService: IProjectDataService = testInjector.resolve("projectDataService"); + projectDataService.removeNSProperty("projectDir", getPropertyName(["root", "id"])); + assert.deepEqual(dataPassedToWriteJson, { nativescript: { root: { constantItem: "myValue" } } }); + }); + }); + describe("removeDependency", () => { it("removes specified dependency from project file", () => { const currentTestData = { diff --git a/test/stubs.ts b/test/stubs.ts index 8f540ef255..e3ee506cd7 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -506,7 +506,7 @@ export class ProjectDataService implements IProjectDataService { removeNSProperty(propertyName: string): void { } - removeNsConfigProperty(projectDir: string, propertyName: string): void { } + removeNSConfigProperty(projectDir: string, propertyName: string): void { } removeDependency(dependencyName: string): void { } From c37d1dd2253a813ea7ea41649b5d337a2784e102 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Mon, 8 Jul 2019 17:25:54 +0300 Subject: [PATCH 30/69] fix: build output location not printed --- lib/controllers/build-controller.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/controllers/build-controller.ts b/lib/controllers/build-controller.ts index fc94dab0fa..56f6fb16b7 100644 --- a/lib/controllers/build-controller.ts +++ b/lib/controllers/build-controller.ts @@ -66,7 +66,8 @@ export class BuildController extends EventEmitter implements IBuildController { if (buildData.copyTo) { this.$buildArtefactsService.copyLatestAppPackage(buildData.copyTo, platformData, buildData); - this.$logger.info(`The build result is located at: ${buildInfoFileDir}`); + } else { + this.$logger.info(`The build result is located at: ${result}`); } return result; From 2dba8834e760045dce9122c4d8b492f606d42b45 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 10 Jul 2019 08:59:18 +0300 Subject: [PATCH 31/69] fix: add skipNativePrepare to buildData --- lib/helpers/deploy-command-helper.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/helpers/deploy-command-helper.ts b/lib/helpers/deploy-command-helper.ts index 2ebc056765..2ebdeaed58 100644 --- a/lib/helpers/deploy-command-helper.ts +++ b/lib/helpers/deploy-command-helper.ts @@ -32,7 +32,14 @@ export class DeployCommandHelper { projectDir: this.$projectData.projectDir }); - const buildData = this.$buildDataService.getBuildData(this.$projectData.projectDir, d.deviceInfo.platform, { ...this.$options.argv, outputPath, buildForDevice: !d.isEmulator, skipWatcher: !this.$options.watch }); + const buildData = this.$buildDataService.getBuildData(this.$projectData.projectDir, d.deviceInfo.platform, + { + ...this.$options.argv, + outputPath, + buildForDevice: !d.isEmulator, + skipWatcher: !this.$options.watch, + nativePrepare: { skipNativePrepare: additionalOptions && additionalOptions.skipNativePrepare } + }); const buildAction = additionalOptions && additionalOptions.buildPlatform ? additionalOptions.buildPlatform.bind(additionalOptions.buildPlatform, d.deviceInfo.platform, buildData, this.$projectData) : From 1c03901c81dcdf6b4b6a8ba0d55ab979b3e36976 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 10 Jul 2019 12:34:27 +0300 Subject: [PATCH 32/69] fix: execute npm install before all hooks CLI must install all project dependencies before running any hook as the hooks are commonly created during the installation of packages. In the current codebase we install the depenencies only during `run` operation, however we actually need this to be executed before each project preparation. To fix the behavior move the installation of dependencies in the prepareController and remove it from webpack-compiler-service. Also remove hook which is no longer supported - prepareJS. --- lib/controllers/prepare-controller.ts | 40 +++++++++++-------- .../webpack/webpack-compiler-service.ts | 5 --- 2 files changed, 24 insertions(+), 21 deletions(-) diff --git a/lib/controllers/prepare-controller.ts b/lib/controllers/prepare-controller.ts index e488c1e641..c201b2beef 100644 --- a/lib/controllers/prepare-controller.ts +++ b/lib/controllers/prepare-controller.ts @@ -22,6 +22,7 @@ export class PrepareController extends EventEmitter { private $logger: ILogger, private $nodeModulesDependenciesBuilder: INodeModulesDependenciesBuilder, private $platformsDataService: IPlatformsDataService, + private $pluginsService: IPluginsService, private $prepareNativePlatformService: IPrepareNativePlatformService, private $projectChangesService: IProjectChangesService, private $projectDataService: IProjectDataService, @@ -29,10 +30,31 @@ export class PrepareController extends EventEmitter { private $watchIgnoreListService: IWatchIgnoreListService ) { super(); } - @performanceLog() - @hook("prepare") public async prepare(prepareData: IPrepareData): Promise { const projectData = this.$projectDataService.getProjectData(prepareData.projectDir); + + await this.$pluginsService.ensureAllDependenciesAreInstalled(projectData); + + return this.prepareCore(prepareData, projectData); + } + + public async stopWatchers(projectDir: string, platform: string): Promise { + const platformLowerCase = platform.toLowerCase(); + + if (this.watchersData && this.watchersData[projectDir] && this.watchersData[projectDir][platformLowerCase] && this.watchersData[projectDir][platformLowerCase].nativeFilesWatcher) { + this.watchersData[projectDir][platformLowerCase].nativeFilesWatcher.close(); + this.watchersData[projectDir][platformLowerCase].nativeFilesWatcher = null; + } + + if (this.watchersData && this.watchersData[projectDir] && this.watchersData[projectDir][platformLowerCase] && this.watchersData[projectDir][platformLowerCase].hasWebpackCompilerProcess) { + await this.$webpackCompilerService.stopWebpackCompiler(platform); + this.watchersData[projectDir][platformLowerCase].hasWebpackCompilerProcess = false; + } + } + + @performanceLog() + @hook("prepare") + private async prepareCore(prepareData: IPrepareData, projectData: IProjectData): Promise { this.$bundleValidatorHelper.validate(projectData, "1.0.0"); await this.$platformController.addPlatformIfNeeded(prepareData); @@ -57,20 +79,6 @@ export class PrepareController extends EventEmitter { return result; } - public async stopWatchers(projectDir: string, platform: string): Promise { - const platformLowerCase = platform.toLowerCase(); - - if (this.watchersData && this.watchersData[projectDir] && this.watchersData[projectDir][platformLowerCase] && this.watchersData[projectDir][platformLowerCase].nativeFilesWatcher) { - this.watchersData[projectDir][platformLowerCase].nativeFilesWatcher.close(); - this.watchersData[projectDir][platformLowerCase].nativeFilesWatcher = null; - } - - if (this.watchersData && this.watchersData[projectDir] && this.watchersData[projectDir][platformLowerCase] && this.watchersData[projectDir][platformLowerCase].hasWebpackCompilerProcess) { - await this.$webpackCompilerService.stopWebpackCompiler(platform); - this.watchersData[projectDir][platformLowerCase].hasWebpackCompilerProcess = false; - } - } - @hook("watch") private async startWatchersWithPrepare(platformData: IPlatformData, projectData: IProjectData, prepareData: IPrepareData): Promise { if (!this.watchersData[projectData.projectDir]) { diff --git a/lib/services/webpack/webpack-compiler-service.ts b/lib/services/webpack/webpack-compiler-service.ts index f795aaa72d..58110df109 100644 --- a/lib/services/webpack/webpack-compiler-service.ts +++ b/lib/services/webpack/webpack-compiler-service.ts @@ -2,7 +2,6 @@ import * as path from "path"; import * as child_process from "child_process"; import { EventEmitter } from "events"; import { performanceLog } from "../../common/decorators"; -import { hook } from "../../common/helpers"; import { WEBPACK_COMPILATION_COMPLETE } from "../../constants"; export class WebpackCompilerService extends EventEmitter implements IWebpackCompilerService { @@ -13,7 +12,6 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp public $hooksService: IHooksService, public $hostInfo: IHostInfo, private $logger: ILogger, - private $pluginsService: IPluginsService, private $mobileHelper: Mobile.IMobileHelper, private $cleanupService: ICleanupService ) { super(); } @@ -129,13 +127,10 @@ export class WebpackCompilerService extends EventEmitter implements IWebpackComp } @performanceLog() - @hook('prepareJSApp') private async startWebpackProcess(platformData: IPlatformData, projectData: IProjectData, prepareData: IPrepareData): Promise { const envData = this.buildEnvData(platformData.platformNameLowerCase, projectData, prepareData); const envParams = this.buildEnvCommandLineParams(envData, platformData, prepareData); - await this.$pluginsService.ensureAllDependenciesAreInstalled(projectData); - const args = [ path.join(projectData.projectDir, "node_modules", "webpack", "bin", "webpack.js"), "--preserve-symlinks", From 47484fd6f62e2292536af7da2a9964f051ed9e23 Mon Sep 17 00:00:00 2001 From: rosen-vladimirov Date: Wed, 10 Jul 2019 12:41:58 +0300 Subject: [PATCH 33/69] fix: `tns debug ios` should work on device Currently `tns debug ios` hangs when executed for device. The problem is that we pass `"waitForDebugger": false` to ios-device-lib binary, which can parse only strings. The value `false` is boolean, not string, so ios-device-lib binary crashes, but CLI does not understand this and hangs. Fix this by ensuring we pass waitForDebugger as string. --- lib/common/mobile/ios/device/ios-application-manager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/common/mobile/ios/device/ios-application-manager.ts b/lib/common/mobile/ios/device/ios-application-manager.ts index 5c757de159..4e7d0bc44e 100644 --- a/lib/common/mobile/ios/device/ios-application-manager.ts +++ b/lib/common/mobile/ios/device/ios-application-manager.ts @@ -102,7 +102,7 @@ export class IOSApplicationManager extends ApplicationManagerBase { } private async runApplicationCore(appData: Mobile.IStartApplicationData): Promise { - const waitForDebugger = appData.waitForDebugger && appData.waitForDebugger.toString(); + const waitForDebugger = (!!appData.waitForDebugger).toString(); await this.$iosDeviceOperations.start([{ deviceId: this.device.deviceInfo.identifier, appId: appData.appId, ddi: this.$options.ddi, waitForDebugger }]); } From f10b0e5d2c65539176d2699727e1aa8153b9b5bf Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 09:06:30 +0300 Subject: [PATCH 34/69] fix: include nativescript-dev-webpack in the update command --- lib/controllers/update-controller.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/controllers/update-controller.ts b/lib/controllers/update-controller.ts index 8e662ce5b8..e93b0d7afb 100644 --- a/lib/controllers/update-controller.ts +++ b/lib/controllers/update-controller.ts @@ -5,7 +5,10 @@ import { UpdateControllerBase } from "./update-controller-base"; export class UpdateController extends UpdateControllerBase implements IUpdateController { private getTemplateManifest: Function; - static readonly updatableDependencies: string[] = [constants.TNS_CORE_MODULES_NAME, constants.TNS_CORE_MODULES_WIDGETS_NAME]; + static readonly updatableDependencies: string[] = [ + constants.TNS_CORE_MODULES_NAME, + constants.TNS_CORE_MODULES_WIDGETS_NAME, + constants.WEBPACK_PLUGIN_NAME]; static readonly folders: string[] = [ constants.LIB_DIR_NAME, constants.HOOKS_DIR_NAME, From fdb1fe373b9211de52d80ca4608367c16edf27af Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 09:18:47 +0300 Subject: [PATCH 35/69] fix: update versions in the migrate command. --- lib/controllers/migrate-controller.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 6c71445c32..d2b54fb48c 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -38,15 +38,15 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC ]; private migrationDependencies: IMigrationDependency[] = [ - { packageName: constants.TNS_CORE_MODULES_NAME, verifiedVersion: "6.0.0-rc-2019-07-08-111131-01" }, + { packageName: constants.TNS_CORE_MODULES_NAME, verifiedVersion: "6.0.0-rc-2019-07-09-183845-06" }, { packageName: constants.TNS_CORE_MODULES_WIDGETS_NAME, verifiedVersion: "6.0.0" }, - { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.0-rc-2019-06-28-175837-02" }, + { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.0-rc-2019-07-09-183845-06" }, { packageName: "node-sass", isDev: true, verifiedVersion: "4.12.0" }, { packageName: "typescript", isDev: true, verifiedVersion: "3.4.1" }, { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: "typescript" }, { packageName: "nativescript-dev-less", isDev: true, shouldRemove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, - { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-08-135456-03" }, + { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-10-002255-01" }, { packageName: "nativescript-camera", verifiedVersion: "4.5.0" }, { packageName: "nativescript-geolocation", verifiedVersion: "5.1.0" }, { packageName: "nativescript-imagepicker", verifiedVersion: "6.2.0" }, @@ -59,12 +59,10 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: "nativescript-ui-calendar", verifiedVersion: "5.0.0-androidx-110619-2" }, { packageName: "nativescript-ui-autocomplete", verifiedVersion: "5.0.0-androidx-110619" }, { packageName: "nativescript-datetimepicker", verifiedVersion: "1.1.0" }, - //TODO update with compatible with webpack only hooks { packageName: "kinvey-nativescript-sdk", verifiedVersion: "4.2.1" }, - //TODO update with compatible with webpack only hooks - { packageName: "nativescript-plugin-firebase", verifiedVersion: "9.0.1" }, - //TODO update with no prerelease version compatible with webpack only hooks - { packageName: "nativescript-vue", verifiedVersion: "2.3.0-rc.1" }, + { packageName: "nativescript-plugin-firebase", verifiedVersion: "9.0.2" }, + // TODO: update with no prerelease version compatible with webpack only hooks + { packageName: "nativescript-vue", verifiedVersion: "2.3.0-rc.2" }, { packageName: "nativescript-permissions", verifiedVersion: "1.3.0" }, { packageName: "nativescript-cardview", verifiedVersion: "3.2.0" }, { From 19ae3ef09f8e91e9623f259b9af1231180e5ad7d Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 09:30:53 +0300 Subject: [PATCH 36/69] fix: avoid a failng migration because of a failing app resources update --- lib/controllers/migrate-controller.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index d2b54fb48c..f80db32215 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -116,7 +116,11 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC const appResourcesPath = projectData.getAppResourcesDirectoryPath(); if (!this.$androidResourcesMigrationService.hasMigrated(appResourcesPath)) { this.$logger.info("Migrate old Android App_Resources structure."); - await this.$androidResourcesMigrationService.migrate(appResourcesPath); + try { + await this.$androidResourcesMigrationService.migrate(appResourcesPath); + } catch (error) { + this.$logger.warn("Migrate old Android App_Resources structure failed: ", error.message); + } } } From 33bc9adf7511d98989b962f50d08405b38407597 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 14:01:06 +0300 Subject: [PATCH 37/69] fix(migrate): get the TypeScript version from the Angular peer dependency when available --- lib/controllers/migrate-controller.ts | 80 +++++++++++++++++------ lib/controllers/update-controller-base.ts | 20 +++++- lib/controllers/update-controller.ts | 16 +---- lib/definitions/migrate.d.ts | 1 + 4 files changed, 79 insertions(+), 38 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index f80db32215..9c0f18868a 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -12,6 +12,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC protected $platformsDataService: IPlatformsDataService, protected $packageInstallationManager: IPackageInstallationManager, protected $packageManager: IPackageManager, + protected $pacoteService: IPacoteService, private $androidResourcesMigrationService: IAndroidResourcesMigrationService, private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, private $logger: ILogger, @@ -20,9 +21,10 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC private $pluginsService: IPluginsService, private $projectDataService: IProjectDataService, private $resources: IResourceLoader) { - super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager); + super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager, $pacoteService); } + static readonly typescriptPackageName: string = "typescript"; static readonly backupFolder: string = ".migration_backup"; static readonly migrateFailMessage: string = "Could not migrate the project!"; static readonly backupFailMessage: string = "Could not backup project folders!"; @@ -42,9 +44,34 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: constants.TNS_CORE_MODULES_WIDGETS_NAME, verifiedVersion: "6.0.0" }, { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.0-rc-2019-07-09-183845-06" }, { packageName: "node-sass", isDev: true, verifiedVersion: "4.12.0" }, - { packageName: "typescript", isDev: true, verifiedVersion: "3.4.1" }, + { + packageName: MigrateController.typescriptPackageName, isDev: true, getVerifiedVersion: async (projectData: IProjectData) => { + let verifiedVersion = "3.4.1"; + try { + const ngcPackageName = "@angular/compiler-cli"; + // e.g. ~8.0.0 + let ngcVersion = projectData.dependencies[ngcPackageName] || projectData.devDependencies[ngcPackageName]; + if (ngcVersion) { + // e.g. ~8.0.3 + ngcVersion = await this.$packageInstallationManager.maxSatisfyingVersion(ngcPackageName, ngcVersion); + const ngcManifest = await this.getTemplateManifest(ngcPackageName, ngcVersion); + // e.g. >=3.4 <3.5 + verifiedVersion = (ngcManifest && ngcManifest.peerDependencies && + ngcManifest.peerDependencies[MigrateController.typescriptPackageName]) || verifiedVersion; + + // e.g. 3.4.4 + verifiedVersion = await this.$packageInstallationManager.maxSatisfyingVersion( + MigrateController.typescriptPackageName, verifiedVersion); + } + } catch (error) { + this.$logger.warn(`Unable to determine the TypeScript version based on the Angular packages. Error is: '${error}'.`); + } + + return verifiedVersion; + } + }, { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, - { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: "typescript" }, + { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: MigrateController.typescriptPackageName }, { packageName: "nativescript-dev-less", isDev: true, shouldRemove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-10-002255-01" }, { packageName: "nativescript-camera", verifiedVersion: "4.5.0" }, @@ -112,18 +139,6 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC } } - private async migrateOldAndroidAppResources(projectData: IProjectData) { - const appResourcesPath = projectData.getAppResourcesDirectoryPath(); - if (!this.$androidResourcesMigrationService.hasMigrated(appResourcesPath)) { - this.$logger.info("Migrate old Android App_Resources structure."); - try { - await this.$androidResourcesMigrationService.migrate(appResourcesPath); - } catch (error) { - this.$logger.warn("Migrate old Android App_Resources structure failed: ", error.message); - } - } - } - public async shouldMigrate({ projectDir }: IProjectDir): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); @@ -160,6 +175,18 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC } } + private async migrateOldAndroidAppResources(projectData: IProjectData) { + const appResourcesPath = projectData.getAppResourcesDirectoryPath(); + if (!this.$androidResourcesMigrationService.hasMigrated(appResourcesPath)) { + this.$logger.info("Migrate old Android App_Resources structure."); + try { + await this.$androidResourcesMigrationService.migrate(appResourcesPath); + } catch (error) { + this.$logger.warn("Migrate old Android App_Resources structure failed: ", error.message); + } + } + } + private async cleanUpProject(projectData: IProjectData): Promise { this.$logger.info("Clean old project artefacts."); this.$projectDataService.removeNSConfigProperty(projectData.projectDir, "useLegacyWorkflow"); @@ -261,6 +288,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC private async migrateDependency(dependency: IMigrationDependency, projectData: IProjectData): Promise { const hasDependency = this.hasDependency(dependency, projectData); + const dependencyVersion = await this.getDependencyVerifiedVersion(dependency, projectData); if (dependency.warning) { this.$logger.warn(dependency.warning); } @@ -272,33 +300,43 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC if (!replacementDep) { this.$errors.failWithoutHelp("Failed to find replacement dependency."); } + + const replacementDepVersion = await this.getDependencyVerifiedVersion(replacementDep, projectData); this.$logger.info(`Replacing '${dependency.packageName}' with '${replacementDep.packageName}'.`); - this.$pluginsService.addToPackageJson(replacementDep.packageName, replacementDep.verifiedVersion, replacementDep.isDev, projectData.projectDir); + this.$pluginsService.addToPackageJson(replacementDep.packageName, replacementDepVersion, replacementDep.isDev, projectData.projectDir); } return; } if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData)) { - this.$logger.info(`Updating '${dependency.packageName}' to compatible version '${dependency.verifiedVersion}'`); - this.$pluginsService.addToPackageJson(dependency.packageName, dependency.verifiedVersion, dependency.isDev, projectData.projectDir); + this.$logger.info(`Updating '${dependency.packageName}' to compatible version '${dependencyVersion}'`); + this.$pluginsService.addToPackageJson(dependency.packageName, dependencyVersion, dependency.isDev, projectData.projectDir); return; } if (!hasDependency && dependency.shouldAddIfMissing) { - this.$logger.info(`Adding '${dependency.packageName}' with version '${dependency.verifiedVersion}'`); - this.$pluginsService.addToPackageJson(dependency.packageName, dependency.verifiedVersion, dependency.isDev, projectData.projectDir); + this.$logger.info(`Adding '${dependency.packageName}' with version '${dependencyVersion}'`); + this.$pluginsService.addToPackageJson(dependency.packageName, dependencyVersion, dependency.isDev, projectData.projectDir); } } + private async getDependencyVerifiedVersion(dependency: IMigrationDependency, projectData: IProjectData): Promise { + const verifiedVersion = dependency.getVerifiedVersion ? + await dependency.getVerifiedVersion(projectData) : dependency.verifiedVersion; + + return verifiedVersion; + } + private async shouldMigrateDependencyVersion(dependency: IMigrationDependency, projectData: IProjectData): Promise { const devDependencies = projectData.devDependencies || {}; const dependencies = projectData.dependencies || {}; const packageName = dependency.packageName; const version = dependencies[packageName] || devDependencies[packageName]; const maxSatisfyingVersion = await this.getMaxDependencyVersion(dependency.packageName, version); + const dependencyVersion = await this.getDependencyVerifiedVersion(dependency, projectData); - return !(maxSatisfyingVersion && semver.gte(maxSatisfyingVersion, dependency.verifiedVersion)); + return !(maxSatisfyingVersion && semver.gte(maxSatisfyingVersion, dependencyVersion)); } protected async shouldUpdateRuntimeVersion({ targetVersion, platform, projectData }: { targetVersion: string, platform: string, projectData: IProjectData }): Promise { diff --git a/lib/controllers/update-controller-base.ts b/lib/controllers/update-controller-base.ts index ea0c591d39..9f2eb4b3e6 100644 --- a/lib/controllers/update-controller-base.ts +++ b/lib/controllers/update-controller-base.ts @@ -2,11 +2,17 @@ import * as path from "path"; import * as semver from "semver"; export class UpdateControllerBase { + protected getTemplateManifest: Function; + constructor(protected $fs: IFileSystem, protected $platformCommandHelper: IPlatformCommandHelper, protected $platformsDataService: IPlatformsDataService, protected $packageInstallationManager: IPackageInstallationManager, - protected $packageManager: IPackageManager) { + protected $packageManager: IPackageManager, + protected $pacoteService: IPacoteService) { + this.getTemplateManifest = _.memoize(this._getTemplateManifest, (...args) => { + return args.join("@"); + }); } protected restoreBackup(folders: string[], backupDir: string, projectDir: string): void { @@ -39,13 +45,13 @@ export class UpdateControllerBase { return (dependencies && dependencies[dependency.packageName]) || (devDependencies && devDependencies[dependency.packageName]); } - protected hasRuntimeDependency({platform, projectData}: {platform: string, projectData: IProjectData}): boolean { + protected hasRuntimeDependency({ platform, projectData }: { platform: string, projectData: IProjectData }): boolean { const lowercasePlatform = platform.toLowerCase(); const currentPlatformVersion = this.$platformCommandHelper.getCurrentPlatformVersion(lowercasePlatform, projectData); return !!currentPlatformVersion; } - protected async getMaxRuntimeVersion({platform, projectData}: {platform: string, projectData: IProjectData}) { + protected async getMaxRuntimeVersion({ platform, projectData }: { platform: string, projectData: IProjectData }) { const lowercasePlatform = platform.toLowerCase(); const currentPlatformVersion = this.$platformCommandHelper.getCurrentPlatformVersion(lowercasePlatform, projectData); const platformData = this.$platformsDataService.getPlatformData(lowercasePlatform, projectData); @@ -66,4 +72,12 @@ export class UpdateControllerBase { return maxDependencyVersion; } + + private async _getTemplateManifest(templateName: string, version?: string) { + const packageVersion = semver.valid(version) || + await this.$packageManager.getTagVersion(templateName, version) || + await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); + + return await this.$pacoteService.manifest(`${templateName}@${packageVersion}`, { fullMetadata: true }); + } } diff --git a/lib/controllers/update-controller.ts b/lib/controllers/update-controller.ts index e93b0d7afb..341e2cbca5 100644 --- a/lib/controllers/update-controller.ts +++ b/lib/controllers/update-controller.ts @@ -4,7 +4,6 @@ import * as constants from "../constants"; import { UpdateControllerBase } from "./update-controller-base"; export class UpdateController extends UpdateControllerBase implements IUpdateController { - private getTemplateManifest: Function; static readonly updatableDependencies: string[] = [ constants.TNS_CORE_MODULES_NAME, constants.TNS_CORE_MODULES_WIDGETS_NAME, @@ -31,12 +30,9 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon private $addPlatformService: IAddPlatformService, private $logger: ILogger, private $pluginsService: IPluginsService, - private $pacoteService: IPacoteService, + protected $pacoteService: IPacoteService, private $projectDataService: IProjectDataService) { - super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager); - this.getTemplateManifest = _.memoize(this._getTemplateManifest, (...args) => { - return args.join("@"); - }); + super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager, $pacoteService); } public async update(updateOptions: IUpdateOptions): Promise { @@ -183,14 +179,6 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon return maxTemplateRuntimeVersion && maxRuntimeVersion && semver.gt(maxTemplateRuntimeVersion, maxRuntimeVersion); } - private async _getTemplateManifest(templateName: string, version?: string) { - const packageVersion = semver.valid(version) || - await this.$packageManager.getTagVersion(templateName, version) || - await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); - - return await this.$pacoteService.manifest(`${templateName}@${packageVersion}`, { fullMetadata: true }); - } - private getUpdatableDependencies(dependencies: IDictionary): IDictionary { return _.pickBy(dependencies, (value, key) => { return UpdateController.updatableDependencies.indexOf(key) > -1; diff --git a/lib/definitions/migrate.d.ts b/lib/definitions/migrate.d.ts index fca836ae31..e7e434693d 100644 --- a/lib/definitions/migrate.d.ts +++ b/lib/definitions/migrate.d.ts @@ -13,6 +13,7 @@ interface IMigrationDependency extends IDependency { replaceWith?: string; warning?: string; verifiedVersion?: string; + getVerifiedVersion?: (projectData: IProjectData) => Promise; shouldAddIfMissing?: boolean; shouldMigrateAction?: (projectData: IProjectData) => boolean; migrateAction?: (projectData: IProjectData, migrationBackupDirPath: string) => Promise; From 701ba20c9bd9673a35753547ef1393eae118d189 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 10 Jul 2019 14:04:15 +0300 Subject: [PATCH 38/69] docs: introduce help for migrate command --- docs/man_pages/general/migrate.md | 64 +++++++++++++++++++ docs/man_pages/general/package-manager-get.md | 2 +- docs/man_pages/general/package-manager-set.md | 2 +- docs/man_pages/general/update.md | 2 +- docs/man_pages/general/usage-reporting.md | 2 +- docs/man_pages/index.md | 1 + 6 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 docs/man_pages/general/migrate.md diff --git a/docs/man_pages/general/migrate.md b/docs/man_pages/general/migrate.md new file mode 100644 index 0000000000..949e38725b --- /dev/null +++ b/docs/man_pages/general/migrate.md @@ -0,0 +1,64 @@ +<% if (isJekyll) { %>--- +title: tns migrate +position: 15 +---<% } %> + +# tns migrate + +### Description + +Migrates the app dependencies to a form compatible with NativeScript 6.0. Running this command will not affect the codebase of the application and you might need to do additional changes manually. + +The migrate command will update **"webpack.config.js"**, **"karma.conf.js"**, **"tsconfig.tns.json"**(not for code sharing projects) and **"package-lock.json"**. The original files will be moved to **".migration_backup"** folder. +The following folders will be removed: **"hooks"**, **"platforms"** and **"node_modules"**. The **"hooks"** folder will also be backed up in **".migration_backup"** folder. + +The **"nativescript-dev-sass"** and **"nativescript-dev-typescript"** dependencies will be replaced with **"node-sass"** and **"typescript"** respectively. +The **"nativescript-dev-less"** dependency will be removed, but to enable LESS CSS support the user should follow the steps in this<% if(isConsole) { %> feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967.<% } %><% if(isHtml) { %> [feature request](https://github.com/NativeScript/nativescript-dev-webpack/issues/967).<% } %> + +The following dependencies will be updated if needed: +* tns-core-modules +* tns-core-modules-widgets +* tns-platform-declarations +* nativescript-dev-webpack +* nativescript-camera +* nativescript-geolocation +* nativescript-imagepicker +* nativescript-permissions +* nativescript-social-share +* nativescript-ui-chart +* nativescript-ui-dataform +* nativescript-ui-gauge +* nativescript-ui-listview +* nativescript-ui-sidedrawer +* nativescript-ui-calendar +* nativescript-ui-autocomplete +* nativescript-cardview +* nativescript-datetimepicker +* kinvey-nativescript-sdk +* nativescript-plugin-firebase +* nativescript-vue +* nativescript-unit-test-runner +* karma-webpack +* karma-jasmine +* karma-mocha +* karma-chai +* karma-qunit +* karma" + + +### Commands + +Usage | Synopsis +------|------- +General | `$ tns migrate` + +<% if(isHtml) { %> + +### Related Commands + +Command | Description +----------|---------- +[update](update.html) | Updates the project with the latest versions of iOS/Android runtimes and cross-platform modules. +[help](help.html) | Lists the available commands or shows information about the selected command. +[doctor](doctor.html) | Checks your system for configuration problems which might prevent the NativeScript CLI from working properly. +<% } %> diff --git a/docs/man_pages/general/package-manager-get.md b/docs/man_pages/general/package-manager-get.md index e1fd3de934..ba516da2a3 100644 --- a/docs/man_pages/general/package-manager-get.md +++ b/docs/man_pages/general/package-manager-get.md @@ -1,6 +1,6 @@ <% if (isJekyll) { %>--- title: tns package-manager get -position: 18 +position: 19 ---<% } %> # tns package-manager get diff --git a/docs/man_pages/general/package-manager-set.md b/docs/man_pages/general/package-manager-set.md index 38bf182674..333ae3c93a 100644 --- a/docs/man_pages/general/package-manager-set.md +++ b/docs/man_pages/general/package-manager-set.md @@ -1,6 +1,6 @@ <% if (isJekyll) { %>--- title: tns package-manager set -position: 17 +position: 18 ---<% } %> # tns package-manager set diff --git a/docs/man_pages/general/update.md b/docs/man_pages/general/update.md index c4849220a5..868686aa40 100644 --- a/docs/man_pages/general/update.md +++ b/docs/man_pages/general/update.md @@ -1,6 +1,6 @@ <% if (isJekyll) { %>--- title: tns update -position: 15 +position: 16 ---<% } %> # tns update diff --git a/docs/man_pages/general/usage-reporting.md b/docs/man_pages/general/usage-reporting.md index 1b11115748..5edf50dca4 100644 --- a/docs/man_pages/general/usage-reporting.md +++ b/docs/man_pages/general/usage-reporting.md @@ -1,6 +1,6 @@ <% if (isJekyll) { %>--- title: tns usage-reporting -position: 16 +position: 17 ---<% } %> # tns usage-reporting diff --git a/docs/man_pages/index.md b/docs/man_pages/index.md index 542395e2ea..0d86ade439 100644 --- a/docs/man_pages/index.md +++ b/docs/man_pages/index.md @@ -21,6 +21,7 @@ Command | Description [doctor](general/doctor.html) | Checks your system for configuration problems which might prevent the NativeScript CLI from working properly. [info](general/info.html) | Displays version information about the NativeScript CLI, core modules, and runtimes. [proxy](general/proxy.html) | Displays proxy settings. +[migrate](general/migrate.html) | Migrates the app dependencies to a form compatible with NativeScript 6.0. [update](general/update.html) | Updates the project with the latest versions of iOS/Android runtimes and cross-platform modules. ## Project Development Commands From 7c789d12b495a66c87b00ddba74bb4545335c288 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 14:42:12 +0300 Subject: [PATCH 39/69] fix: fix PR comments --- lib/controllers/migrate-controller.ts | 56 +++++++++++++-------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 9c0f18868a..1c5f44b8ff 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -44,32 +44,6 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC { packageName: constants.TNS_CORE_MODULES_WIDGETS_NAME, verifiedVersion: "6.0.0" }, { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.0-rc-2019-07-09-183845-06" }, { packageName: "node-sass", isDev: true, verifiedVersion: "4.12.0" }, - { - packageName: MigrateController.typescriptPackageName, isDev: true, getVerifiedVersion: async (projectData: IProjectData) => { - let verifiedVersion = "3.4.1"; - try { - const ngcPackageName = "@angular/compiler-cli"; - // e.g. ~8.0.0 - let ngcVersion = projectData.dependencies[ngcPackageName] || projectData.devDependencies[ngcPackageName]; - if (ngcVersion) { - // e.g. ~8.0.3 - ngcVersion = await this.$packageInstallationManager.maxSatisfyingVersion(ngcPackageName, ngcVersion); - const ngcManifest = await this.getTemplateManifest(ngcPackageName, ngcVersion); - // e.g. >=3.4 <3.5 - verifiedVersion = (ngcManifest && ngcManifest.peerDependencies && - ngcManifest.peerDependencies[MigrateController.typescriptPackageName]) || verifiedVersion; - - // e.g. 3.4.4 - verifiedVersion = await this.$packageInstallationManager.maxSatisfyingVersion( - MigrateController.typescriptPackageName, verifiedVersion); - } - } catch (error) { - this.$logger.warn(`Unable to determine the TypeScript version based on the Angular packages. Error is: '${error}'.`); - } - - return verifiedVersion; - } - }, { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: MigrateController.typescriptPackageName }, { packageName: "nativescript-dev-less", isDev: true, shouldRemove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, @@ -96,7 +70,8 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC packageName: "nativescript-unit-test-runner", verifiedVersion: "0.6.4", shouldMigrateAction: (projectData: IProjectData) => this.hasDependency({ packageName: "nativescript-unit-test-runner", isDev: false }, projectData), migrateAction: this.migrateUnitTestRunner.bind(this) - } + }, + { packageName: MigrateController.typescriptPackageName, isDev: true, getVerifiedVersion: this.getAngularTypeScriptVersion.bind(this) } ]; get verifiedPlatformVersions(): IDictionary { @@ -175,7 +150,32 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC } } - private async migrateOldAndroidAppResources(projectData: IProjectData) { + private async getAngularTypeScriptVersion(projectData: IProjectData): Promise { + let verifiedVersion = "3.4.1"; + try { + const ngcPackageName = "@angular/compiler-cli"; + // e.g. ~8.0.0 + let ngcVersion = projectData.dependencies[ngcPackageName] || projectData.devDependencies[ngcPackageName]; + if (ngcVersion) { + // e.g. 8.0.3 + ngcVersion = await this.$packageInstallationManager.maxSatisfyingVersion(ngcPackageName, ngcVersion); + const ngcManifest = await this.getTemplateManifest(ngcPackageName, ngcVersion); + // e.g. >=3.4 <3.5 + verifiedVersion = (ngcManifest && ngcManifest.peerDependencies && + ngcManifest.peerDependencies[MigrateController.typescriptPackageName]) || verifiedVersion; + + // e.g. 3.4.4 + verifiedVersion = await this.$packageInstallationManager.maxSatisfyingVersion( + MigrateController.typescriptPackageName, verifiedVersion); + } + } catch (error) { + this.$logger.warn(`Unable to determine the TypeScript version based on the Angular packages. Error is: '${error}'.`); + } + + return verifiedVersion; + } + + private async migrateOldAndroidAppResources(projectData: IProjectData, backupDir: string) { const appResourcesPath = projectData.getAppResourcesDirectoryPath(); if (!this.$androidResourcesMigrationService.hasMigrated(appResourcesPath)) { this.$logger.info("Migrate old Android App_Resources structure."); From 25afbbf50e637afae873f797cdc7162d80568bce Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 14:42:41 +0300 Subject: [PATCH 40/69] fix: fix auto-generated files logs --- lib/controllers/migrate-controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 1c5f44b8ff..8e28e3690c 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -96,9 +96,9 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC } try { - this.$logger.info("Backup auto-generated files."); + this.$logger.info("Clean auto-generated files."); this.handleAutoGeneratedFiles(backupDir, projectData); - this.$logger.info("Backup auto-generated files complete."); + this.$logger.info("Clean auto-generated files complete."); } catch (error) { this.$logger.trace(`Error during auto-generated files handling. ${(error && error.message) || error}`); } From e795a8b8e4041f058448aaee919694291ff62cfb Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 14:43:13 +0300 Subject: [PATCH 41/69] fix: backup the pre-v4 android app_resources in the .migration_backup during `tns migrate` --- lib/controllers/migrate-controller.ts | 4 ++-- lib/declarations.d.ts | 2 +- lib/services/android-resources-migration-service.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 8e28e3690c..b3dd991d73 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -103,7 +103,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC this.$logger.trace(`Error during auto-generated files handling. ${(error && error.message) || error}`); } - await this.migrateOldAndroidAppResources(projectData); + await this.migrateOldAndroidAppResources(projectData, backupDir); try { await this.cleanUpProject(projectData); @@ -180,7 +180,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC if (!this.$androidResourcesMigrationService.hasMigrated(appResourcesPath)) { this.$logger.info("Migrate old Android App_Resources structure."); try { - await this.$androidResourcesMigrationService.migrate(appResourcesPath); + await this.$androidResourcesMigrationService.migrate(appResourcesPath, backupDir); } catch (error) { this.$logger.warn("Migrate old Android App_Resources structure failed: ", error.message); } diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index eed7ccdcf7..b1b2c43a64 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -603,7 +603,7 @@ interface IInfoService { interface IAndroidResourcesMigrationService { canMigrate(platformString: string): boolean; hasMigrated(appResourcesDir: string): boolean; - migrate(appResourcesDir: string): Promise; + migrate(appResourcesDir: string, backupLocation?: string): Promise; } /** diff --git a/lib/services/android-resources-migration-service.ts b/lib/services/android-resources-migration-service.ts index a565bacc22..6167154e53 100644 --- a/lib/services/android-resources-migration-service.ts +++ b/lib/services/android-resources-migration-service.ts @@ -20,10 +20,10 @@ export class AndroidResourcesMigrationService implements IAndroidResourcesMigrat return this.$fs.exists(path.join(appResourcesDir, AndroidResourcesMigrationService.ANDROID_DIR, constants.SRC_DIR, constants.MAIN_DIR)); } - public async migrate(appResourcesDir: string): Promise { + public async migrate(appResourcesDir: string, backupLocation?: string): Promise { const originalAppResources = path.join(appResourcesDir, AndroidResourcesMigrationService.ANDROID_DIR); const appResourcesDestination = path.join(appResourcesDir, AndroidResourcesMigrationService.ANDROID_DIR_TEMP); - const appResourcesBackup = path.join(appResourcesDir, AndroidResourcesMigrationService.ANDROID_DIR_OLD); + const appResourcesBackup = path.join(backupLocation || appResourcesDir, AndroidResourcesMigrationService.ANDROID_DIR_OLD); try { await this.tryMigrate(originalAppResources, appResourcesDestination, appResourcesBackup); From c0d4e479fa313284227d0820ca69ea443ab3954f Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Wed, 10 Jul 2019 15:10:59 +0300 Subject: [PATCH 42/69] fix: reduce the npm calls during migration --- lib/controllers/migrate-controller.ts | 11 ++++++----- lib/controllers/update-controller-base.ts | 6 +++--- lib/controllers/update-controller.ts | 4 ++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index b3dd991d73..b5fe07f463 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -159,7 +159,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC if (ngcVersion) { // e.g. 8.0.3 ngcVersion = await this.$packageInstallationManager.maxSatisfyingVersion(ngcPackageName, ngcVersion); - const ngcManifest = await this.getTemplateManifest(ngcPackageName, ngcVersion); + const ngcManifest = await this.getPackageManifest(ngcPackageName, ngcVersion); // e.g. >=3.4 <3.5 verifiedVersion = (ngcManifest && ngcManifest.peerDependencies && ngcManifest.peerDependencies[MigrateController.typescriptPackageName]) || verifiedVersion; @@ -288,7 +288,6 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC private async migrateDependency(dependency: IMigrationDependency, projectData: IProjectData): Promise { const hasDependency = this.hasDependency(dependency, projectData); - const dependencyVersion = await this.getDependencyVerifiedVersion(dependency, projectData); if (dependency.warning) { this.$logger.warn(dependency.warning); } @@ -309,6 +308,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC return; } + const dependencyVersion = await this.getDependencyVerifiedVersion(dependency, projectData); if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData)) { this.$logger.info(`Updating '${dependency.packageName}' to compatible version '${dependencyVersion}'`); this.$pluginsService.addToPackageJson(dependency.packageName, dependencyVersion, dependency.isDev, projectData.projectDir); @@ -322,10 +322,11 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC } private async getDependencyVerifiedVersion(dependency: IMigrationDependency, projectData: IProjectData): Promise { - const verifiedVersion = dependency.getVerifiedVersion ? - await dependency.getVerifiedVersion(projectData) : dependency.verifiedVersion; + if (!dependency.verifiedVersion && dependency.getVerifiedVersion) { + dependency.verifiedVersion = await dependency.getVerifiedVersion(projectData); + } - return verifiedVersion; + return dependency.verifiedVersion; } private async shouldMigrateDependencyVersion(dependency: IMigrationDependency, projectData: IProjectData): Promise { diff --git a/lib/controllers/update-controller-base.ts b/lib/controllers/update-controller-base.ts index 9f2eb4b3e6..54cbc3ab7e 100644 --- a/lib/controllers/update-controller-base.ts +++ b/lib/controllers/update-controller-base.ts @@ -2,7 +2,7 @@ import * as path from "path"; import * as semver from "semver"; export class UpdateControllerBase { - protected getTemplateManifest: Function; + protected getPackageManifest: Function; constructor(protected $fs: IFileSystem, protected $platformCommandHelper: IPlatformCommandHelper, @@ -10,7 +10,7 @@ export class UpdateControllerBase { protected $packageInstallationManager: IPackageInstallationManager, protected $packageManager: IPackageManager, protected $pacoteService: IPacoteService) { - this.getTemplateManifest = _.memoize(this._getTemplateManifest, (...args) => { + this.getPackageManifest = _.memoize(this._getManifestManifest, (...args) => { return args.join("@"); }); } @@ -73,7 +73,7 @@ export class UpdateControllerBase { return maxDependencyVersion; } - private async _getTemplateManifest(templateName: string, version?: string) { + private async _getManifestManifest(templateName: string, version?: string) { const packageVersion = semver.valid(version) || await this.$packageManager.getTagVersion(templateName, version) || await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); diff --git a/lib/controllers/update-controller.ts b/lib/controllers/update-controller.ts index 341e2cbca5..82b14d64dd 100644 --- a/lib/controllers/update-controller.ts +++ b/lib/controllers/update-controller.ts @@ -59,7 +59,7 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon public async shouldUpdate({ projectDir, version }: { projectDir: string, version?: string }): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); const templateName = this.getTemplateName(projectData); - const templateManifest = await this.getTemplateManifest(templateName, version); + const templateManifest = await this.getPackageManifest(templateName, version); const dependencies = this.getUpdatableDependencies(templateManifest.dependencies); const devDependencies = this.getUpdatableDependencies(templateManifest.devDependencies); @@ -93,7 +93,7 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon private async updateProject(projectData: IProjectData, version: string): Promise { const templateName = this.getTemplateName(projectData); - const templateManifest = await this.getTemplateManifest(templateName, version); + const templateManifest = await this.getPackageManifest(templateName, version); const dependencies = this.getUpdatableDependencies(templateManifest.dependencies); const devDependencies = this.getUpdatableDependencies(templateManifest.devDependencies); From 3e95c78083e915301cdee8fbc0d666af5c18992d Mon Sep 17 00:00:00 2001 From: Dimitar Tachev Date: Wed, 10 Jul 2019 15:30:35 +0300 Subject: [PATCH 43/69] chore: remove forgotten " --- docs/man_pages/general/migrate.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/man_pages/general/migrate.md b/docs/man_pages/general/migrate.md index 949e38725b..c326907cae 100644 --- a/docs/man_pages/general/migrate.md +++ b/docs/man_pages/general/migrate.md @@ -43,7 +43,7 @@ The following dependencies will be updated if needed: * karma-mocha * karma-chai * karma-qunit -* karma" +* karma ### Commands From e082e8ada3603b1f5be680eab76e7afd8c554a5c Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Wed, 10 Jul 2019 15:33:19 +0300 Subject: [PATCH 44/69] chore: remove extra new line in migrate help --- docs/man_pages/general/migrate.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/man_pages/general/migrate.md b/docs/man_pages/general/migrate.md index c326907cae..b33a19f87a 100644 --- a/docs/man_pages/general/migrate.md +++ b/docs/man_pages/general/migrate.md @@ -45,7 +45,6 @@ The following dependencies will be updated if needed: * karma-qunit * karma - ### Commands Usage | Synopsis From d1607c84114966544baa13df0da1620863d8d952 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 10 Jul 2019 09:23:15 +0300 Subject: [PATCH 45/69] feat: show error when the project is not migrated and is not compatible for CLI 6.0 --- lib/commands/build.ts | 8 ++++++-- lib/commands/debug.ts | 5 ++++- lib/commands/migrate.ts | 6 ++++-- lib/commands/prepare.ts | 4 +++- lib/commands/preview.ts | 5 +++-- lib/commands/run.ts | 3 +++ lib/commands/test.ts | 9 +++++++-- lib/controllers/migrate-controller.ts | 24 ++++++++++++++++++++---- lib/controllers/prepare-controller.ts | 3 --- lib/definitions/migrate.d.ts | 1 + 10 files changed, 51 insertions(+), 17 deletions(-) diff --git a/lib/commands/build.ts b/lib/commands/build.ts index c665231967..b7f45f4843 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -63,7 +63,8 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { $buildController: IBuildController, $platformValidationService: IPlatformValidationService, $logger: ILogger, - $buildDataService: IBuildDataService) { + $buildDataService: IBuildDataService, + private $migrateController: IMigrateController) { super($options, $errors, $projectData, $platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); } @@ -72,6 +73,7 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { } public async canExecute(args: string[]): Promise { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); const platform = this.$devicePlatformsConstants.iOS; super.validatePlatform(platform); @@ -99,7 +101,8 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { $platformValidationService: IPlatformValidationService, protected $androidBundleValidatorHelper: IAndroidBundleValidatorHelper, $buildDataService: IBuildDataService, - protected $logger: ILogger) { + protected $logger: ILogger, + private $migrateController: IMigrateController) { super($options, $errors, $projectData, platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); } @@ -116,6 +119,7 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { } public async canExecute(args: string[]): Promise { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); const platform = this.$devicePlatformsConstants.Android; this.$androidBundleValidatorHelper.validateRuntimeVersion(this.$projectData); let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true } }); diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts index f606d9b418..16a3753000 100644 --- a/lib/commands/debug.ts +++ b/lib/commands/debug.ts @@ -16,7 +16,8 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements private $debugDataService: IDebugDataService, private $debugController: IDebugController, private $liveSyncCommandHelper: ILiveSyncCommandHelper, - private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper) { + private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper, + private $migrateController: IMigrateController) { super($options, $platformsDataService, $platformValidationService, $projectData); $cleanupService.setShouldDispose(false); } @@ -52,6 +53,8 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements } public async canExecute(args: string[]): Promise { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); + this.$androidBundleValidatorHelper.validateNoAab(); if (!this.$platformValidationService.isPlatformSupportedForOS(this.platform, this.$projectData)) { diff --git a/lib/commands/migrate.ts b/lib/commands/migrate.ts index e9cdf19cac..d8bb4b6a54 100644 --- a/lib/commands/migrate.ts +++ b/lib/commands/migrate.ts @@ -9,11 +9,13 @@ export class MigrateCommand implements ICommand { } public async execute(args: string[]): Promise { - await this.$migrateController.migrate({projectDir: this.$projectData.projectDir}); + await this.$migrateController.migrate({ projectDir: this.$projectData.projectDir }); } public async canExecute(args: string[]): Promise { - if (!await this.$migrateController.shouldMigrate({ projectDir: this.$projectData.projectDir })) { + const shouldMigrateResult = await this.$migrateController.shouldMigrate({ projectDir: this.$projectData.projectDir }); + + if (!shouldMigrateResult) { this.$errors.failWithoutHelp('Project is compatible with NativeScript "v6.0.0". To get the latest NativesScript packages execute "tns update".'); } diff --git a/lib/commands/prepare.ts b/lib/commands/prepare.ts index 71f6e6fdd3..3b8298d599 100644 --- a/lib/commands/prepare.ts +++ b/lib/commands/prepare.ts @@ -16,7 +16,8 @@ export class PrepareCommand extends ValidatePlatformCommandBase implements IComm $projectData: IProjectData, private $platformCommandParameter: ICommandParameter, $platformsDataService: IPlatformsDataService, - private $prepareDataService: PrepareDataService) { + private $prepareDataService: PrepareDataService, + private $migrateController: IMigrateController) { super($options, $platformsDataService, $platformValidationService, $projectData); this.$projectData.initializeProjectData(); } @@ -29,6 +30,7 @@ export class PrepareCommand extends ValidatePlatformCommandBase implements IComm } public async canExecute(args: string[]): Promise { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); const platform = args[0]; const result = await this.$platformCommandParameter.validate(platform) && await this.$platformValidationService.validateOptions(this.$options.provision, this.$options.teamId, this.$projectData, platform); diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index f891b5fca9..f84de1f516 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -4,9 +4,9 @@ export class PreviewCommand implements ICommand { public allowedParameters: ICommandParameter[] = []; constructor(private $analyticsService: IAnalyticsService, - private $bundleValidatorHelper: IBundleValidatorHelper, private $errors: IErrors, private $logger: ILogger, + private $migrateController: IMigrateController, private $previewAppController: IPreviewAppController, private $networkConnectivityValidator: INetworkConnectivityValidator, private $projectData: IProjectData, @@ -41,8 +41,9 @@ export class PreviewCommand implements ICommand { this.$errors.fail(`The arguments '${args.join(" ")}' are not valid for the preview command.`); } + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); + await this.$networkConnectivityValidator.validate(); - this.$bundleValidatorHelper.validate(this.$projectData, "1.0.0"); return true; } } diff --git a/lib/commands/run.ts b/lib/commands/run.ts index e8fcda7cdc..0a308a2f4a 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -13,6 +13,7 @@ export class RunCommandBase implements ICommand { private $errors: IErrors, private $hostInfo: IHostInfo, private $liveSyncCommandHelper: ILiveSyncCommandHelper, + private $migrateController: IMigrateController, private $projectData: IProjectData ) { } @@ -27,6 +28,8 @@ export class RunCommandBase implements ICommand { this.$errors.fail(ERROR_NO_VALID_SUBCOMMAND_FORMAT, "run"); } + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); + this.$androidBundleValidatorHelper.validateNoAab(); this.$projectData.initializeProjectData(); diff --git a/lib/commands/test.ts b/lib/commands/test.ts index 1641227d28..a7459796ed 100644 --- a/lib/commands/test.ts +++ b/lib/commands/test.ts @@ -10,6 +10,7 @@ abstract class TestCommandBase { protected abstract $cleanupService: ICleanupService; protected abstract $liveSyncCommandHelper: ILiveSyncCommandHelper; protected abstract $devicesService: Mobile.IDevicesService; + protected abstract $migrateController: IMigrateController; async execute(args: string[]): Promise { let devices = []; @@ -48,6 +49,8 @@ abstract class TestCommandBase { } async canExecute(args: string[]): Promise { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); + this.$projectData.initializeProjectData(); this.$analyticsService.setShouldDispose(this.$options.justlaunch || !this.$options.watch); this.$cleanupService.setShouldDispose(this.$options.justlaunch || !this.$options.watch); @@ -86,7 +89,8 @@ class TestAndroidCommand extends TestCommandBase implements ICommand { protected $errors: IErrors, protected $cleanupService: ICleanupService, protected $liveSyncCommandHelper: ILiveSyncCommandHelper, - protected $devicesService: Mobile.IDevicesService) { + protected $devicesService: Mobile.IDevicesService, + protected $migrateController: IMigrateController) { super(); } } @@ -102,7 +106,8 @@ class TestIosCommand extends TestCommandBase implements ICommand { protected $errors: IErrors, protected $cleanupService: ICleanupService, protected $liveSyncCommandHelper: ILiveSyncCommandHelper, - protected $devicesService: Mobile.IDevicesService) { + protected $devicesService: Mobile.IDevicesService, + protected $migrateController: IMigrateController) { super(); } diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index b5fe07f463..0fa6ffe504 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -6,6 +6,10 @@ import { UpdateControllerBase } from "./update-controller-base"; import { fromWindowsRelativePathToUnix } from "../common/helpers"; export class MigrateController extends UpdateControllerBase implements IMigrateController { + // TODO: Improve the messages here + public UNABLE_TO_MIGRATE_APP_ERROR = "The project is not compatible with NativeScript 6.0"; + public MIGRATE_MESSAGE = ""; + constructor( protected $fs: IFileSystem, protected $platformCommandHelper: IPlatformCommandHelper, @@ -71,7 +75,10 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC shouldMigrateAction: (projectData: IProjectData) => this.hasDependency({ packageName: "nativescript-unit-test-runner", isDev: false }, projectData), migrateAction: this.migrateUnitTestRunner.bind(this) }, - { packageName: MigrateController.typescriptPackageName, isDev: true, getVerifiedVersion: this.getAngularTypeScriptVersion.bind(this) } + { packageName: MigrateController.typescriptPackageName, isDev: true, getVerifiedVersion: this.getAngularTypeScriptVersion.bind(this) }, + { packageName: "nativescript-localize", verifiedVersion: "4.2.0" }, + { packageName: "nativescript-dev-babel", verifiedVersion: "0.2.1" }, + { packageName: "nativescript-nfc", verifiedVersion: "4.0.1" } ]; get verifiedPlatformVersions(): IDictionary { @@ -112,6 +119,8 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC this.restoreBackup(MigrateController.folders, backupDir, projectData.projectDir); this.$errors.failWithoutHelp(`${MigrateController.migrateFailMessage} The error is: ${error}`); } + + this.$logger.info(this.MIGRATE_MESSAGE); } public async shouldMigrate({ projectDir }: IProjectDir): Promise { @@ -136,10 +145,10 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC if (!hasDependency && dependency.shouldAddIfMissing) { return true; } + } - if (!this.$androidResourcesMigrationService.hasMigrated(projectData.getAppResourcesDirectoryPath())) { - return true; - } + if (!this.$androidResourcesMigrationService.hasMigrated(projectData.getAppResourcesDirectoryPath())) { + return true; } for (const platform in this.$devicePlatformsConstants) { @@ -150,6 +159,13 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC } } + public async validate({ projectDir }: IProjectDir): Promise { + const shouldMigrate = await this.shouldMigrate({ projectDir }); + if (shouldMigrate) { + this.$errors.failWithoutHelp(this.UNABLE_TO_MIGRATE_APP_ERROR); + } + } + private async getAngularTypeScriptVersion(projectData: IProjectData): Promise { let verifiedVersion = "3.4.1"; try { diff --git a/lib/controllers/prepare-controller.ts b/lib/controllers/prepare-controller.ts index c201b2beef..86c871027d 100644 --- a/lib/controllers/prepare-controller.ts +++ b/lib/controllers/prepare-controller.ts @@ -16,7 +16,6 @@ export class PrepareController extends EventEmitter { private persistedData: IFilesChangeEventData[] = []; constructor( - private $bundleValidatorHelper: IBundleValidatorHelper, private $platformController: IPlatformController, public $hooksService: IHooksService, private $logger: ILogger, @@ -55,8 +54,6 @@ export class PrepareController extends EventEmitter { @performanceLog() @hook("prepare") private async prepareCore(prepareData: IPrepareData, projectData: IProjectData): Promise { - this.$bundleValidatorHelper.validate(projectData, "1.0.0"); - await this.$platformController.addPlatformIfNeeded(prepareData); this.$logger.info("Preparing project..."); diff --git a/lib/definitions/migrate.d.ts b/lib/definitions/migrate.d.ts index e7e434693d..d79f961745 100644 --- a/lib/definitions/migrate.d.ts +++ b/lib/definitions/migrate.d.ts @@ -1,6 +1,7 @@ interface IMigrateController { migrate(migrateData: IProjectDir): Promise; shouldMigrate(data: IProjectDir): Promise; + validate(data: IProjectDir): Promise; } interface IDependency { From 80d2c9ae4c514f3e1e0c480d4670fd8d966f8268 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 10 Jul 2019 09:25:28 +0300 Subject: [PATCH 46/69] chore: remove bundleValidatorHelper --- lib/bootstrap.ts | 1 - lib/helpers/bundle-validator-helper.ts | 40 --------- test/controllers/prepare-controller.ts | 4 - test/helpers/bundle-validator-helper.ts | 107 ------------------------ 4 files changed, 152 deletions(-) delete mode 100644 lib/helpers/bundle-validator-helper.ts delete mode 100644 test/helpers/bundle-validator-helper.ts diff --git a/lib/bootstrap.ts b/lib/bootstrap.ts index c66924ab9f..00cbc57b25 100644 --- a/lib/bootstrap.ts +++ b/lib/bootstrap.ts @@ -144,7 +144,6 @@ $injector.require("devicePathProvider", "./device-path-provider"); $injector.requireCommand("platform|clean", "./commands/platform-clean"); -$injector.require("bundleValidatorHelper", "./helpers/bundle-validator-helper"); $injector.require("androidBundleValidatorHelper", "./helpers/android-bundle-validator-helper"); $injector.require("liveSyncCommandHelper", "./helpers/livesync-command-helper"); $injector.require("deployCommandHelper", "./helpers/deploy-command-helper"); diff --git a/lib/helpers/bundle-validator-helper.ts b/lib/helpers/bundle-validator-helper.ts deleted file mode 100644 index 485424f30a..0000000000 --- a/lib/helpers/bundle-validator-helper.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as util from "util"; -import { BundleValidatorMessages } from "../constants"; -import { VersionValidatorHelper } from "./version-validator-helper"; -import { WEBPACK_PLUGIN_NAME } from "../constants"; - -export class BundleValidatorHelper extends VersionValidatorHelper implements IBundleValidatorHelper { - private bundlersMap: IStringDictionary = { - webpack: WEBPACK_PLUGIN_NAME - }; - - constructor(protected $errors: IErrors, - protected $options: IOptions) { - super(); - } - - public validate(projectData: IProjectData, minSupportedVersion?: string): void { - const currentVersion = this.getBundlerDependencyVersion(projectData); - if (!currentVersion) { - this.$errors.failWithoutHelp(BundleValidatorMessages.MissingBundlePlugin); - } - - const shouldThrowError = minSupportedVersion && this.isValidVersion(currentVersion) && this.isVersionLowerThan(currentVersion, minSupportedVersion); - if (shouldThrowError) { - this.$errors.failWithoutHelp(util.format(BundleValidatorMessages.NotSupportedVersion, minSupportedVersion)); - } - } - - public getBundlerDependencyVersion(projectData: IProjectData, bundlerName?: string): string { - let dependencyVersion = null; - const bundlePluginName = bundlerName || this.bundlersMap[this.$options.bundle]; - const bundlerVersionInDependencies = projectData.dependencies && projectData.dependencies[bundlePluginName]; - const bundlerVersionInDevDependencies = projectData.devDependencies && projectData.devDependencies[bundlePluginName]; - dependencyVersion = bundlerVersionInDependencies || bundlerVersionInDevDependencies; - - return dependencyVersion; - - } -} - -$injector.register("bundleValidatorHelper", BundleValidatorHelper); diff --git a/test/controllers/prepare-controller.ts b/test/controllers/prepare-controller.ts index 78b4af2d43..ef0b4a0fd0 100644 --- a/test/controllers/prepare-controller.ts +++ b/test/controllers/prepare-controller.ts @@ -54,10 +54,6 @@ function createTestInjector(data: { hasNativeChanges: boolean }): IInjector { isFileInIgnoreList: () => false }); - injector.register("bundleValidatorHelper", { - validate: () => ({}) - }); - const prepareController: PrepareController = injector.resolve("prepareController"); prepareController.emit = (eventName: string, eventData: any) => { emittedEventNames.push(eventName); diff --git a/test/helpers/bundle-validator-helper.ts b/test/helpers/bundle-validator-helper.ts deleted file mode 100644 index 3feee9c4c2..0000000000 --- a/test/helpers/bundle-validator-helper.ts +++ /dev/null @@ -1,107 +0,0 @@ -import { Yok } from "../../lib/common/yok"; -import { BundleValidatorHelper } from "../../lib/helpers/bundle-validator-helper"; -import { assert } from "chai"; -import { format } from "util"; -import { BundleValidatorMessages } from "../../lib/constants"; - -interface ITestCase { - name: string; - isDependency?: boolean; - currentWebpackVersion?: string; - minSupportedWebpackVersion?: string; - expectedError?: string; -} - -let error: string = null; - -function createTestInjector(options: { dependencies?: IStringDictionary, devDependencies?: IStringDictionary }) { - const testInjector = new Yok(); - testInjector.register("projectData", { - initializeProjectData: () => ({}), - dependencies: options.dependencies, - devDependencies: options.devDependencies - }); - testInjector.register("errors", { - fail: (err: string) => error = err, - failWithoutHelp: (err: string) => error = err - }); - testInjector.register("options", ({ bundle: "webpack" })); - testInjector.register("bundleValidatorHelper", BundleValidatorHelper); - - return testInjector; -} - -describe("BundleValidatorHelper", () => { - beforeEach(() => error = null); - - let testCases: ITestCase[] = [ - { - name: "should throw an error when no webpack plugin is installed", - expectedError: BundleValidatorMessages.MissingBundlePlugin - } - ]; - - ["dependencies", "devDependencies"] - .forEach(key => { - const isDependency = key === "dependencies"; - - testCases = testCases.concat([ - { - name: `should not throw an error when webpack is added as ${key}`, - isDependency, - currentWebpackVersion: "0.12.0", - expectedError: null - }, - { - name: `should not throw an error when webpack's version is greater than minSupportedVersion when webpack is installed as ${key}`, - isDependency, - currentWebpackVersion: "0.13.1", - minSupportedWebpackVersion: "0.13.0", - expectedError: null - }, - { - name: `should not throw an error when webpack's version is equal to minSupportedVersion when webpack is installed as ${key}`, - isDependency, - currentWebpackVersion: "0.10.0", - minSupportedWebpackVersion: "0.10.0", - expectedError: null - }, - { - name: `should throw an error when webpack's version is lower than minSupportedVersion when webpack is installed as ${key}`, - isDependency, - currentWebpackVersion: "0.17.0", - minSupportedWebpackVersion: "0.18.0", - expectedError: format(BundleValidatorMessages.NotSupportedVersion, "0.18.0") - }, - { - name: `should not throw an error when prerelease version of webpack is installed as ${key}`, - isDependency, - currentWebpackVersion: "0.17.0-2018-09-28-173604-01", - minSupportedWebpackVersion: "0.17.0", - expectedError: null - }, - { - name: `should not throw an error when next version of webpack is installed as ${key}`, - isDependency, - currentWebpackVersion: "next", - minSupportedWebpackVersion: "0.17.0", - expectedError: null - } - ]); - }); - - _.each(testCases, (testCase: any) => { - const deps = { - "nativescript-dev-webpack": testCase.currentWebpackVersion - }; - - it(`${testCase.name}`, async () => { - const injector = createTestInjector({ dependencies: testCase.isDependency ? deps : null, devDependencies: !testCase.isDependency ? deps : null }); - const bundleValidatorHelper = injector.resolve("bundleValidatorHelper"); - const projectData = injector.resolve("projectData"); - bundleValidatorHelper.validate(projectData, testCase.minSupportedWebpackVersion); - - assert.deepEqual(error, testCase.expectedError); - }); - }); -}); From 40e5bc3624611579f61696b0cd4868373c71d208 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 10 Jul 2019 14:07:35 +0300 Subject: [PATCH 47/69] fix: add karma-webpack only when it is missing from project --- lib/controllers/migrate-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 0fa6ffe504..05c3bcbc73 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -383,7 +383,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC // Dependencies to migrate const dependencies = [ - { packageName: "karma-webpack", verifiedVersion: "3.0.5", isDev: true, shouldAddIfMissing: true }, + { packageName: "karma-webpack", verifiedVersion: "3.0.5", isDev: true, shouldAddIfMissing: !this.hasDependency({ packageName: "karma-webpack", isDev: true }, projectData) }, { packageName: "karma-jasmine", verifiedVersion: "2.0.1", isDev: true }, { packageName: "karma-mocha", verifiedVersion: "1.3.0", isDev: true }, { packageName: "karma-chai", verifiedVersion: "0.1.0", isDev: true }, From b7fb5e4820f7f1154586fc2083094d6022bfe1ea Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 10 Jul 2019 14:30:09 +0300 Subject: [PATCH 48/69] fix: update the error message shown when the app is not migrated and the message shown at the end of migrate command --- lib/controllers/migrate-controller.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 05c3bcbc73..e200837902 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -6,9 +6,12 @@ import { UpdateControllerBase } from "./update-controller-base"; import { fromWindowsRelativePathToUnix } from "../common/helpers"; export class MigrateController extends UpdateControllerBase implements IMigrateController { - // TODO: Improve the messages here - public UNABLE_TO_MIGRATE_APP_ERROR = "The project is not compatible with NativeScript 6.0"; - public MIGRATE_MESSAGE = ""; + // TODO: Update the links to blog post when it is available + private static UNABLE_TO_MIGRATE_APP_ERROR = `The current application is not compatible with NativeScript CLI 6.0. +Use the \`tns migrate\` command to migrate the app dependencies to a form compatible with NativeScript 6.0. +Running this command will not affect the codebase of the application and you might need to do additional changes manually – +for more information, refer to the instructions in the following blog post: .`; + private static MIGRATE_FINISH_MESSAGE = "The `tns migrate` command does not affect the codebase of the application and you might need to do additional changes manually – for more information, refer to the instructions in the following blog post: ."; constructor( protected $fs: IFileSystem, @@ -120,7 +123,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC this.$errors.failWithoutHelp(`${MigrateController.migrateFailMessage} The error is: ${error}`); } - this.$logger.info(this.MIGRATE_MESSAGE); + this.$logger.info(MigrateController.MIGRATE_FINISH_MESSAGE); } public async shouldMigrate({ projectDir }: IProjectDir): Promise { @@ -162,7 +165,7 @@ export class MigrateController extends UpdateControllerBase implements IMigrateC public async validate({ projectDir }: IProjectDir): Promise { const shouldMigrate = await this.shouldMigrate({ projectDir }); if (shouldMigrate) { - this.$errors.failWithoutHelp(this.UNABLE_TO_MIGRATE_APP_ERROR); + this.$errors.failWithoutHelp(MigrateController.UNABLE_TO_MIGRATE_APP_ERROR); } } From 979321d6d7c3c4b3f258a9c3f59c0d4732bd6fc2 Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 10 Jul 2019 15:53:38 +0300 Subject: [PATCH 49/69] fix: check the version of nativescript-unit-test-runner from shouldMigrate action Currently the version of nativescript-unit-test-runner is not checked on shouldMigrate action and this led to the behavior that shouldMigrate returns true for all projects that have `nativescript-unit-test-runner` as dependency. --- lib/controllers/migrate-controller.ts | 10 +++++++--- lib/definitions/migrate.d.ts | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index e200837902..ef73161071 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -75,7 +75,11 @@ for more information, refer to the instructions in the following blog post: this.hasDependency({ packageName: "nativescript-unit-test-runner", isDev: false }, projectData), + shouldMigrateAction: async (projectData: IProjectData) => { + const dependency = { packageName: "nativescript-unit-test-runner", verifiedVersion: "0.6.4", isDev: false }; + const result = this.hasDependency(dependency, projectData) && await this.shouldMigrateDependencyVersion(dependency, projectData); + return result; + }, migrateAction: this.migrateUnitTestRunner.bind(this) }, { packageName: MigrateController.typescriptPackageName, isDev: true, getVerifiedVersion: this.getAngularTypeScriptVersion.bind(this) }, @@ -133,7 +137,7 @@ for more information, refer to the instructions in the following blog post: Promise; shouldAddIfMissing?: boolean; - shouldMigrateAction?: (projectData: IProjectData) => boolean; + shouldMigrateAction?: (projectData: IProjectData) => Promise; migrateAction?: (projectData: IProjectData, migrationBackupDirPath: string) => Promise; } \ No newline at end of file From fab55aa61496d618d09d5cf995364231e2d97dfd Mon Sep 17 00:00:00 2001 From: fatme Date: Wed, 10 Jul 2019 15:55:30 +0300 Subject: [PATCH 50/69] fix: check runtimeVersion only when the project has runtime property in package.json (tns-android or tns-ios) --- lib/controllers/migrate-controller.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index ef73161071..ba6f580b4d 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -160,7 +160,7 @@ for more information, refer to the instructions in the following blog post: Date: Wed, 10 Jul 2019 17:06:52 +0300 Subject: [PATCH 51/69] fix: fix PR comments --- lib/controllers/migrate-controller.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index ba6f580b4d..621506ca6f 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -7,11 +7,11 @@ import { fromWindowsRelativePathToUnix } from "../common/helpers"; export class MigrateController extends UpdateControllerBase implements IMigrateController { // TODO: Update the links to blog post when it is available + private static COMMON_MIGRATE_MESSAGE = "not affect the codebase of the application and you might need to do additional changes manually – for more information, refer to the instructions in the following blog post: ."; private static UNABLE_TO_MIGRATE_APP_ERROR = `The current application is not compatible with NativeScript CLI 6.0. Use the \`tns migrate\` command to migrate the app dependencies to a form compatible with NativeScript 6.0. -Running this command will not affect the codebase of the application and you might need to do additional changes manually – -for more information, refer to the instructions in the following blog post: .`; - private static MIGRATE_FINISH_MESSAGE = "The `tns migrate` command does not affect the codebase of the application and you might need to do additional changes manually – for more information, refer to the instructions in the following blog post: ."; +Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; + private static MIGRATE_FINISH_MESSAGE = `The \`tns migrate\` command does ${MigrateController.COMMON_MIGRATE_MESSAGE}`; constructor( protected $fs: IFileSystem, @@ -390,7 +390,7 @@ for more information, refer to the instructions in the following blog post: Date: Wed, 10 Jul 2019 17:39:13 +0300 Subject: [PATCH 52/69] fix: show warning for less only when the project has nativescript-dev-less plugin as dependency --- lib/controllers/migrate-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 621506ca6f..129e4c172f 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -311,7 +311,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; private async migrateDependency(dependency: IMigrationDependency, projectData: IProjectData): Promise { const hasDependency = this.hasDependency(dependency, projectData); - if (dependency.warning) { + if (hasDependency && dependency.warning) { this.$logger.warn(dependency.warning); } From f1b58ba9c0cf367057921183768aae6b495c4193 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 11 Jul 2019 09:35:20 +0300 Subject: [PATCH 53/69] fix: do not require migration when file references or tags are used as dependencies --- lib/controllers/migrate-controller.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 129e4c172f..9ef8eef199 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -356,11 +356,11 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; const devDependencies = projectData.devDependencies || {}; const dependencies = projectData.dependencies || {}; const packageName = dependency.packageName; - const version = dependencies[packageName] || devDependencies[packageName]; - const maxSatisfyingVersion = await this.getMaxDependencyVersion(dependency.packageName, version); - const dependencyVersion = await this.getDependencyVerifiedVersion(dependency, projectData); + const referencedVersion = dependencies[packageName] || devDependencies[packageName]; + const installedVersion = await this.getMaxDependencyVersion(dependency.packageName, referencedVersion); + const requiredVersion = await this.getDependencyVerifiedVersion(dependency, projectData); - return !(maxSatisfyingVersion && semver.gte(maxSatisfyingVersion, dependencyVersion)); + return !!installedVersion && semver.lt(installedVersion, requiredVersion); } protected async shouldUpdateRuntimeVersion({ targetVersion, platform, projectData }: { targetVersion: string, platform: string, projectData: IProjectData }): Promise { From 72b9e583a8d9406439b9bd338a48dd375916a98c Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 11 Jul 2019 09:36:15 +0300 Subject: [PATCH 54/69] fix: do not require migration when only the App_Resources are using the pre 4.0 structure --- lib/controllers/migrate-controller.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 9ef8eef199..044ef18eac 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -154,10 +154,6 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; } } - if (!this.$androidResourcesMigrationService.hasMigrated(projectData.getAppResourcesDirectoryPath())) { - return true; - } - for (const platform in this.$devicePlatformsConstants) { const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion({ targetVersion: this.verifiedPlatformVersions[platform.toLowerCase()], platform, projectData })) { From 94c63aea30b1f1d2cefd60f77b8bbbb6cd10039c Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 11 Jul 2019 09:48:10 +0300 Subject: [PATCH 55/69] fix: add trace logs for the shouldMigrate reason. --- lib/controllers/migrate-controller.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 044ef18eac..0fecf2cb29 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -132,24 +132,29 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; public async shouldMigrate({ projectDir }: IProjectDir): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); + const shouldMigrateCommonMessage = "The app is not compatible with this CLI version and it should be migrated. Reason: "; for (let i = 0; i < this.migrationDependencies.length; i++) { const dependency = this.migrationDependencies[i]; const hasDependency = this.hasDependency(dependency, projectData); if (hasDependency && dependency.shouldMigrateAction && await dependency.shouldMigrateAction(projectData)) { + this.$logger.trace(`${shouldMigrateCommonMessage}'${dependency.packageName}' requires an update.`); return true; } if (hasDependency && (dependency.replaceWith || dependency.shouldRemove)) { + this.$logger.trace(`${shouldMigrateCommonMessage}'${dependency.packageName}' is deprecated.`); return true; } if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData)) { + this.$logger.trace(`${shouldMigrateCommonMessage}'${dependency.packageName}' should be updated.`); return true; } if (!hasDependency && dependency.shouldAddIfMissing) { + this.$logger.trace(`${shouldMigrateCommonMessage}'${dependency.packageName}' is missing.`); return true; } } @@ -157,6 +162,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; for (const platform in this.$devicePlatformsConstants) { const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion({ targetVersion: this.verifiedPlatformVersions[platform.toLowerCase()], platform, projectData })) { + this.$logger.trace(`${shouldMigrateCommonMessage}Platform '${platform}' should be updated.`); return true; } } From 335828040435ada932d817963d951484dc4d1aab Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 11 Jul 2019 10:08:33 +0300 Subject: [PATCH 56/69] fix: validate the migration per platform --- lib/commands/build.ts | 12 ++++++------ lib/commands/debug.ts | 2 +- lib/commands/migrate.ts | 11 +++++++++-- lib/commands/prepare.ts | 6 +++--- lib/commands/preview.ts | 2 +- lib/commands/run.ts | 10 ++++------ lib/commands/test.ts | 4 ++-- lib/commands/update.ts | 12 +++++++++--- lib/controllers/migrate-controller.ts | 18 ++++++++++-------- lib/definitions/migrate.d.ts | 10 +++++++--- test/update.ts | 2 ++ 11 files changed, 54 insertions(+), 35 deletions(-) diff --git a/lib/commands/build.ts b/lib/commands/build.ts index b7f45f4843..912753e508 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -11,8 +11,8 @@ export abstract class BuildCommandBase extends ValidatePlatformCommandBase { $platformValidationService: IPlatformValidationService, private $buildDataService: IBuildDataService, protected $logger: ILogger) { - super($options, $platformsDataService, $platformValidationService, $projectData); - this.$projectData.initializeProjectData(); + super($options, $platformsDataService, $platformValidationService, $projectData); + this.$projectData.initializeProjectData(); } public dashedOptions = { @@ -65,7 +65,7 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { $logger: ILogger, $buildDataService: IBuildDataService, private $migrateController: IMigrateController) { - super($options, $errors, $projectData, $platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); + super($options, $errors, $projectData, $platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); } public async execute(args: string[]): Promise { @@ -73,8 +73,8 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { } public async canExecute(args: string[]): Promise { - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); const platform = this.$devicePlatformsConstants.iOS; + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); super.validatePlatform(platform); @@ -103,7 +103,7 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { $buildDataService: IBuildDataService, protected $logger: ILogger, private $migrateController: IMigrateController) { - super($options, $errors, $projectData, platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); + super($options, $errors, $projectData, platformsDataService, $devicePlatformsConstants, $buildController, $platformValidationService, $buildDataService, $logger); } public async execute(args: string[]): Promise { @@ -119,8 +119,8 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { } public async canExecute(args: string[]): Promise { - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); const platform = this.$devicePlatformsConstants.Android; + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); this.$androidBundleValidatorHelper.validateRuntimeVersion(this.$projectData); let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true } }); if (result.canExecute) { diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts index 16a3753000..a9ca28acb0 100644 --- a/lib/commands/debug.ts +++ b/lib/commands/debug.ts @@ -53,7 +53,7 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements } public async canExecute(args: string[]): Promise { - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [this.platform] }); this.$androidBundleValidatorHelper.validateNoAab(); diff --git a/lib/commands/migrate.ts b/lib/commands/migrate.ts index d8bb4b6a54..e40cfd8651 100644 --- a/lib/commands/migrate.ts +++ b/lib/commands/migrate.ts @@ -2,6 +2,7 @@ export class MigrateCommand implements ICommand { public allowedParameters: ICommandParameter[] = []; constructor( + private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, private $migrateController: IMigrateController, private $projectData: IProjectData, private $errors: IErrors) { @@ -9,11 +10,17 @@ export class MigrateCommand implements ICommand { } public async execute(args: string[]): Promise { - await this.$migrateController.migrate({ projectDir: this.$projectData.projectDir }); + await this.$migrateController.migrate({ + projectDir: this.$projectData.projectDir, + platforms: [this.$devicePlatformsConstants.Android, this.$devicePlatformsConstants.iOS] + }); } public async canExecute(args: string[]): Promise { - const shouldMigrateResult = await this.$migrateController.shouldMigrate({ projectDir: this.$projectData.projectDir }); + const shouldMigrateResult = await this.$migrateController.shouldMigrate({ + projectDir: this.$projectData.projectDir, + platforms: [this.$devicePlatformsConstants.Android, this.$devicePlatformsConstants.iOS] + }); if (!shouldMigrateResult) { this.$errors.failWithoutHelp('Project is compatible with NativeScript "v6.0.0". To get the latest NativesScript packages execute "tns update".'); diff --git a/lib/commands/prepare.ts b/lib/commands/prepare.ts index 3b8298d599..5faef3e149 100644 --- a/lib/commands/prepare.ts +++ b/lib/commands/prepare.ts @@ -18,8 +18,8 @@ export class PrepareCommand extends ValidatePlatformCommandBase implements IComm $platformsDataService: IPlatformsDataService, private $prepareDataService: PrepareDataService, private $migrateController: IMigrateController) { - super($options, $platformsDataService, $platformValidationService, $projectData); - this.$projectData.initializeProjectData(); + super($options, $platformsDataService, $platformValidationService, $projectData); + this.$projectData.initializeProjectData(); } public async execute(args: string[]): Promise { @@ -30,10 +30,10 @@ export class PrepareCommand extends ValidatePlatformCommandBase implements IComm } public async canExecute(args: string[]): Promise { - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); const platform = args[0]; const result = await this.$platformCommandParameter.validate(platform) && await this.$platformValidationService.validateOptions(this.$options.provision, this.$options.teamId, this.$projectData, platform); + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); if (!result) { return false; } diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index f84de1f516..8f847fe5eb 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -41,7 +41,7 @@ export class PreviewCommand implements ICommand { this.$errors.fail(`The arguments '${args.join(" ")}' are not valid for the preview command.`); } - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [] }); await this.$networkConnectivityValidator.validate(); return true; diff --git a/lib/commands/run.ts b/lib/commands/run.ts index 0a308a2f4a..f5e3ef9861 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -28,17 +28,15 @@ export class RunCommandBase implements ICommand { this.$errors.fail(ERROR_NO_VALID_SUBCOMMAND_FORMAT, "run"); } - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); - - this.$androidBundleValidatorHelper.validateNoAab(); - - this.$projectData.initializeProjectData(); this.platform = args[0] || this.platform; - if (!this.platform && !this.$hostInfo.isDarwin) { this.platform = this.$devicePlatformsConstants.Android; } + this.$androidBundleValidatorHelper.validateNoAab(); + this.$projectData.initializeProjectData(); + const platforms = this.platform ? [this.platform] : [this.$devicePlatformsConstants.Android, this.$devicePlatformsConstants.iOS]; + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms }); await this.$liveSyncCommandHelper.validatePlatform(this.platform); return true; diff --git a/lib/commands/test.ts b/lib/commands/test.ts index a7459796ed..8f12bea759 100644 --- a/lib/commands/test.ts +++ b/lib/commands/test.ts @@ -35,7 +35,7 @@ abstract class TestCommandBase { devices = await this.$liveSyncCommandHelper.getDeviceInstances(this.platform); } - if (!this.$options.env) { this.$options.env = { }; } + if (!this.$options.env) { this.$options.env = {}; } this.$options.env.unitTesting = true; const liveSyncInfo = this.$liveSyncCommandHelper.getLiveSyncData(this.$projectData.projectDir); @@ -49,7 +49,7 @@ abstract class TestCommandBase { } async canExecute(args: string[]): Promise { - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir }); + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [this.platform] }); this.$projectData.initializeProjectData(); this.$analyticsService.setShouldDispose(this.$options.justlaunch || !this.$options.watch); diff --git a/lib/commands/update.ts b/lib/commands/update.ts index 1a1c7f712e..0dddf6a07f 100644 --- a/lib/commands/update.ts +++ b/lib/commands/update.ts @@ -4,6 +4,7 @@ export class UpdateCommand implements ICommand { public static readonly PROJECT_UP_TO_DATE_MESSAGE = 'This project is up to date.'; constructor( + private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, private $updateController: IUpdateController, private $migrateController: IMigrateController, private $options: IOptions, @@ -13,15 +14,20 @@ export class UpdateCommand implements ICommand { } public async execute(args: string[]): Promise { - await this.$updateController.update({projectDir: this.$projectData.projectDir, version: args[0], frameworkPath: this.$options.frameworkPath}); + await this.$updateController.update({ projectDir: this.$projectData.projectDir, version: args[0], frameworkPath: this.$options.frameworkPath }); } public async canExecute(args: string[]): Promise { - if (await this.$migrateController.shouldMigrate({projectDir: this.$projectData.projectDir})) { + const shouldMigrate = await this.$migrateController.shouldMigrate({ + projectDir: this.$projectData.projectDir, + platforms: [this.$devicePlatformsConstants.Android, this.$devicePlatformsConstants.iOS] + }); + + if (shouldMigrate) { this.$errors.failWithoutHelp(UpdateCommand.SHOULD_MIGRATE_PROJECT_MESSAGE); } - if (!await this.$updateController.shouldUpdate({projectDir:this.$projectData.projectDir, version: args[0]})) { + if (!await this.$updateController.shouldUpdate({ projectDir: this.$projectData.projectDir, version: args[0] })) { this.$errors.failWithoutHelp(UpdateCommand.PROJECT_UP_TO_DATE_MESSAGE); } diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 0fecf2cb29..c14e905edf 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -95,7 +95,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; }; } - public async migrate({ projectDir }: { projectDir: string }): Promise { + public async migrate({ projectDir, platforms }: IMigrationData): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); const backupDir = path.join(projectDir, MigrateController.backupFolder); @@ -121,7 +121,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; try { await this.cleanUpProject(projectData); - await this.migrateDependencies(projectData); + await this.migrateDependencies(projectData, platforms); } catch (error) { this.restoreBackup(MigrateController.folders, backupDir, projectData.projectDir); this.$errors.failWithoutHelp(`${MigrateController.migrateFailMessage} The error is: ${error}`); @@ -130,7 +130,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; this.$logger.info(MigrateController.MIGRATE_FINISH_MESSAGE); } - public async shouldMigrate({ projectDir }: IProjectDir): Promise { + public async shouldMigrate({ projectDir, platforms }: IMigrationData): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); const shouldMigrateCommonMessage = "The app is not compatible with this CLI version and it should be migrated. Reason: "; @@ -159,7 +159,9 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; } } - for (const platform in this.$devicePlatformsConstants) { + for (let platform of platforms) { + platform = platform && platform.toLowerCase(); + const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion({ targetVersion: this.verifiedPlatformVersions[platform.toLowerCase()], platform, projectData })) { this.$logger.trace(`${shouldMigrateCommonMessage}Platform '${platform}' should be updated.`); @@ -168,8 +170,8 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; } } - public async validate({ projectDir }: IProjectDir): Promise { - const shouldMigrate = await this.shouldMigrate({ projectDir }); + public async validate({ projectDir, platforms }: IMigrationData): Promise { + const shouldMigrate = await this.shouldMigrate({ projectDir, platforms }); if (shouldMigrate) { this.$errors.failWithoutHelp(MigrateController.UNABLE_TO_MIGRATE_APP_ERROR); } @@ -273,7 +275,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; return autoGeneratedFiles; } - private async migrateDependencies(projectData: IProjectData): Promise { + private async migrateDependencies(projectData: IProjectData, platforms: string[]): Promise { this.$logger.info("Start dependencies migration."); for (let i = 0; i < this.migrationDependencies.length; i++) { const dependency = this.migrationDependencies[i]; @@ -289,7 +291,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; await this.migrateDependency(dependency, projectData); } - for (const platform in this.$devicePlatformsConstants) { + for (const platform of platforms) { const lowercasePlatform = platform.toLowerCase(); const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion({ targetVersion: this.verifiedPlatformVersions[lowercasePlatform], platform, projectData })) { diff --git a/lib/definitions/migrate.d.ts b/lib/definitions/migrate.d.ts index 2db417be92..47a182c540 100644 --- a/lib/definitions/migrate.d.ts +++ b/lib/definitions/migrate.d.ts @@ -1,7 +1,11 @@ interface IMigrateController { - migrate(migrateData: IProjectDir): Promise; - shouldMigrate(data: IProjectDir): Promise; - validate(data: IProjectDir): Promise; + migrate(data: IMigrationData): Promise; + shouldMigrate(data: IMigrationData): Promise; + validate(data: IMigrationData): Promise; +} + +interface IMigrationData extends IProjectDir { + platforms: string[]; } interface IDependency { diff --git a/test/update.ts b/test/update.ts index e1795b2435..8ab22c7802 100644 --- a/test/update.ts +++ b/test/update.ts @@ -5,6 +5,7 @@ import { assert } from "chai"; import { Options } from "../lib/options"; import { StaticConfig } from "../lib/config"; import { SettingsService } from "../lib/common/test/unit-tests/stubs"; +import { DevicePlatformsConstants } from "../lib/common/mobile/device-platforms-constants"; const projectFolder = "test"; function createTestInjector( @@ -26,6 +27,7 @@ function createTestInjector( dependencies: {} }); testInjector.register("settingsService", SettingsService); + testInjector.register("devicePlatformsConstants", DevicePlatformsConstants); testInjector.register("migrateController", { shouldMigrate: () => { return false; }, }); From 54b093fd6ad79c3e6f475f67a161d04306b12b55 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 11 Jul 2019 11:00:48 +0300 Subject: [PATCH 57/69] fix: do not allow invalid version during `tns migrate` --- lib/controllers/migrate-controller.ts | 48 +++++++++++++++------------ lib/definitions/migrate.d.ts | 3 +- 2 files changed, 28 insertions(+), 23 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index c14e905edf..fbdb6dd417 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -75,9 +75,9 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; { packageName: "nativescript-cardview", verifiedVersion: "3.2.0" }, { packageName: "nativescript-unit-test-runner", verifiedVersion: "0.6.4", - shouldMigrateAction: async (projectData: IProjectData) => { + shouldMigrateAction: async (projectData: IProjectData, allowInvalidVersions: boolean) => { const dependency = { packageName: "nativescript-unit-test-runner", verifiedVersion: "0.6.4", isDev: false }; - const result = this.hasDependency(dependency, projectData) && await this.shouldMigrateDependencyVersion(dependency, projectData); + const result = this.hasDependency(dependency, projectData) && await this.shouldMigrateDependencyVersion(dependency, projectData, allowInvalidVersions); return result; }, migrateAction: this.migrateUnitTestRunner.bind(this) @@ -95,7 +95,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; }; } - public async migrate({ projectDir, platforms }: IMigrationData): Promise { + public async migrate({ projectDir, platforms, allowInvalidVersions = false }: IMigrationData): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); const backupDir = path.join(projectDir, MigrateController.backupFolder); @@ -121,7 +121,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; try { await this.cleanUpProject(projectData); - await this.migrateDependencies(projectData, platforms); + await this.migrateDependencies(projectData, platforms, allowInvalidVersions); } catch (error) { this.restoreBackup(MigrateController.folders, backupDir, projectData.projectDir); this.$errors.failWithoutHelp(`${MigrateController.migrateFailMessage} The error is: ${error}`); @@ -130,7 +130,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; this.$logger.info(MigrateController.MIGRATE_FINISH_MESSAGE); } - public async shouldMigrate({ projectDir, platforms }: IMigrationData): Promise { + public async shouldMigrate({ projectDir, platforms, allowInvalidVersions = false }: IMigrationData): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); const shouldMigrateCommonMessage = "The app is not compatible with this CLI version and it should be migrated. Reason: "; @@ -138,7 +138,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; const dependency = this.migrationDependencies[i]; const hasDependency = this.hasDependency(dependency, projectData); - if (hasDependency && dependency.shouldMigrateAction && await dependency.shouldMigrateAction(projectData)) { + if (hasDependency && dependency.shouldMigrateAction && await dependency.shouldMigrateAction(projectData, allowInvalidVersions)) { this.$logger.trace(`${shouldMigrateCommonMessage}'${dependency.packageName}' requires an update.`); return true; } @@ -148,7 +148,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; return true; } - if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData)) { + if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData, allowInvalidVersions)) { this.$logger.trace(`${shouldMigrateCommonMessage}'${dependency.packageName}' should be updated.`); return true; } @@ -163,15 +163,15 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; platform = platform && platform.toLowerCase(); const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); - if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion({ targetVersion: this.verifiedPlatformVersions[platform.toLowerCase()], platform, projectData })) { + if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion(this.verifiedPlatformVersions[platform.toLowerCase()], platform, projectData, allowInvalidVersions)) { this.$logger.trace(`${shouldMigrateCommonMessage}Platform '${platform}' should be updated.`); return true; } } } - public async validate({ projectDir, platforms }: IMigrationData): Promise { - const shouldMigrate = await this.shouldMigrate({ projectDir, platforms }); + public async validate({ projectDir, platforms, allowInvalidVersions = true }: IMigrationData): Promise { + const shouldMigrate = await this.shouldMigrate({ projectDir, platforms, allowInvalidVersions }); if (shouldMigrate) { this.$errors.failWithoutHelp(MigrateController.UNABLE_TO_MIGRATE_APP_ERROR); } @@ -275,26 +275,26 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; return autoGeneratedFiles; } - private async migrateDependencies(projectData: IProjectData, platforms: string[]): Promise { + private async migrateDependencies(projectData: IProjectData, platforms: string[], allowInvalidVersions: boolean): Promise { this.$logger.info("Start dependencies migration."); for (let i = 0; i < this.migrationDependencies.length; i++) { const dependency = this.migrationDependencies[i]; const hasDependency = this.hasDependency(dependency, projectData); - if (hasDependency && dependency.migrateAction && await dependency.shouldMigrateAction(projectData)) { + if (hasDependency && dependency.migrateAction && await dependency.shouldMigrateAction(projectData, allowInvalidVersions)) { const newDependencies = await dependency.migrateAction(projectData, path.join(projectData.projectDir, MigrateController.backupFolder)); for (const newDependency of newDependencies) { - await this.migrateDependency(newDependency, projectData); + await this.migrateDependency(newDependency, projectData, allowInvalidVersions); } } - await this.migrateDependency(dependency, projectData); + await this.migrateDependency(dependency, projectData, allowInvalidVersions); } for (const platform of platforms) { const lowercasePlatform = platform.toLowerCase(); const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); - if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion({ targetVersion: this.verifiedPlatformVersions[lowercasePlatform], platform, projectData })) { + if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion(this.verifiedPlatformVersions[lowercasePlatform], platform, projectData, allowInvalidVersions)) { const verifiedPlatformVersion = this.verifiedPlatformVersions[lowercasePlatform]; const platformData = this.$platformsDataService.getPlatformData(lowercasePlatform, projectData); this.$logger.info(`Updating ${platform} platform to version '${verifiedPlatformVersion}'.`); @@ -313,7 +313,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; this.$logger.info("Migration complete."); } - private async migrateDependency(dependency: IMigrationDependency, projectData: IProjectData): Promise { + private async migrateDependency(dependency: IMigrationDependency, projectData: IProjectData, allowInvalidVersions: boolean): Promise { const hasDependency = this.hasDependency(dependency, projectData); if (hasDependency && dependency.warning) { this.$logger.warn(dependency.warning); @@ -336,7 +336,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; } const dependencyVersion = await this.getDependencyVerifiedVersion(dependency, projectData); - if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData)) { + if (hasDependency && await this.shouldMigrateDependencyVersion(dependency, projectData, allowInvalidVersions)) { this.$logger.info(`Updating '${dependency.packageName}' to compatible version '${dependencyVersion}'`); this.$pluginsService.addToPackageJson(dependency.packageName, dependencyVersion, dependency.isDev, projectData.projectDir); return; @@ -356,7 +356,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; return dependency.verifiedVersion; } - private async shouldMigrateDependencyVersion(dependency: IMigrationDependency, projectData: IProjectData): Promise { + private async shouldMigrateDependencyVersion(dependency: IMigrationDependency, projectData: IProjectData, allowInvalidVersions: boolean): Promise { const devDependencies = projectData.devDependencies || {}; const dependencies = projectData.dependencies || {}; const packageName = dependency.packageName; @@ -364,13 +364,17 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; const installedVersion = await this.getMaxDependencyVersion(dependency.packageName, referencedVersion); const requiredVersion = await this.getDependencyVerifiedVersion(dependency, projectData); - return !!installedVersion && semver.lt(installedVersion, requiredVersion); + return this.isOutdatedVersion(installedVersion, requiredVersion, allowInvalidVersions); } - protected async shouldUpdateRuntimeVersion({ targetVersion, platform, projectData }: { targetVersion: string, platform: string, projectData: IProjectData }): Promise { - const maxRuntimeVersion = await this.getMaxRuntimeVersion({ platform, projectData }); + private async shouldUpdateRuntimeVersion(targetVersion: string, platform: string, projectData: IProjectData, allowInvalidVersions: boolean): Promise { + const installedVersion = await this.getMaxRuntimeVersion({ platform, projectData }); - return !(maxRuntimeVersion && semver.gte(maxRuntimeVersion, targetVersion)); + return this.isOutdatedVersion(installedVersion, targetVersion, allowInvalidVersions); + } + + private isOutdatedVersion(version: string, targetVersion: string, allowInvalidVersions: boolean): boolean { + return !!version ? semver.lt(version, targetVersion) : !allowInvalidVersions; } private async migrateUnitTestRunner(projectData: IProjectData, migrationBackupDirPath: string): Promise { diff --git a/lib/definitions/migrate.d.ts b/lib/definitions/migrate.d.ts index 47a182c540..1931d4fc88 100644 --- a/lib/definitions/migrate.d.ts +++ b/lib/definitions/migrate.d.ts @@ -6,6 +6,7 @@ interface IMigrateController { interface IMigrationData extends IProjectDir { platforms: string[]; + allowInvalidVersions?: boolean; } interface IDependency { @@ -20,6 +21,6 @@ interface IMigrationDependency extends IDependency { verifiedVersion?: string; getVerifiedVersion?: (projectData: IProjectData) => Promise; shouldAddIfMissing?: boolean; - shouldMigrateAction?: (projectData: IProjectData) => Promise; + shouldMigrateAction?: (projectData: IProjectData, allowInvalidVersions: boolean) => Promise; migrateAction?: (projectData: IProjectData, migrationBackupDirPath: string) => Promise; } \ No newline at end of file From ea61a765b918baefbdb63e56e62348e5b0624191 Mon Sep 17 00:00:00 2001 From: fatme Date: Thu, 11 Jul 2019 11:56:13 +0300 Subject: [PATCH 58/69] fix: don't build every time the application from sidekick when using cloud build Currently the application is built every time from sidekick when opening the app and starting cloud build. This happens as we decided that there are changes in app_resources as `prepareData.release` is undefined but `prepareInfo.release` is false. This way the check `prepareData.release !== this._prepareInfo.release` passes and we set `this._changesInfo.appResourcesChanged` to `true`. --- lib/services/project-changes-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/project-changes-service.ts b/lib/services/project-changes-service.ts index a82a9a009c..55ce723b97 100644 --- a/lib/services/project-changes-service.ts +++ b/lib/services/project-changes-service.ts @@ -91,7 +91,7 @@ export class ProjectChangesService implements IProjectChangesService { await platformData.platformProjectService.checkForChanges(this._changesInfo, prepareData, projectData); } - if (prepareData.release !== this._prepareInfo.release) { + if (!!prepareData.release !== !!this._prepareInfo.release) { this.$logger.trace(`Setting all setting to true. Current options are: `, prepareData, " old prepare info is: ", this._prepareInfo); this._changesInfo.appResourcesChanged = true; this._changesInfo.configChanged = true; From e54f922c14fc8bfb2940ac5c3cc7872ced3806c1 Mon Sep 17 00:00:00 2001 From: fatme Date: Thu, 11 Jul 2019 13:03:21 +0300 Subject: [PATCH 59/69] fix: add the link to blog post --- lib/controllers/migrate-controller.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 129e4c172f..d5cbe76624 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -6,8 +6,7 @@ import { UpdateControllerBase } from "./update-controller-base"; import { fromWindowsRelativePathToUnix } from "../common/helpers"; export class MigrateController extends UpdateControllerBase implements IMigrateController { - // TODO: Update the links to blog post when it is available - private static COMMON_MIGRATE_MESSAGE = "not affect the codebase of the application and you might need to do additional changes manually – for more information, refer to the instructions in the following blog post: ."; + private static COMMON_MIGRATE_MESSAGE = "not affect the codebase of the application and you might need to do additional changes manually – for more information, refer to the instructions in the following blog post: https://www.nativescript.org/blog/nativescript-6.0-application-migration."; private static UNABLE_TO_MIGRATE_APP_ERROR = `The current application is not compatible with NativeScript CLI 6.0. Use the \`tns migrate\` command to migrate the app dependencies to a form compatible with NativeScript 6.0. Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; From 5c418472b97f4bcd6fd1a3d14367fc42e156409e Mon Sep 17 00:00:00 2001 From: Fatme Date: Thu, 11 Jul 2019 13:12:16 +0300 Subject: [PATCH 60/69] chore: fix the message Co-Authored-By: Dimitar Tachev --- lib/controllers/migrate-controller.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index d5cbe76624..3a7ce43cb0 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -6,7 +6,7 @@ import { UpdateControllerBase } from "./update-controller-base"; import { fromWindowsRelativePathToUnix } from "../common/helpers"; export class MigrateController extends UpdateControllerBase implements IMigrateController { - private static COMMON_MIGRATE_MESSAGE = "not affect the codebase of the application and you might need to do additional changes manually – for more information, refer to the instructions in the following blog post: https://www.nativescript.org/blog/nativescript-6.0-application-migration."; + private static COMMON_MIGRATE_MESSAGE = "not affect the codebase of the application and you might need to do additional changes manually – for more information, refer to the instructions in the following blog post: https://www.nativescript.org/blog/nativescript-6.0-application-migration"; private static UNABLE_TO_MIGRATE_APP_ERROR = `The current application is not compatible with NativeScript CLI 6.0. Use the \`tns migrate\` command to migrate the app dependencies to a form compatible with NativeScript 6.0. Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; From 6333a6c74c648333b68d771cf3a40f9f7962834a Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Thu, 11 Jul 2019 13:15:52 +0300 Subject: [PATCH 61/69] docs: fix update command help --- docs/man_pages/general/update.md | 2 +- .../man_pages/project/configuration/update.md | 29 ------------------- 2 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 docs/man_pages/project/configuration/update.md diff --git a/docs/man_pages/general/update.md b/docs/man_pages/general/update.md index 868686aa40..9df25b52df 100644 --- a/docs/man_pages/general/update.md +++ b/docs/man_pages/general/update.md @@ -7,7 +7,7 @@ position: 16 ### Description -Updates the project with the latest versions of iOS/Android runtimes and cross-platform modules. +Updates the project with the latest versions of iOS/Android runtimes, cross-platform modules and "nativescript-dev-webpack". In order to get the latest development release instead, pass `next` as argument: `tns update next` diff --git a/docs/man_pages/project/configuration/update.md b/docs/man_pages/project/configuration/update.md deleted file mode 100644 index a59fa8720b..0000000000 --- a/docs/man_pages/project/configuration/update.md +++ /dev/null @@ -1,29 +0,0 @@ -<% if (isJekyll) { %>--- -title: tns update -position: 8 ----<% } %> - -# tns update - -### Description - -Updates a NativeScript to the latest compatible combination of NativeScript dependencies. The combination of dependencies is taken from the latest(or specified) version of the template for the type of the target project (Angular, Vue.js and etc.). - -### Commands - -Usage | Synopsis -------|------- -Update with the latest version |`$ tns update` -Update with specific version | `$ tns update ` - -### Related Commands - -Command | Description -----------|---------- -[install](install.html) | Installs all platforms and dependencies described in the `package.json` file in the current directory. -[platform add](platform-add.html) | Configures the current project to target the selected platform. -[platform remove](platform-remove.html) | Removes the selected platform from the platforms that the project currently targets. -[platform](platform.html) | Lists all platforms that the project currently targets. -[prepare](prepare.html) | Copies common and relevant platform-specific content from the app directory to the subdirectory for the selected target platform in the platforms directory. -[platform update](platform-update.html) | Updates the NativeScript runtime for the specified platform. -[resources update android](resources-update.html) | Updates the App_Resources/Android directory to the new v4.0 directory structure \ No newline at end of file From 0e1c13d650ea194e9c73a6014eb1e51043b6cf79 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Thu, 11 Jul 2019 17:03:04 +0300 Subject: [PATCH 62/69] fix: update with invalid tag will execute for latest compatible version --- docs/man_pages/general/update.md | 2 ++ lib/controllers/update-controller-base.ts | 14 ++++++++------ lib/controllers/update-controller.ts | 21 +++++++++++++++++---- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/docs/man_pages/general/update.md b/docs/man_pages/general/update.md index 9df25b52df..53bf2bef1d 100644 --- a/docs/man_pages/general/update.md +++ b/docs/man_pages/general/update.md @@ -14,6 +14,8 @@ In order to get the latest development release instead, pass `next` as argument: You can also switch to specific version by passing it to the command: `tns update 5.0.0` +**NOTE:** The provided version should be an existing version of the project template for this project type. + ### Commands Usage | Synopsis diff --git a/lib/controllers/update-controller-base.ts b/lib/controllers/update-controller-base.ts index 54cbc3ab7e..5451b9d822 100644 --- a/lib/controllers/update-controller-base.ts +++ b/lib/controllers/update-controller-base.ts @@ -10,7 +10,7 @@ export class UpdateControllerBase { protected $packageInstallationManager: IPackageInstallationManager, protected $packageManager: IPackageManager, protected $pacoteService: IPacoteService) { - this.getPackageManifest = _.memoize(this._getManifestManifest, (...args) => { + this.getPackageManifest = _.memoize(this._getPackageManifest, (...args) => { return args.join("@"); }); } @@ -73,11 +73,13 @@ export class UpdateControllerBase { return maxDependencyVersion; } - private async _getManifestManifest(templateName: string, version?: string) { - const packageVersion = semver.valid(version) || - await this.$packageManager.getTagVersion(templateName, version) || - await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); + private async _getPackageManifest(templateName: string, version: string): Promise { + const packageVersion = semver.valid(version) || await this.$packageManager.getTagVersion(templateName, version); - return await this.$pacoteService.manifest(`${templateName}@${packageVersion}`, { fullMetadata: true }); + if (packageVersion && semver.valid(packageVersion)) { + return await this.$pacoteService.manifest(`${templateName}@${packageVersion}`, { fullMetadata: true }); + } else { + throw new Error(`Failed to get information for package: ${templateName}@${version}`); + } } } diff --git a/lib/controllers/update-controller.ts b/lib/controllers/update-controller.ts index 82b14d64dd..873451cca0 100644 --- a/lib/controllers/update-controller.ts +++ b/lib/controllers/update-controller.ts @@ -19,6 +19,7 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon static readonly backupFolder: string = ".update_backup"; static readonly updateFailMessage: string = "Could not update the project!"; static readonly backupFailMessage: string = "Could not backup project folders!"; + static readonly failedToGetTemplateManifestMessage = "Failed to get template information for the specified version. Original error: %s"; constructor( protected $fs: IFileSystem, @@ -29,6 +30,7 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, private $addPlatformService: IAddPlatformService, private $logger: ILogger, + private $errors: IErrors, private $pluginsService: IPluginsService, protected $pacoteService: IPacoteService, private $projectDataService: IProjectDataService) { @@ -58,8 +60,7 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon public async shouldUpdate({ projectDir, version }: { projectDir: string, version?: string }): Promise { const projectData = this.$projectDataService.getProjectData(projectDir); - const templateName = this.getTemplateName(projectData); - const templateManifest = await this.getPackageManifest(templateName, version); + const templateManifest = await this.getTemplateManifest(projectData, version); const dependencies = this.getUpdatableDependencies(templateManifest.dependencies); const devDependencies = this.getUpdatableDependencies(templateManifest.devDependencies); @@ -92,8 +93,7 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon } private async updateProject(projectData: IProjectData, version: string): Promise { - const templateName = this.getTemplateName(projectData); - const templateManifest = await this.getPackageManifest(templateName, version); + const templateManifest = await this.getTemplateManifest(projectData, version); const dependencies = this.getUpdatableDependencies(templateManifest.dependencies); const devDependencies = this.getUpdatableDependencies(templateManifest.devDependencies); @@ -208,6 +208,19 @@ export class UpdateController extends UpdateControllerBase implements IUpdateCon return template; } + + private async getTemplateManifest(projectData: IProjectData, version: string): Promise { + let templateManifest; + const templateName = this.getTemplateName(projectData); + version = version || await this.$packageInstallationManager.getLatestCompatibleVersionSafe(templateName); + try { + templateManifest = await this.getPackageManifest(templateName, version); + } catch (err) { + this.$errors.fail(UpdateController.failedToGetTemplateManifestMessage, err.message); + } + + return templateManifest; + } } $injector.register("updateController", UpdateController); From 07149eefb0157b3afe228afdb6e62fa48a9c4521 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 11 Jul 2019 17:30:48 +0300 Subject: [PATCH 63/69] fix: disable the `watch` in release build as its triggering 2 snapshot build causing an invalid build --- lib/helpers/livesync-command-helper.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/helpers/livesync-command-helper.ts b/lib/helpers/livesync-command-helper.ts index fcc6d26076..f895783f2f 100644 --- a/lib/helpers/livesync-command-helper.ts +++ b/lib/helpers/livesync-command-helper.ts @@ -65,7 +65,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { projectDir: this.$projectData.projectDir }); - const buildData = this.$buildDataService.getBuildData(this.$projectData.projectDir, d.deviceInfo.platform, { ...this.$options.argv, outputPath, buildForDevice: !d.isEmulator }); + const buildData = this.$buildDataService.getBuildData(this.$projectData.projectDir, d.deviceInfo.platform, { ...this.$options.argv, outputPath, buildForDevice: !d.isEmulator, watch: !this.$options.release && this.$options.watch }); const buildAction = additionalOptions && additionalOptions.buildPlatform ? additionalOptions.buildPlatform.bind(additionalOptions.buildPlatform, d.deviceInfo.platform, buildData, this.$projectData) : @@ -83,7 +83,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { return info; }); - return deviceDescriptors; + return deviceDescriptors; } public getPlatformsForOperation(platform: string): string[] { @@ -133,7 +133,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { return result; } - private async executeLiveSyncOperationCore(devices: Mobile.IDevice[], platform: string, additionalOptions?: ILiveSyncCommandHelperAdditionalOptions): Promise<{liveSyncInfo: ILiveSyncInfo, deviceDescriptors: ILiveSyncDeviceDescriptor[]}> { + private async executeLiveSyncOperationCore(devices: Mobile.IDevice[], platform: string, additionalOptions?: ILiveSyncCommandHelperAdditionalOptions): Promise<{ liveSyncInfo: ILiveSyncInfo, deviceDescriptors: ILiveSyncDeviceDescriptor[] }> { if (!devices || !devices.length) { if (platform) { this.$errors.failWithoutHelp("Unable to find applicable devices to execute operation. Ensure connected devices are trusted and try again."); From c15c2d17d812b2a47f148979a33f6a785d352863 Mon Sep 17 00:00:00 2001 From: Kristian Dimitrov Date: Thu, 11 Jul 2019 18:46:00 +0300 Subject: [PATCH 64/69] chore: update migrate dependencies --- lib/controllers/migrate-controller.ts | 29 +++++++++++++-------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 4c410da0d5..67b7cddcad 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -46,30 +46,29 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; ]; private migrationDependencies: IMigrationDependency[] = [ - { packageName: constants.TNS_CORE_MODULES_NAME, verifiedVersion: "6.0.0-rc-2019-07-09-183845-06" }, - { packageName: constants.TNS_CORE_MODULES_WIDGETS_NAME, verifiedVersion: "6.0.0" }, - { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.0-rc-2019-07-09-183845-06" }, + { packageName: constants.TNS_CORE_MODULES_NAME, verifiedVersion: "6.0.1" }, + { packageName: constants.TNS_CORE_MODULES_WIDGETS_NAME, verifiedVersion: "6.0.1" }, + { packageName: "tns-platform-declarations", isDev: true, verifiedVersion: "6.0.1" }, { packageName: "node-sass", isDev: true, verifiedVersion: "4.12.0" }, { packageName: "nativescript-dev-sass", isDev: true, replaceWith: "node-sass" }, { packageName: "nativescript-dev-typescript", isDev: true, replaceWith: MigrateController.typescriptPackageName }, { packageName: "nativescript-dev-less", isDev: true, shouldRemove: true, warning: "LESS CSS is not supported out of the box. In order to enable it, follow the steps in this feature request: https://github.com/NativeScript/nativescript-dev-webpack/issues/967" }, - { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0-rc-2019-07-10-002255-01" }, + { packageName: constants.WEBPACK_PLUGIN_NAME, isDev: true, shouldAddIfMissing: true, verifiedVersion: "1.0.0" }, { packageName: "nativescript-camera", verifiedVersion: "4.5.0" }, { packageName: "nativescript-geolocation", verifiedVersion: "5.1.0" }, { packageName: "nativescript-imagepicker", verifiedVersion: "6.2.0" }, { packageName: "nativescript-social-share", verifiedVersion: "1.5.2" }, - { packageName: "nativescript-ui-chart", verifiedVersion: "5.0.0-androidx-110619" }, - { packageName: "nativescript-ui-dataform", verifiedVersion: "5.0.0-androidx-110619" }, - { packageName: "nativescript-ui-gauge", verifiedVersion: "5.0.0-androidx" }, - { packageName: "nativescript-ui-listview", verifiedVersion: "7.0.0-androidx-110619" }, - { packageName: "nativescript-ui-sidedrawer", verifiedVersion: "7.0.0-androidx-110619" }, - { packageName: "nativescript-ui-calendar", verifiedVersion: "5.0.0-androidx-110619-2" }, - { packageName: "nativescript-ui-autocomplete", verifiedVersion: "5.0.0-androidx-110619" }, + { packageName: "nativescript-ui-chart", verifiedVersion: "5.0.0" }, + { packageName: "nativescript-ui-dataform", verifiedVersion: "5.0.0" }, + { packageName: "nativescript-ui-gauge", verifiedVersion: "5.0.0" }, + { packageName: "nativescript-ui-listview", verifiedVersion: "7.0.0" }, + { packageName: "nativescript-ui-sidedrawer", verifiedVersion: "7.0.0" }, + { packageName: "nativescript-ui-calendar", verifiedVersion: "5.0.0" }, + { packageName: "nativescript-ui-autocomplete", verifiedVersion: "5.0.0" }, { packageName: "nativescript-datetimepicker", verifiedVersion: "1.1.0" }, { packageName: "kinvey-nativescript-sdk", verifiedVersion: "4.2.1" }, { packageName: "nativescript-plugin-firebase", verifiedVersion: "9.0.2" }, - // TODO: update with no prerelease version compatible with webpack only hooks - { packageName: "nativescript-vue", verifiedVersion: "2.3.0-rc.2" }, + { packageName: "nativescript-vue", verifiedVersion: "2.3.0" }, { packageName: "nativescript-permissions", verifiedVersion: "1.3.0" }, { packageName: "nativescript-cardview", verifiedVersion: "3.2.0" }, { @@ -89,8 +88,8 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; get verifiedPlatformVersions(): IDictionary { return { - [this.$devicePlatformsConstants.Android.toLowerCase()]: "6.0.0-rc-2019-06-27-172817-03", - [this.$devicePlatformsConstants.iOS.toLowerCase()]: "6.0.0-rc-2019-06-28-105002-01" + [this.$devicePlatformsConstants.Android.toLowerCase()]: "6.0.0", + [this.$devicePlatformsConstants.iOS.toLowerCase()]: "6.0.0" }; } From 423f77eb675ec692aad55f1d1567f076fb6e03b0 Mon Sep 17 00:00:00 2001 From: fatme Date: Fri, 12 Jul 2019 13:00:01 +0300 Subject: [PATCH 65/69] fix: fix the missing icons in newly created apps on iOS devices --- lib/services/platform/add-platform-service.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/services/platform/add-platform-service.ts b/lib/services/platform/add-platform-service.ts index 0d6ad7438e..9185127290 100644 --- a/lib/services/platform/add-platform-service.ts +++ b/lib/services/platform/add-platform-service.ts @@ -1,13 +1,12 @@ import * as path from "path"; import * as temp from "temp"; -import { PROJECT_FRAMEWORK_FOLDER_NAME, NativePlatformStatus } from "../../constants"; +import { PROJECT_FRAMEWORK_FOLDER_NAME } from "../../constants"; import { performanceLog } from "../../common/decorators"; export class AddPlatformService implements IAddPlatformService { constructor( private $fs: IFileSystem, private $pacoteService: IPacoteService, - private $projectChangesService: IProjectChangesService, private $projectDataService: IProjectDataService, private $terminalSpinnerService: ITerminalSpinnerService ) { } @@ -61,7 +60,6 @@ export class AddPlatformService implements IAddPlatformService { platformData.platformProjectService.ensureConfigurationFileInAppResources(projectData); await platformData.platformProjectService.interpolateData(projectData); platformData.platformProjectService.afterCreateProject(platformData.projectRoot, projectData); - await this.$projectChangesService.setNativePlatformStatus(platformData, projectData, { nativePlatformStatus: NativePlatformStatus.requiresPrepare }); } } $injector.register("addPlatformService", AddPlatformService); From 488791585787dfcabee1209623e87f674f537982 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Mon, 15 Jul 2019 08:46:32 +0300 Subject: [PATCH 66/69] fix: do not validate invalid platforms versions --- lib/controllers/migrate-controller.ts | 4 ++++ lib/declarations.d.ts | 5 +++++ .../platform/platform-validation-service.ts | 17 ++++++++++++++--- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/lib/controllers/migrate-controller.ts b/lib/controllers/migrate-controller.ts index 67b7cddcad..49c00bcd52 100644 --- a/lib/controllers/migrate-controller.ts +++ b/lib/controllers/migrate-controller.ts @@ -26,6 +26,7 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; private $addPlatformService: IAddPlatformService, private $pluginsService: IPluginsService, private $projectDataService: IProjectDataService, + private $platformValidationService: IPlatformValidationService, private $resources: IResourceLoader) { super($fs, $platformCommandHelper, $platformsDataService, $packageInstallationManager, $packageManager, $pacoteService); } @@ -159,6 +160,9 @@ Running this command will ${MigrateController.COMMON_MIGRATE_MESSAGE}`; for (let platform of platforms) { platform = platform && platform.toLowerCase(); + if (!this.$platformValidationService.isValidPlatform(platform, projectData)) { + continue; + } const hasRuntimeDependency = this.hasRuntimeDependency({ platform, projectData }); if (hasRuntimeDependency && await this.shouldUpdateRuntimeVersion(this.verifiedPlatformVersions[platform.toLowerCase()], platform, projectData, allowInvalidVersions)) { diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index b1b2c43a64..389e2c17b7 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -1021,6 +1021,11 @@ interface IPlatformValidationService { */ validatePlatform(platform: string, projectData: IProjectData): void; + /** + * Returns whether the passed platform is a valid one (from the supported ones) + */ + isValidPlatform(platform: string, projectData: IProjectData): boolean; + /** * Gets first chance to validate the options provided as command line arguments. * If no platform is provided or a falsy (null, undefined, "", false...) platform is provided, diff --git a/lib/services/platform/platform-validation-service.ts b/lib/services/platform/platform-validation-service.ts index 6648803b51..2ac7981c9d 100644 --- a/lib/services/platform/platform-validation-service.ts +++ b/lib/services/platform/platform-validation-service.ts @@ -11,14 +11,25 @@ export class PlatformValidationService implements IPlatformValidationService { private $platformsDataService: IPlatformsDataService ) { } - public validatePlatform(platform: string, projectData: IProjectData): void { + public isValidPlatform(platform: string, projectData: IProjectData): boolean { if (!platform) { - this.$errors.fail("No platform specified."); + return false; } platform = platform.split("@")[0].toLowerCase(); - if (!this.$platformsDataService.getPlatformData(platform, projectData)) { + return false; + } + + return true; + } + + public validatePlatform(platform: string, projectData: IProjectData): void { + if (!platform) { + this.$errors.fail("No platform specified."); + } + + if (!this.isValidPlatform(platform, projectData)) { const platformNames = helpers.formatListOfNames(this.$mobileHelper.platformNames); this.$errors.fail(`Invalid platform ${platform}. Valid platforms are ${platformNames}.`); } From b117ef72cb260f9464311de47b0992f0356c9bd9 Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 15 Jul 2019 09:05:10 +0300 Subject: [PATCH 67/69] fix: stop all webpack processes from sidekick when stopping the livesync Currently when livesync is started on iOS device from sidekick, {N} CLI persist that livesync is started for iOS platform. After that if the livesync process is started on android device, {N} CLI overrides the persisted platforms and stores that the livesync is started for Android platform. However, when the livesync is stopped, {N} CLI stops it only for android platform. This means that the iOS webpack process is alive and continues to report data. This led to the multiple livesync messages when syncing the changes. --- lib/controllers/run-controller.ts | 4 +++- lib/definitions/livesync.d.ts | 1 + lib/services/livesync-process-data-service.ts | 8 +++++++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/lib/controllers/run-controller.ts b/lib/controllers/run-controller.ts index bb46da92e5..259a44b99f 100644 --- a/lib/controllers/run-controller.ts +++ b/lib/controllers/run-controller.ts @@ -38,8 +38,10 @@ export class RunController extends EventEmitter implements IRunController { const projectData = this.$projectDataService.getProjectData(projectDir); await this.initializeSetup(projectData); - const platforms = this.$devicesService.getPlatformsFromDeviceDescriptors(deviceDescriptors); const deviceDescriptorsForInitialSync = this.getDeviceDescriptorsForInitialSync(projectDir, deviceDescriptors); + const newPlatforms = this.$devicesService.getPlatformsFromDeviceDescriptors(deviceDescriptors); + const oldPlatforms = this.$liveSyncProcessDataService.getPlatforms(projectDir); + const platforms = _.uniq(_.concat(newPlatforms, oldPlatforms)); this.$liveSyncProcessDataService.persistData(projectDir, deviceDescriptors, platforms); diff --git a/lib/definitions/livesync.d.ts b/lib/definitions/livesync.d.ts index b692609ccb..e4ac2c0d99 100644 --- a/lib/definitions/livesync.d.ts +++ b/lib/definitions/livesync.d.ts @@ -492,5 +492,6 @@ declare global { getAllPersistedData(): IDictionary; persistData(projectDir: string, deviceDescriptors: ILiveSyncDeviceDescriptor[], platforms: string[]): void; hasDeviceDescriptors(projectDir: string): boolean; + getPlatforms(projectDir: string): string[]; } } diff --git a/lib/services/livesync-process-data-service.ts b/lib/services/livesync-process-data-service.ts index 6edd76ef88..487141aa04 100644 --- a/lib/services/livesync-process-data-service.ts +++ b/lib/services/livesync-process-data-service.ts @@ -6,7 +6,7 @@ export class LiveSyncProcessDataService implements ILiveSyncProcessDataService { this.processes[projectDir].actionsChain = this.processes[projectDir].actionsChain || Promise.resolve(); this.processes[projectDir].currentSyncAction = this.processes[projectDir].actionsChain; this.processes[projectDir].isStopped = false; - this.processes[projectDir].platforms = platforms; + this.processes[projectDir].platforms = platforms; const currentDeviceDescriptors = this.getDeviceDescriptors(projectDir); this.processes[projectDir].deviceDescriptors = _.uniqBy(currentDeviceDescriptors.concat(deviceDescriptors), "identifier"); @@ -30,5 +30,11 @@ export class LiveSyncProcessDataService implements ILiveSyncProcessDataService { public getAllPersistedData() { return this.processes; } + + public getPlatforms(projectDir: string): string[] { + const liveSyncProcessesInfo = this.processes[projectDir] || {}; + const currentPlatforms = liveSyncProcessesInfo.platforms; + return currentPlatforms || []; + } } $injector.register("liveSyncProcessDataService", LiveSyncProcessDataService); From fd1ed04c8d8608c5350fad4eaf393931fa20d6fe Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Mon, 15 Jul 2019 09:15:25 +0300 Subject: [PATCH 68/69] fix: skip migration check based on the --force flag --- lib/commands/build.ts | 8 ++++++-- lib/commands/debug.ts | 4 +++- lib/commands/prepare.ts | 6 +++++- lib/commands/preview.ts | 4 +++- lib/commands/run.ts | 7 ++++++- lib/commands/test.ts | 4 +++- 6 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/commands/build.ts b/lib/commands/build.ts index 912753e508..86686e4688 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -74,7 +74,9 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { public async canExecute(args: string[]): Promise { const platform = this.$devicePlatformsConstants.iOS; - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); + if (!this.$options.force) { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); + } super.validatePlatform(platform); @@ -120,7 +122,9 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { public async canExecute(args: string[]): Promise { const platform = this.$devicePlatformsConstants.Android; - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); + if (!this.$options.force) { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); + } this.$androidBundleValidatorHelper.validateRuntimeVersion(this.$projectData); let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true } }); if (result.canExecute) { diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts index a9ca28acb0..1bdc9c50b3 100644 --- a/lib/commands/debug.ts +++ b/lib/commands/debug.ts @@ -53,7 +53,9 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements } public async canExecute(args: string[]): Promise { - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [this.platform] }); + if (!this.$options.force) { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [this.platform] }); + } this.$androidBundleValidatorHelper.validateNoAab(); diff --git a/lib/commands/prepare.ts b/lib/commands/prepare.ts index 5faef3e149..0e42bdd1aa 100644 --- a/lib/commands/prepare.ts +++ b/lib/commands/prepare.ts @@ -33,7 +33,11 @@ export class PrepareCommand extends ValidatePlatformCommandBase implements IComm const platform = args[0]; const result = await this.$platformCommandParameter.validate(platform) && await this.$platformValidationService.validateOptions(this.$options.provision, this.$options.teamId, this.$projectData, platform); - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); + + if (!this.$options.force) { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [platform] }); + } + if (!result) { return false; } diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index 8f847fe5eb..21249fec62 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -41,7 +41,9 @@ export class PreviewCommand implements ICommand { this.$errors.fail(`The arguments '${args.join(" ")}' are not valid for the preview command.`); } - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [] }); + if (!this.$options.force) { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [] }); + } await this.$networkConnectivityValidator.validate(); return true; diff --git a/lib/commands/run.ts b/lib/commands/run.ts index f5e3ef9861..7348c63c58 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -14,6 +14,7 @@ export class RunCommandBase implements ICommand { private $hostInfo: IHostInfo, private $liveSyncCommandHelper: ILiveSyncCommandHelper, private $migrateController: IMigrateController, + private $options: IOptions, private $projectData: IProjectData ) { } @@ -36,7 +37,11 @@ export class RunCommandBase implements ICommand { this.$androidBundleValidatorHelper.validateNoAab(); this.$projectData.initializeProjectData(); const platforms = this.platform ? [this.platform] : [this.$devicePlatformsConstants.Android, this.$devicePlatformsConstants.iOS]; - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms }); + + if (!this.$options.force) { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms }); + } + await this.$liveSyncCommandHelper.validatePlatform(this.platform); return true; diff --git a/lib/commands/test.ts b/lib/commands/test.ts index 8f12bea759..e412e72ab0 100644 --- a/lib/commands/test.ts +++ b/lib/commands/test.ts @@ -49,7 +49,9 @@ abstract class TestCommandBase { } async canExecute(args: string[]): Promise { - await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [this.platform] }); + if (!this.$options.force) { + await this.$migrateController.validate({ projectDir: this.$projectData.projectDir, platforms: [this.platform] }); + } this.$projectData.initializeProjectData(); this.$analyticsService.setShouldDispose(this.$options.justlaunch || !this.$options.watch); From c575d50f6f49a0cbacb6eacaf96a680456373b38 Mon Sep 17 00:00:00 2001 From: fatme Date: Mon, 15 Jul 2019 14:09:44 +0300 Subject: [PATCH 69/69] chore: fix additional whitespace --- lib/services/livesync-process-data-service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/livesync-process-data-service.ts b/lib/services/livesync-process-data-service.ts index 487141aa04..9975bdb6d2 100644 --- a/lib/services/livesync-process-data-service.ts +++ b/lib/services/livesync-process-data-service.ts @@ -6,7 +6,7 @@ export class LiveSyncProcessDataService implements ILiveSyncProcessDataService { this.processes[projectDir].actionsChain = this.processes[projectDir].actionsChain || Promise.resolve(); this.processes[projectDir].currentSyncAction = this.processes[projectDir].actionsChain; this.processes[projectDir].isStopped = false; - this.processes[projectDir].platforms = platforms; + this.processes[projectDir].platforms = platforms; const currentDeviceDescriptors = this.getDeviceDescriptors(projectDir); this.processes[projectDir].deviceDescriptors = _.uniqBy(currentDeviceDescriptors.concat(deviceDescriptors), "identifier");