From d255b97ac3e41699ebe5e4fb05abfed4491ba2d6 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 18 Apr 2019 11:03:50 +0300 Subject: [PATCH 1/5] feat: deprecate the legacy workflow and recommend the new one --- lib/bootstrap.ts | 1 + lib/commands/preview.ts | 8 +- lib/commands/test.ts | 8 +- lib/commands/update.ts | 9 +- lib/declarations.d.ts | 7 ++ lib/definitions/platform.d.ts | 10 ++ lib/definitions/project.d.ts | 10 +- lib/helpers/bundle-validator-helper.ts | 20 ++-- lib/options.ts | 1 + lib/project-data.ts | 2 +- .../preview-app-livesync-service.ts | 10 +- lib/services/platform-service.ts | 4 +- lib/services/project-data-service.ts | 72 +++++++++++-- lib/services/workflow-service.ts | 102 ++++++++++++++++++ test/stubs.ts | 3 + 15 files changed, 239 insertions(+), 28 deletions(-) create mode 100644 lib/services/workflow-service.ts diff --git a/lib/bootstrap.ts b/lib/bootstrap.ts index e359fa3f35..a3a6c22a12 100644 --- a/lib/bootstrap.ts +++ b/lib/bootstrap.ts @@ -190,6 +190,7 @@ $injector.require("hmrStatusService", "./services/hmr-status-service"); $injector.require("pacoteService", "./services/pacote-service"); $injector.require("qrCodeTerminalService", "./services/qr-code-terminal-service"); $injector.require("testInitializationService", "./services/test-initialization-service"); +$injector.require("workflowService", "./services/workflow-service"); $injector.require("networkConnectivityValidator", "./helpers/network-connectivity-validator"); $injector.requirePublic("cleanupService", "./services/cleanup-service"); diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index bb2aab8c35..4a77d6a294 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -14,12 +14,14 @@ export class PreviewCommand implements ICommand { private $options: IOptions, private $previewAppLogProvider: IPreviewAppLogProvider, private $previewQrCodeService: IPreviewQrCodeService, + protected $workflowService: IWorkflowService, $cleanupService: ICleanupService) { - this.$analyticsService.setShouldDispose(false); - $cleanupService.setShouldDispose(false); - } + this.$analyticsService.setShouldDispose(false); + $cleanupService.setShouldDispose(false); + } public async execute(): Promise { + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options); this.$previewAppLogProvider.on(DEVICE_LOG_EVENT_NAME, (deviceId: string, message: string) => { this.$logger.info(message); }); diff --git a/lib/commands/test.ts b/lib/commands/test.ts index e96d981793..f855972076 100644 --- a/lib/commands/test.ts +++ b/lib/commands/test.ts @@ -11,8 +11,10 @@ abstract class TestCommandBase { protected abstract $platformEnvironmentRequirements: IPlatformEnvironmentRequirements; protected abstract $errors: IErrors; protected abstract $cleanupService: ICleanupService; + protected abstract $workflowService: IWorkflowService; async execute(args: string[]): Promise { + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options); await this.$testExecutionService.startKarmaServer(this.platform, this.$projectData, this.projectFilesConfig); } @@ -54,7 +56,8 @@ class TestAndroidCommand extends TestCommandBase implements ICommand { protected $options: IOptions, protected $platformEnvironmentRequirements: IPlatformEnvironmentRequirements, protected $errors: IErrors, - protected $cleanupService: ICleanupService) { + protected $cleanupService: ICleanupService, + protected $workflowService: IWorkflowService) { super(); } @@ -69,7 +72,8 @@ class TestIosCommand extends TestCommandBase implements ICommand { protected $options: IOptions, protected $platformEnvironmentRequirements: IPlatformEnvironmentRequirements, protected $errors: IErrors, - protected $cleanupService: ICleanupService) { + protected $cleanupService: ICleanupService, + protected $workflowService: IWorkflowService) { super(); } diff --git a/lib/commands/update.ts b/lib/commands/update.ts index 1649284c41..07054ac7be 100644 --- a/lib/commands/update.ts +++ b/lib/commands/update.ts @@ -12,7 +12,8 @@ export class UpdateCommand extends ValidatePlatformCommandBase implements IComma private $pluginsService: IPluginsService, private $projectDataService: IProjectDataService, private $fs: IFileSystem, - private $logger: ILogger) { + private $logger: ILogger, + private $workflowService: IWorkflowService) { super($options, $platformsData, $platformService, $projectData); this.$projectData.initializeProjectData(); } @@ -28,6 +29,12 @@ export class UpdateCommand extends ValidatePlatformCommandBase implements IComma static readonly backupFailMessage: string = "Could not backup project folders!"; public async execute(args: string[]): Promise { + if (this.$options.workflow) { + const forceWebpackWorkflow = true; + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, forceWebpackWorkflow); + return; + } + const tmpDir = path.join(this.$projectData.projectDir, UpdateCommand.tempFolder); try { diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index e048c14ba4..aef6e0fd86 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -571,6 +571,7 @@ interface IOptions extends IRelease, IDeviceIdentifier, IJustLaunch, IAvd, IAvai performance: Object; setupOptions(projectData: IProjectData): void; cleanupLogFile: string; + workflow: boolean; } interface IEnvOptions { @@ -940,6 +941,12 @@ interface IBundleValidatorHelper { * @return {void} */ validate(minSupportedVersion?: string): void; + + /** + * Returns the installed bundler version. + * @return {string} + */ + getBundlerDependencyVersion(bundlerName?: string): string; } diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts index 6a02997efc..e9f29a99c8 100644 --- a/lib/definitions/platform.d.ts +++ b/lib/definitions/platform.d.ts @@ -14,6 +14,16 @@ interface IBuildPlatformAction { buildPlatform(platform: string, buildConfig: IBuildConfig, projectData: IProjectData): Promise; } +interface IWorkflowService { + handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, force?: boolean): Promise; +} + +interface IWebpackWorkflowSettings { + bundle?: boolean | string; + useHotModuleReload?: boolean; + release?: boolean; +} + interface IPlatformService extends IBuildPlatformAction, NodeJS.EventEmitter { cleanPlatforms(platforms: string[], platformTemplate: string, projectData: IProjectData, config: IPlatformOptions, framework?: string): Promise; diff --git a/lib/definitions/project.d.ts b/lib/definitions/project.d.ts index 8de8d95e18..37be0d1158 100644 --- a/lib/definitions/project.d.ts +++ b/lib/definitions/project.d.ts @@ -142,6 +142,14 @@ interface IProjectDataService { */ setNSValue(projectDir: string, key: string, value: any): void; + /** + * Sets a value in the `useLegacyWorkflow` key in a project's nsconfig.json. + * @param {string} projectDir The project directory - the place where the root package.json is located. + * @param {any} value Value of the key to be set to `useLegacyWorkflow` key in project's nsconfig.json. + * @returns {void} + */ + setUseLegacyWorkflow(projectDir: string, value: any): void; + /** * Removes a property from `nativescript` key in project's package.json. * @param {string} projectDir The project directory - the place where the root package.json is located. @@ -584,7 +592,7 @@ interface IIOSExtensionsService { removeExtensions(options: IRemoveExtensionsOptions): void; } -interface IAddExtensionsFromPathOptions{ +interface IAddExtensionsFromPathOptions { extensionsFolderPath: string; projectData: IProjectData; platformData: IPlatformData; diff --git a/lib/helpers/bundle-validator-helper.ts b/lib/helpers/bundle-validator-helper.ts index 4eedac652b..2caf345a16 100644 --- a/lib/helpers/bundle-validator-helper.ts +++ b/lib/helpers/bundle-validator-helper.ts @@ -16,20 +16,28 @@ export class BundleValidatorHelper extends VersionValidatorHelper implements IBu public validate(minSupportedVersion?: string): void { if (this.$options.bundle) { - const bundlePluginName = this.bundlersMap[this.$options.bundle]; - const bundlerVersionInDependencies = this.$projectData.dependencies && this.$projectData.dependencies[bundlePluginName]; - const bundlerVersionInDevDependencies = this.$projectData.devDependencies && this.$projectData.devDependencies[bundlePluginName]; - if (!bundlePluginName || (!bundlerVersionInDependencies && !bundlerVersionInDevDependencies)) { + const currentVersion = this.getBundlerDependencyVersion(); + if (!currentVersion) { this.$errors.failWithoutHelp(BundleValidatorMessages.MissingBundlePlugin); } - const currentVersion = bundlerVersionInDependencies || bundlerVersionInDevDependencies; const shouldThrowError = minSupportedVersion && this.isValidVersion(currentVersion) && this.isVersionLowerThan(currentVersion, minSupportedVersion); if (shouldThrowError) { - this.$errors.failWithoutHelp(util.format(BundleValidatorMessages.NotSupportedVersion, minSupportedVersion)); + this.$errors.failWithoutHelp(util.format(BundleValidatorMessages.NotSupportedVersion, minSupportedVersion)); } } } + + public getBundlerDependencyVersion(bundlerName?: string): string { + let dependencyVersion = null; + const bundlePluginName = bundlerName || this.bundlersMap[this.$options.bundle]; + const bundlerVersionInDependencies = this.$projectData.dependencies && this.$projectData.dependencies[bundlePluginName]; + const bundlerVersionInDevDependencies = this.$projectData.devDependencies && this.$projectData.devDependencies[bundlePluginName]; + dependencyVersion = bundlerVersionInDependencies || bundlerVersionInDevDependencies; + + return dependencyVersion; + + } } $injector.register("bundleValidatorHelper", BundleValidatorHelper); diff --git a/lib/options.ts b/lib/options.ts index b75042a669..44793f0fcb 100644 --- a/lib/options.ts +++ b/lib/options.ts @@ -136,6 +136,7 @@ export class Options { file: { type: OptionType.String, hasSensitiveValue: true }, force: { type: OptionType.Boolean, alias: "f", hasSensitiveValue: false }, // remove legacy + workflow: { type: OptionType.Boolean, hasSensitiveValue: false }, companion: { type: OptionType.Boolean, hasSensitiveValue: false }, emulator: { type: OptionType.Boolean, hasSensitiveValue: false }, sdk: { type: OptionType.String, hasSensitiveValue: false }, diff --git a/lib/project-data.ts b/lib/project-data.ts index 328d8a6198..0e3106b7e7 100644 --- a/lib/project-data.ts +++ b/lib/project-data.ts @@ -263,4 +263,4 @@ export class ProjectData implements IProjectData { this.$logger.warnWithLabel("IProjectData.projectId is deprecated. Please use IProjectData.projectIdentifiers[platform]."); } } -$injector.register("projectData", ProjectData); +$injector.register("projectData", ProjectData, true); diff --git a/lib/services/livesync/playground/preview-app-livesync-service.ts b/lib/services/livesync/playground/preview-app-livesync-service.ts index ad59828b55..b7db6b59ba 100644 --- a/lib/services/livesync/playground/preview-app-livesync-service.ts +++ b/lib/services/livesync/playground/preview-app-livesync-service.ts @@ -22,13 +22,15 @@ export class PreviewAppLiveSyncService extends EventEmitter implements IPreviewA private $previewAppFilesService: IPreviewAppFilesService, private $previewAppPluginsService: IPreviewAppPluginsService, private $previewDevicesService: IPreviewDevicesService, - private $hmrStatusService: IHmrStatusService) { - super(); - } + private $hmrStatusService: IHmrStatusService, + protected $workflowService: IWorkflowService) { + super(); + } @performanceLog() public async initialize(data: IPreviewAppLiveSyncData): Promise { await this.$previewSdkService.initialize(data.projectDir, async (device: Device) => { + await this.$workflowService.handleLegacyWorkflow(data.projectDir, data); try { if (!device) { this.$errors.failWithoutHelp("Sending initial preview files without a specified device is not supported."); @@ -177,7 +179,7 @@ export class PreviewAppLiveSyncService extends EventEmitter implements IPreviewA if (status === HmrConstants.HMR_ERROR_STATUS) { const originalUseHotModuleReload = data.useHotModuleReload; data.useHotModuleReload = false; - await this.syncFilesForPlatformSafe(data, { filesToSync: platformHmrData.fallbackFiles }, platform, previewDevice.id ); + await this.syncFilesForPlatformSafe(data, { filesToSync: platformHmrData.fallbackFiles }, platform, previewDevice.id); data.useHotModuleReload = originalUseHotModuleReload; } })); diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index 4129447144..b5d8a20885 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -36,7 +36,8 @@ export class PlatformService extends EventEmitter implements IPlatformService { private $terminalSpinnerService: ITerminalSpinnerService, private $pacoteService: IPacoteService, private $usbLiveSyncService: any, - public $hooksService: IHooksService + public $hooksService: IHooksService, + public $workflowService: IWorkflowService ) { super(); } @@ -221,6 +222,7 @@ export class PlatformService extends EventEmitter implements IPlatformService { @performanceLog() public async preparePlatform(platformInfo: IPreparePlatformInfo): Promise { + await this.$workflowService.handleLegacyWorkflow(platformInfo.projectData.projectDir, platformInfo.appFilesUpdaterOptions); const changesInfo = await this.getChangesInfo(platformInfo); const shouldPrepare = await this.shouldPrepare({ platformInfo, changesInfo }); diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 6a4cb20bbd..34e5f3e389 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 * as constants from "../constants"; import { ProjectData } from "../project-data"; +import { parseJson } from "../common/helpers"; import { exported } from "../common/decorators"; import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER, @@ -17,14 +19,21 @@ interface IProjectFileData { } export class ProjectDataService implements IProjectDataService { + private defaultProjectDir = ""; private static DEPENDENCIES_KEY_NAME = "dependencies"; + private projectDataCache: IDictionary = {}; constructor(private $fs: IFileSystem, private $staticConfig: IStaticConfig, private $logger: ILogger, private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, private $androidResourcesMigrationService: IAndroidResourcesMigrationService, - private $injector: IInjector) { + private $injector: IInjector, + $projectData: IProjectData) { + // add the ProjectData of the default projectDir to the projectData cache + $projectData.initializeProjectData(); + this.defaultProjectDir = $projectData.projectDir; + this.projectDataCache[this.defaultProjectDir] = $projectData; } public getNSValue(projectDir: string, propertyName: string): any { @@ -49,16 +58,19 @@ export class ProjectDataService implements IProjectDataService { // TODO: Remove $projectData and replace it with $projectDataService.getProjectData @exported("projectDataService") public getProjectData(projectDir: string): IProjectData { - const projectDataInstance = this.$injector.resolve(ProjectData); - projectDataInstance.initializeProjectData(projectDir); - return projectDataInstance; + projectDir = projectDir || this.defaultProjectDir; + this.projectDataCache[projectDir] = this.projectDataCache[projectDir] || this.$injector.resolve(ProjectData); + this.projectDataCache[projectDir].initializeProjectData(projectDir); + + return this.projectDataCache[projectDir]; } @exported("projectDataService") public getProjectDataFromContent(packageJsonContent: string, nsconfigContent: string, projectDir?: string): IProjectData { - const projectDataInstance = this.$injector.resolve(ProjectData); - projectDataInstance.initializeProjectDataFromContent(packageJsonContent, nsconfigContent, projectDir); - return projectDataInstance; + projectDir = projectDir || this.defaultProjectDir; + this.projectDataCache[projectDir] = this.projectDataCache[projectDir] || this.$injector.resolve(ProjectData); + this.projectDataCache[projectDir].initializeProjectDataFromContent(packageJsonContent, nsconfigContent, projectDir); + return this.projectDataCache[projectDir]; } @exported("projectDataService") @@ -124,6 +136,14 @@ export class ProjectDataService implements IProjectDataService { }; } + public setUseLegacyWorkflow(projectDir: string, value: any): void { + // TODO: use trace + this.$logger.info(`useLegacyWorkflow will be set to ${value}`); + this.updateNsConfigValue(projectDir, { useLegacyWorkflow: value }); + this.refreshProjectData(projectDir); + this.$logger.info(`useLegacyWorkflow was set to ${value}`); + } + public getAppExecutableFiles(projectDir: string): string[] { const projectData = this.getProjectData(projectDir); @@ -157,6 +177,34 @@ 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): void { + const nsConfigPath = path.join(projectDir, constants.CONFIG_NS_FILE_NAME); + const currentNsConfig = this.getNsConfig(nsConfigPath); + const newNsConfig = Object.assign(currentNsConfig, updateObject); + + this.$fs.writeJson(nsConfigPath, newNsConfig); + } + + private getNsConfig(nsConfigPath: string): INsConfig { + let result = this.getNsConfigDefaultObject(); + if (this.$fs.exists(nsConfigPath)) { + const nsConfigContent = this.$fs.readText(nsConfigPath); + try { + result = parseJson(nsConfigContent); + } catch (e) { + // default + } + } + + return result; + } + private getImageDefinitions(): IImageDefinitionsStructure { const pathToImageDefinitions = path.join(__dirname, "..", "..", CLI_RESOURCES_DIR_NAME, AssetConstants.assets, AssetConstants.imageDefinitionsFileName); const imageDefinitions = this.$fs.readJson(pathToImageDefinitions); @@ -308,10 +356,16 @@ export class ProjectDataService implements IProjectDataService { }; } + private getNsConfigDefaultObject(data?: Object): INsConfig { + const config: INsConfig = { useLegacyWorkflow: false }; + Object.assign(config, data); + + return config; + } + @exported("projectDataService") public getNsConfigDefaultContent(data?: Object): string { - const config: INsConfig = {}; - Object.assign(config, data); + const config = this.getNsConfigDefaultObject(data); return JSON.stringify(config); } diff --git a/lib/services/workflow-service.ts b/lib/services/workflow-service.ts new file mode 100644 index 0000000000..bc3a023b72 --- /dev/null +++ b/lib/services/workflow-service.ts @@ -0,0 +1,102 @@ +import * as helpers from "../common/helpers"; +import * as path from "path"; +import * as semver from "semver"; + +export class WorkflowService implements IWorkflowService { + constructor(private $bundleValidatorHelper: IBundleValidatorHelper, + private $fs: IFileSystem, + private $logger: ILogger, + private $packageManager: INodePackageManager, + private $projectDataService: IProjectDataService, + private $prompter: IPrompter, + private $options: IOptions + ) { + } + + public async handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, force?: boolean): Promise { + if (!settings.bundle || force) { + const projectData = this.$projectDataService.getProjectData(projectDir); + if (projectData.useLegacyWorkflow === null || projectData.useLegacyWorkflow === undefined || force) { + const hasSwitched = await this.handleWebpackWorkflowSwitch(projectData, force); + if (hasSwitched) { + this.$options.bundle = "webpack"; + this.$options.hmr = !settings.release; + if (typeof (settings.bundle) === "boolean") { + settings.bundle = true; + } else { + settings.bundle = this.$options.bundle; + } + settings.useHotModuleReload = this.$options.hmr; + } + } else if (projectData.useLegacyWorkflow === true) { + this.showLegacyWorkflowWarning(); + } else { + this.showNoBundleWarning(); + } + } + } + + private async handleWebpackWorkflowSwitch(projectData: IProjectData, force: boolean): Promise { + let hasSwitched = false; + if (force || helpers.isInteractive()) { + hasSwitched = force || await this.$prompter.confirm("Please use webpack!", () => true); + if (hasSwitched) { + this.$projectDataService.setUseLegacyWorkflow(projectData.projectDir, false); + await this.ensureWebpackPluginInstalled(projectData); + } else { + this.$projectDataService.setUseLegacyWorkflow(projectData.projectDir, true); + await this.showLegacyWorkflowWarning(); + } + } else { + await this.showLegacyWorkflowWarning(); + } + + return hasSwitched; + } + + private async showLegacyWorkflowWarning() { + this.$logger.warn("WARNINGGGGG LEGACY TRUE!!!"); + } + + private showNoBundleWarning() { + this.$logger.warn("WARNINGGGGG NO BUNDLE!!!"); + } + + private async ensureWebpackPluginInstalled(projectData: IProjectData) { + const hmrOutOfBetaWebpackPluginVersion = "0.21.0"; + const webpackPluginName = "nativescript-dev-webpack"; + const webpackConfigFileName = "webpack.config.js"; + const validWebpackPluginTags = ["*", "latest", "next", "rc"]; + + let isInstalledVersionSupported = true; + const installedVersion = this.$bundleValidatorHelper.getBundlerDependencyVersion(webpackPluginName); + // TODO: use trace + this.$logger.info(`Updating to webpack workflow: Found ${webpackPluginName} v${installedVersion}`); + if (validWebpackPluginTags.indexOf(installedVersion) === -1) { + const isInstalledVersionValid = !!semver.valid(installedVersion) || !!semver.coerce(installedVersion); + isInstalledVersionSupported = + isInstalledVersionValid && semver.gte(semver.coerce(installedVersion), hmrOutOfBetaWebpackPluginVersion); + this.$logger.info(`Updating to webpack workflow: Is installedVersion valid: ${isInstalledVersionValid}`); + } + + this.$logger.info(`Updating to webpack workflow: Is installedVersion supported: ${isInstalledVersionSupported}`); + if (!isInstalledVersionSupported) { + const webpackConfigPath = path.join(projectData.projectDir, webpackConfigFileName); + if (this.$fs.exists(webpackConfigPath)) { + this.$logger.info(`Your Webpack config was stored to .bak!!`); + this.$fs.rename(webpackConfigPath, `${webpackConfigPath}.bak`); + } + + const installResult = await this.$packageManager.install(`${webpackPluginName}@latest`, projectData.projectDir, { + 'save-dev': true, + 'save-exact': true, + disableNpmInstall: false, + frameworkPath: null, + ignoreScripts: false, + }); + this.$logger.info(`Updating to webpack workflow: The ${webpackPluginName} was updated to v${installResult.version}`); + } + } +} + +$injector.register("workflowService", WorkflowService); diff --git a/test/stubs.ts b/test/stubs.ts index 828fcc1646..1f775f69f8 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -497,6 +497,9 @@ export class PlatformsDataStub extends EventEmitter implements IPlatformsData { } export class ProjectDataService implements IProjectDataService { + setUseLegacyWorkflow(projectDir: string, value: any): Promise { + return; + } getNSValue(propertyName: string): any { return {}; } From dfbc0872c6a3d17984343568904f304ea248156c Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Thu, 18 Apr 2019 11:57:01 +0300 Subject: [PATCH 2/5] fix: recommend the new workflow before executing run/test/debug/prepare/build/preview --- lib/commands/build.ts | 22 +++++++++++-------- lib/commands/debug.ts | 4 +++- lib/commands/prepare.ts | 8 ++++--- lib/commands/preview.ts | 2 +- lib/commands/run.ts | 5 ++++- lib/commands/test.ts | 2 +- lib/definitions/platform.d.ts | 2 +- lib/services/project-data-service.ts | 5 ++--- lib/services/workflow-service.ts | 32 +++++++++++++--------------- 9 files changed, 45 insertions(+), 37 deletions(-) diff --git a/lib/commands/build.ts b/lib/commands/build.ts index 33d7db7639..bdad8cfe02 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -9,12 +9,14 @@ export abstract class BuildCommandBase extends ValidatePlatformCommandBase { protected $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, $platformService: IPlatformService, private $bundleValidatorHelper: IBundleValidatorHelper, - protected $logger: ILogger) { - super($options, $platformsData, $platformService, $projectData); - this.$projectData.initializeProjectData(); + protected $logger: ILogger, + protected $workflowService: IWorkflowService) { + super($options, $platformsData, $platformService, $projectData); + this.$projectData.initializeProjectData(); } public async executeCore(args: string[]): Promise { + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); const platform = args[0].toLowerCase(); const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: !!this.$options.bundle, @@ -94,8 +96,9 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, $platformService: IPlatformService, $bundleValidatorHelper: IBundleValidatorHelper, - $logger: ILogger) { - super($options, $errors, $projectData, $platformsData, $devicePlatformsConstants, $platformService, $bundleValidatorHelper, $logger); + $logger: ILogger, + $workflowService: IWorkflowService) { + super($options, $errors, $projectData, $platformsData, $devicePlatformsConstants, $platformService, $bundleValidatorHelper, $logger, $workflowService); } public async execute(args: string[]): Promise { @@ -107,7 +110,7 @@ export class BuildIosCommand extends BuildCommandBase implements ICommand { super.validatePlatform(platform); - let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true }}); + let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true } }); if (result.canExecute) { result = await super.validateArgs(args, platform); } @@ -129,8 +132,9 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { $platformService: IPlatformService, $bundleValidatorHelper: IBundleValidatorHelper, protected $androidBundleValidatorHelper: IAndroidBundleValidatorHelper, - protected $logger: ILogger) { - super($options, $errors, $projectData, $platformsData, $devicePlatformsConstants, $platformService, $bundleValidatorHelper, $logger); + protected $logger: ILogger, + $workflowService: IWorkflowService) { + super($options, $errors, $projectData, $platformsData, $devicePlatformsConstants, $platformService, $bundleValidatorHelper, $logger, $workflowService); } public async execute(args: string[]): Promise { @@ -149,7 +153,7 @@ export class BuildAndroidCommand extends BuildCommandBase implements ICommand { const platform = this.$devicePlatformsConstants.Android; super.validatePlatform(platform); this.$androidBundleValidatorHelper.validateRuntimeVersion(this.$projectData); - let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true }}); + let result = await super.canExecuteCommandBase(platform, { notConfiguredEnvOptions: { hideSyncToPreviewAppOption: true } }); if (result.canExecute) { if (this.$options.release && (!this.$options.keyStorePath || !this.$options.keyStorePassword || !this.$options.keyStoreAlias || !this.$options.keyStoreAliasPassword)) { this.$errors.fail(ANDROID_RELEASE_BUILD_ERROR_MESSAGE); diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts index ab62e8ac56..f53a40bc2a 100644 --- a/lib/commands/debug.ts +++ b/lib/commands/debug.ts @@ -18,11 +18,13 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements private $debugDataService: IDebugDataService, private $liveSyncService: IDebugLiveSyncService, private $liveSyncCommandHelper: ILiveSyncCommandHelper, - private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper) { + private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper, + private $workflowService: IWorkflowService) { super($options, $platformsData, $platformService, $projectData); } public async execute(args: string[]): Promise { + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); await this.$devicesService.initialize({ platform: this.platform, deviceId: this.$options.device, diff --git a/lib/commands/prepare.ts b/lib/commands/prepare.ts index 409ddf16c6..91e8734411 100644 --- a/lib/commands/prepare.ts +++ b/lib/commands/prepare.ts @@ -7,12 +7,14 @@ export class PrepareCommand extends ValidatePlatformCommandBase implements IComm $platformService: IPlatformService, $projectData: IProjectData, private $platformCommandParameter: ICommandParameter, - $platformsData: IPlatformsData) { - super($options, $platformsData, $platformService, $projectData); - this.$projectData.initializeProjectData(); + $platformsData: IPlatformsData, + private $workflowService: IWorkflowService) { + super($options, $platformsData, $platformService, $projectData); + this.$projectData.initializeProjectData(); } public async execute(args: string[]): Promise { + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: !!this.$options.bundle, release: this.$options.release, diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index 4a77d6a294..47520544b0 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -21,7 +21,7 @@ export class PreviewCommand implements ICommand { } public async execute(): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options); + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); this.$previewAppLogProvider.on(DEVICE_LOG_EVENT_NAME, (deviceId: string, message: string) => { this.$logger.info(message); }); diff --git a/lib/commands/run.ts b/lib/commands/run.ts index 2e87e58376..af0846f9e2 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -13,10 +13,13 @@ export class RunCommandBase implements ICommand { private $errors: IErrors, private $hostInfo: IHostInfo, private $liveSyncCommandHelper: ILiveSyncCommandHelper, - private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper) { } + private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper, + private $options: IOptions, + private $workflowService: IWorkflowService) { } public allowedParameters: ICommandParameter[] = []; public async execute(args: string[]): Promise { + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); await this.$analyticsService.trackPreviewAppData(this.platform, this.$projectData.projectDir); return this.$liveSyncCommandHelper.executeCommandLiveSync(this.platform, this.liveSyncCommandHelperAdditionalOptions); } diff --git a/lib/commands/test.ts b/lib/commands/test.ts index f855972076..50b4e3a110 100644 --- a/lib/commands/test.ts +++ b/lib/commands/test.ts @@ -14,7 +14,7 @@ abstract class TestCommandBase { protected abstract $workflowService: IWorkflowService; async execute(args: string[]): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options); + await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); await this.$testExecutionService.startKarmaServer(this.platform, this.$projectData, this.projectFilesConfig); } diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts index e9f29a99c8..c1a1973bed 100644 --- a/lib/definitions/platform.d.ts +++ b/lib/definitions/platform.d.ts @@ -15,7 +15,7 @@ interface IBuildPlatformAction { } interface IWorkflowService { - handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, force?: boolean): Promise; + handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, skipWarnings?: boolean, force?: boolean): Promise; } interface IWebpackWorkflowSettings { diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 34e5f3e389..2a22bf4f98 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -137,11 +137,10 @@ export class ProjectDataService implements IProjectDataService { } public setUseLegacyWorkflow(projectDir: string, value: any): void { - // TODO: use trace - this.$logger.info(`useLegacyWorkflow will be set to ${value}`); + this.$logger.trace(`useLegacyWorkflow will be set to ${value}`); this.updateNsConfigValue(projectDir, { useLegacyWorkflow: value }); this.refreshProjectData(projectDir); - this.$logger.info(`useLegacyWorkflow was set to ${value}`); + this.$logger.trace(`useLegacyWorkflow was set to ${value}`); } public getAppExecutableFiles(projectDir: string): string[] { diff --git a/lib/services/workflow-service.ts b/lib/services/workflow-service.ts index bc3a023b72..680bf6d7c0 100644 --- a/lib/services/workflow-service.ts +++ b/lib/services/workflow-service.ts @@ -13,11 +13,11 @@ export class WorkflowService implements IWorkflowService { ) { } - public async handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, force?: boolean): Promise { + public async handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, skipWarnings?: boolean, force?: boolean): Promise { if (!settings.bundle || force) { const projectData = this.$projectDataService.getProjectData(projectDir); - if (projectData.useLegacyWorkflow === null || projectData.useLegacyWorkflow === undefined || force) { - const hasSwitched = await this.handleWebpackWorkflowSwitch(projectData, force); + if (typeof (projectData.useLegacyWorkflow) !== "boolean" || force) { + const hasSwitched = await this.handleWebpackWorkflowSwitch(projectData, skipWarnings, force); if (hasSwitched) { this.$options.bundle = "webpack"; this.$options.hmr = !settings.release; @@ -28,15 +28,15 @@ export class WorkflowService implements IWorkflowService { } settings.useHotModuleReload = this.$options.hmr; } - } else if (projectData.useLegacyWorkflow === true) { + } else if (!skipWarnings && projectData.useLegacyWorkflow === true) { this.showLegacyWorkflowWarning(); - } else { + } else if (!skipWarnings && projectData.useLegacyWorkflow === false) { this.showNoBundleWarning(); } } } - private async handleWebpackWorkflowSwitch(projectData: IProjectData, force: boolean): Promise { + private async handleWebpackWorkflowSwitch(projectData: IProjectData, skipWarnings: boolean, force: boolean): Promise { let hasSwitched = false; if (force || helpers.isInteractive()) { hasSwitched = force || await this.$prompter.confirm("Please use webpack!", () => true); @@ -45,21 +45,20 @@ export class WorkflowService implements IWorkflowService { await this.ensureWebpackPluginInstalled(projectData); } else { this.$projectDataService.setUseLegacyWorkflow(projectData.projectDir, true); - await this.showLegacyWorkflowWarning(); } - } else { + } else if (!skipWarnings) { await this.showLegacyWorkflowWarning(); } return hasSwitched; } - private async showLegacyWorkflowWarning() { - this.$logger.warn("WARNINGGGGG LEGACY TRUE!!!"); + private showLegacyWorkflowWarning() { + this.$logger.warn("TODO: "); } private showNoBundleWarning() { - this.$logger.warn("WARNINGGGGG NO BUNDLE!!!"); + this.$logger.warn("TODO: "); } private async ensureWebpackPluginInstalled(projectData: IProjectData) { @@ -70,20 +69,19 @@ export class WorkflowService implements IWorkflowService { let isInstalledVersionSupported = true; const installedVersion = this.$bundleValidatorHelper.getBundlerDependencyVersion(webpackPluginName); - // TODO: use trace - this.$logger.info(`Updating to webpack workflow: Found ${webpackPluginName} v${installedVersion}`); + this.$logger.trace(`Updating to webpack workflow: Found ${webpackPluginName} v${installedVersion}`); if (validWebpackPluginTags.indexOf(installedVersion) === -1) { const isInstalledVersionValid = !!semver.valid(installedVersion) || !!semver.coerce(installedVersion); isInstalledVersionSupported = isInstalledVersionValid && semver.gte(semver.coerce(installedVersion), hmrOutOfBetaWebpackPluginVersion); - this.$logger.info(`Updating to webpack workflow: Is installedVersion valid: ${isInstalledVersionValid}`); + this.$logger.trace(`Updating to webpack workflow: Is installed version valid?: ${isInstalledVersionValid}`); } - this.$logger.info(`Updating to webpack workflow: Is installedVersion supported: ${isInstalledVersionSupported}`); + this.$logger.trace(`Updating to webpack workflow: Is installed version supported?: ${isInstalledVersionSupported}`); if (!isInstalledVersionSupported) { const webpackConfigPath = path.join(projectData.projectDir, webpackConfigFileName); if (this.$fs.exists(webpackConfigPath)) { - this.$logger.info(`Your Webpack config was stored to .bak!!`); + this.$logger.info(``); this.$fs.rename(webpackConfigPath, `${webpackConfigPath}.bak`); } @@ -94,7 +92,7 @@ export class WorkflowService implements IWorkflowService { frameworkPath: null, ignoreScripts: false, }); - this.$logger.info(`Updating to webpack workflow: The ${webpackPluginName} was updated to v${installResult.version}`); + this.$logger.trace(`Updating to webpack workflow: The ${webpackPluginName} was updated to v${installResult.version}`); } } } From ace53e535bdc33db6ddf839bfb2f2857bbfef588 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Fri, 19 Apr 2019 10:35:47 +0300 Subject: [PATCH 3/5] fix: handle CLI usage as a library --- lib/commands/build.ts | 2 +- lib/commands/debug.ts | 2 +- lib/commands/deploy.ts | 6 +++--- lib/commands/preview.ts | 2 +- lib/declarations.d.ts | 4 ++-- lib/helpers/bundle-validator-helper.ts | 14 ++++++------- lib/helpers/livesync-command-helper.ts | 2 +- lib/services/project-data-service.ts | 18 +++++++++------- lib/services/workflow-service.ts | 2 +- test/debug.ts | 1 + test/helpers/bundle-validator-helper.ts | 21 ++++++++++--------- test/package-installation-manager.ts | 3 +++ test/platform-commands.ts | 2 ++ test/platform-service.ts | 1 + .../preview-app-livesync-service.ts | 3 ++- test/services/project-data-service.ts | 4 +++- test/stubs.ts | 7 +++++++ test/update.ts | 13 ++++++------ 18 files changed, 64 insertions(+), 43 deletions(-) diff --git a/lib/commands/build.ts b/lib/commands/build.ts index bdad8cfe02..a748b2d2d3 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -65,7 +65,7 @@ export abstract class BuildCommandBase extends ValidatePlatformCommandBase { this.$errors.fail(`Applications for platform ${platform} can not be built on this OS`); } - this.$bundleValidatorHelper.validate(); + this.$bundleValidatorHelper.validate(this.$projectData); } protected async validateArgs(args: string[], platform: string): Promise { diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts index f53a40bc2a..1ce3e40830 100644 --- a/lib/commands/debug.ts +++ b/lib/commands/debug.ts @@ -69,7 +69,7 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements } const minSupportedWebpackVersion = this.$options.hmr ? LiveSyncCommandHelper.MIN_SUPPORTED_WEBPACK_VERSION_WITH_HMR : null; - this.$bundleValidatorHelper.validate(minSupportedWebpackVersion); + 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 c83b357ca0..ad6fffc62b 100644 --- a/lib/commands/deploy.ts +++ b/lib/commands/deploy.ts @@ -14,8 +14,8 @@ export class DeployOnDeviceCommand extends ValidatePlatformCommandBase implement $platformsData: IPlatformsData, private $bundleValidatorHelper: IBundleValidatorHelper, private $androidBundleValidatorHelper: IAndroidBundleValidatorHelper) { - super($options, $platformsData, $platformService, $projectData); - this.$projectData.initializeProjectData(); + super($options, $platformsData, $platformService, $projectData); + this.$projectData.initializeProjectData(); } public async execute(args: string[]): Promise { @@ -26,7 +26,7 @@ export class DeployOnDeviceCommand extends ValidatePlatformCommandBase implement public async canExecute(args: string[]): Promise { this.$androidBundleValidatorHelper.validateNoAab(); - this.$bundleValidatorHelper.validate(); + 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 47520544b0..7e03dc87a8 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -46,7 +46,7 @@ export class PreviewCommand implements ICommand { } await this.$networkConnectivityValidator.validate(); - this.$bundleValidatorHelper.validate(PreviewCommand.MIN_SUPPORTED_WEBPACK_VERSION); + this.$bundleValidatorHelper.validate(this.$projectData, PreviewCommand.MIN_SUPPORTED_WEBPACK_VERSION); return true; } } diff --git a/lib/declarations.d.ts b/lib/declarations.d.ts index aef6e0fd86..3c2458cba6 100644 --- a/lib/declarations.d.ts +++ b/lib/declarations.d.ts @@ -940,13 +940,13 @@ interface IBundleValidatorHelper { * @param {string} minSupportedVersion the minimum supported version of nativescript-dev-webpack * @return {void} */ - validate(minSupportedVersion?: string): void; + validate(projectData: IProjectData, minSupportedVersion?: string): void; /** * Returns the installed bundler version. * @return {string} */ - getBundlerDependencyVersion(bundlerName?: string): string; + getBundlerDependencyVersion(projectData: IProjectData, bundlerName?: string): string; } diff --git a/lib/helpers/bundle-validator-helper.ts b/lib/helpers/bundle-validator-helper.ts index 2caf345a16..d5d8e6de0d 100644 --- a/lib/helpers/bundle-validator-helper.ts +++ b/lib/helpers/bundle-validator-helper.ts @@ -7,16 +7,14 @@ export class BundleValidatorHelper extends VersionValidatorHelper implements IBu webpack: "nativescript-dev-webpack" }; - constructor(protected $projectData: IProjectData, - protected $errors: IErrors, + constructor(protected $errors: IErrors, protected $options: IOptions) { super(); - this.$projectData.initializeProjectData(); } - public validate(minSupportedVersion?: string): void { + public validate(projectData: IProjectData, minSupportedVersion?: string): void { if (this.$options.bundle) { - const currentVersion = this.getBundlerDependencyVersion(); + const currentVersion = this.getBundlerDependencyVersion(projectData); if (!currentVersion) { this.$errors.failWithoutHelp(BundleValidatorMessages.MissingBundlePlugin); } @@ -28,11 +26,11 @@ export class BundleValidatorHelper extends VersionValidatorHelper implements IBu } } - public getBundlerDependencyVersion(bundlerName?: string): string { + public getBundlerDependencyVersion(projectData: IProjectData, bundlerName?: string): string { let dependencyVersion = null; const bundlePluginName = bundlerName || this.bundlersMap[this.$options.bundle]; - const bundlerVersionInDependencies = this.$projectData.dependencies && this.$projectData.dependencies[bundlePluginName]; - const bundlerVersionInDevDependencies = this.$projectData.devDependencies && this.$projectData.devDependencies[bundlePluginName]; + const bundlerVersionInDependencies = projectData.dependencies && projectData.dependencies[bundlePluginName]; + const bundlerVersionInDevDependencies = projectData.devDependencies && projectData.devDependencies[bundlePluginName]; dependencyVersion = bundlerVersionInDependencies || bundlerVersionInDevDependencies; return dependencyVersion; diff --git a/lib/helpers/livesync-command-helper.ts b/lib/helpers/livesync-command-helper.ts index 8b5c648298..2760220cdb 100644 --- a/lib/helpers/livesync-command-helper.ts +++ b/lib/helpers/livesync-command-helper.ts @@ -152,7 +152,7 @@ export class LiveSyncCommandHelper implements ILiveSyncCommandHelper { } const minSupportedWebpackVersion = this.$options.hmr ? LiveSyncCommandHelper.MIN_SUPPORTED_WEBPACK_VERSION_WITH_HMR : null; - this.$bundleValidatorHelper.validate(minSupportedWebpackVersion); + this.$bundleValidatorHelper.validate(this.$projectData, minSupportedWebpackVersion); return result; } diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 2a22bf4f98..4d1544bf13 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -19,7 +19,7 @@ interface IProjectFileData { } export class ProjectDataService implements IProjectDataService { - private defaultProjectDir = ""; + private defaultProjectDir: string; private static DEPENDENCIES_KEY_NAME = "dependencies"; private projectDataCache: IDictionary = {}; @@ -28,12 +28,16 @@ export class ProjectDataService implements IProjectDataService { private $logger: ILogger, private $devicePlatformsConstants: Mobile.IDevicePlatformsConstants, private $androidResourcesMigrationService: IAndroidResourcesMigrationService, - private $injector: IInjector, - $projectData: IProjectData) { - // add the ProjectData of the default projectDir to the projectData cache - $projectData.initializeProjectData(); - this.defaultProjectDir = $projectData.projectDir; - this.projectDataCache[this.defaultProjectDir] = $projectData; + private $injector: IInjector) { + try { + // add the ProjectData of the default projectDir to the projectData cache + const projectData = this.$injector.resolve("projectData"); + projectData.initializeProjectData(); + this.defaultProjectDir = projectData.projectDir; + this.projectDataCache[this.defaultProjectDir] = projectData; + } catch (e) { + // the CLI is required as a lib from a non-project folder + } } public getNSValue(projectDir: string, propertyName: string): any { diff --git a/lib/services/workflow-service.ts b/lib/services/workflow-service.ts index 680bf6d7c0..5b5490ef56 100644 --- a/lib/services/workflow-service.ts +++ b/lib/services/workflow-service.ts @@ -68,7 +68,7 @@ export class WorkflowService implements IWorkflowService { const validWebpackPluginTags = ["*", "latest", "next", "rc"]; let isInstalledVersionSupported = true; - const installedVersion = this.$bundleValidatorHelper.getBundlerDependencyVersion(webpackPluginName); + const installedVersion = this.$bundleValidatorHelper.getBundlerDependencyVersion(projectData, webpackPluginName); this.$logger.trace(`Updating to webpack workflow: Found ${webpackPluginName} v${installedVersion}`); if (validWebpackPluginTags.indexOf(installedVersion) === -1) { const isInstalledVersionValid = !!semver.valid(installedVersion) || !!semver.coerce(installedVersion); diff --git a/test/debug.ts b/test/debug.ts index a3de9409d4..e41315dacc 100644 --- a/test/debug.ts +++ b/test/debug.ts @@ -15,6 +15,7 @@ import { SettingsService } from "../lib/common/test/unit-tests/stubs"; function createTestInjector(): IInjector { const testInjector: IInjector = new yok.Yok(); + testInjector.register("workflowService", stubs.WorkflowServiceStub); testInjector.register("debug|android", DebugAndroidCommand); testInjector.register("config", Configuration); testInjector.register("staticConfig", StaticConfig); diff --git a/test/helpers/bundle-validator-helper.ts b/test/helpers/bundle-validator-helper.ts index 2edd2568b2..3feee9c4c2 100644 --- a/test/helpers/bundle-validator-helper.ts +++ b/test/helpers/bundle-validator-helper.ts @@ -90,17 +90,18 @@ describe("BundleValidatorHelper", () => { ]); }); - _.each(testCases, (testCase: any) => { - const deps = { - "nativescript-dev-webpack": testCase.currentWebpackVersion - }; + _.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"); - bundleValidatorHelper.validate(testCase.minSupportedWebpackVersion); + 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); - }); + assert.deepEqual(error, testCase.expectedError); }); + }); }); diff --git a/test/package-installation-manager.ts b/test/package-installation-manager.ts index fa35296680..bec00a5ff7 100644 --- a/test/package-installation-manager.ts +++ b/test/package-installation-manager.ts @@ -14,10 +14,13 @@ import * as yok from "../lib/common/yok"; import ChildProcessLib = require("../lib/common/child-process"); import { SettingsService } from "../lib/common/test/unit-tests/stubs"; import { ProjectDataService } from "../lib/services/project-data-service"; +import { WorkflowServiceStub, ProjectDataStub } from "./stubs"; function createTestInjector(): IInjector { const testInjector = new yok.Yok(); + testInjector.register("workflowService", WorkflowServiceStub); + testInjector.register("projectData", ProjectDataStub); testInjector.register("config", ConfigLib.Configuration); testInjector.register("logger", LoggerLib.Logger); testInjector.register("errors", ErrorsLib.Errors); diff --git a/test/platform-commands.ts b/test/platform-commands.ts index 5bba06ea46..9b593a1b73 100644 --- a/test/platform-commands.ts +++ b/test/platform-commands.ts @@ -20,6 +20,7 @@ import * as ChildProcessLib from "../lib/common/child-process"; import ProjectChangesLib = require("../lib/services/project-changes-service"); import { Messages } from "../lib/common/messages/messages"; import { SettingsService } from "../lib/common/test/unit-tests/stubs"; +import { WorkflowServiceStub } from "./stubs"; let isCommandExecuted = true; @@ -97,6 +98,7 @@ function createTestInjector() { const testInjector = new yok.Yok(); testInjector.register("injector", testInjector); + testInjector.register("workflowService", WorkflowServiceStub); testInjector.register("hooksService", stubs.HooksServiceStub); testInjector.register("staticConfig", StaticConfigLib.StaticConfig); testInjector.register("nodeModulesDependenciesBuilder", {}); diff --git a/test/platform-service.ts b/test/platform-service.ts index 1f61e9fc77..e7039b33f1 100644 --- a/test/platform-service.ts +++ b/test/platform-service.ts @@ -32,6 +32,7 @@ temp.track(); function createTestInjector() { const testInjector = new yok.Yok(); + testInjector.register("workflowService", stubs.WorkflowServiceStub); testInjector.register('platformService', PlatformServiceLib.PlatformService); testInjector.register('errors', stubs.ErrorsStub); testInjector.register('logger', stubs.LoggerStub); diff --git a/test/services/playground/preview-app-livesync-service.ts b/test/services/playground/preview-app-livesync-service.ts index 4706a00439..8eab7ee01e 100644 --- a/test/services/playground/preview-app-livesync-service.ts +++ b/test/services/playground/preview-app-livesync-service.ts @@ -1,6 +1,6 @@ import { Yok } from "../../../lib/common/yok"; import * as _ from 'lodash'; -import { LoggerStub, ErrorsStub } from "../../stubs"; +import { LoggerStub, ErrorsStub, WorkflowServiceStub } from "../../stubs"; import { FilePayload, Device, FilesPayload } from "nativescript-preview-sdk"; import { PreviewAppLiveSyncService } from "../../../lib/services/livesync/playground/preview-app-livesync-service"; import * as chai from "chai"; @@ -101,6 +101,7 @@ function createTestInjector(options?: { options = options || {}; const injector = new Yok(); + injector.register("workflowService", WorkflowServiceStub); injector.register("logger", LoggerMock); injector.register("hmrStatusService", {}); injector.register("errors", ErrorsStub); diff --git a/test/services/project-data-service.ts b/test/services/project-data-service.ts index 414276b1e8..72f1db2b95 100644 --- a/test/services/project-data-service.ts +++ b/test/services/project-data-service.ts @@ -1,7 +1,7 @@ import { Yok } from "../../lib/common/yok"; import { assert } from "chai"; import { ProjectDataService } from "../../lib/services/project-data-service"; -import { LoggerStub } from "../stubs"; +import { LoggerStub, WorkflowServiceStub, ProjectDataStub } from "../stubs"; import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER, PACKAGE_JSON_FILE_NAME, AssetConstants, ProjectTypes } from '../../lib/constants'; import { DevicePlatformsConstants } from "../../lib/common/mobile/device-platforms-constants"; import { basename, join } from "path"; @@ -43,6 +43,8 @@ const testData: any = [ const createTestInjector = (readTextData?: string): IInjector => { const testInjector = new Yok(); + testInjector.register("workflowService", WorkflowServiceStub); + testInjector.register("projectData", ProjectDataStub); testInjector.register("staticConfig", { CLIENT_NAME_KEY_IN_PROJECT_FILE: CLIENT_NAME_KEY_IN_PROJECT_FILE, PROJECT_FILE_NAME: "package.json" diff --git a/test/stubs.ts b/test/stubs.ts index 1f775f69f8..da6e615e55 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -916,6 +916,12 @@ export class PerformanceService implements IPerformanceService { processExecutionData() { } } +export class WorkflowServiceStub implements IWorkflowService { + handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, skipWarnings?: boolean, force?: boolean): Promise { + return; + } +} + export class InjectorStub extends Yok implements IInjector { constructor() { super(); @@ -954,5 +960,6 @@ export class InjectorStub extends Yok implements IInjector { getDevice: (): Mobile.IDevice => undefined, getDeviceByIdentifier: (): Mobile.IDevice => undefined }); + this.register("workflowService", WorkflowServiceStub); } } diff --git a/test/update.ts b/test/update.ts index 65b162c48a..f6a2052017 100644 --- a/test/update.ts +++ b/test/update.ts @@ -25,6 +25,7 @@ function createTestInjector( ): IInjector { const testInjector: IInjector = new yok.Yok(); testInjector.register("logger", stubs.LoggerStub); + testInjector.register("workflowService", stubs.WorkflowServiceStub); testInjector.register("options", Options); testInjector.register('fs', stubs.FileSystemStub); testInjector.register("analyticsService", { @@ -49,10 +50,10 @@ function createTestInjector( }); testInjector.register("pluginVariablesService", {}); testInjector.register("platformService", { - getInstalledPlatforms: function(): string[] { + getInstalledPlatforms: function (): string[] { return installedPlatforms; }, - getAvailablePlatforms: function(): string[] { + getAvailablePlatforms: function (): string[] { return availablePlatforms; }, removePlatforms: async (): Promise => undefined, @@ -66,9 +67,9 @@ function createTestInjector( getPlatformData: () => { return { platformProjectService: { - validate - } - }; + validate + } + }; } }); testInjector.register("settingsService", SettingsService); @@ -161,7 +162,7 @@ describe("update command method tests", () => { const fs = testInjector.resolve("fs"); const copyFileStub = sandbox.stub(fs, "copyFile"); const updateCommand = testInjector.resolve(UpdateCommand); - return updateCommand.execute(["3.3.0"]).then( () => { + return updateCommand.execute(["3.3.0"]).then(() => { assert.isTrue(copyFileStub.calledWith(path.join(projectFolder, "package.json"))); for (const folder of UpdateCommand.folders) { assert.isTrue(copyFileStub.calledWith(path.join(projectFolder, folder))); From f2d59a7e2d967122809b483be1e057cba7f519e8 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Fri, 19 Apr 2019 16:33:08 +0300 Subject: [PATCH 4/5] fix: add the initial version of the Legacy Workflow warnings and recommendations --- lib/common/helpers.ts | 25 +++++++++++++++++++++++++ lib/services/workflow-service.ts | 30 +++++++++++++++++++++++++----- 2 files changed, 50 insertions(+), 5 deletions(-) diff --git a/lib/common/helpers.ts b/lib/common/helpers.ts index f3c22b4430..9d188e2a36 100644 --- a/lib/common/helpers.ts +++ b/lib/common/helpers.ts @@ -384,6 +384,31 @@ export function createTable(headers: string[], data: string[][]): any { return table; } +export function getMessageWithBorders(message: string, spanLength = 3): string { + const longestRowLength = message.split(EOL).sort(function (a, b) { return b.length - a.length; })[0].length; + let border = "*".repeat(longestRowLength + 2 * spanLength); // * 2 for both sides + if (border.length % 2 === 0) { + border += "*"; // the * should always be an odd number in order to get * in each edge (we will remove the even *s below) + } + border = border.replace(/\*\*/g, "* "); // ***** => * * * in order to have similar padding to the side borders + const formatRow = function (row: string) { + return _.padEnd("*", spanLength) + _.padEnd(row, border.length - (2 * spanLength)) + _.padStart("*", spanLength) + EOL; + }; + const emptyRow = formatRow(""); + + const messageWithBorders = []; + messageWithBorders.push( + EOL, + border + EOL, + emptyRow, + ...message.split(EOL).map(row => formatRow(row)), + emptyRow, + border + EOL, + EOL + ); + return messageWithBorders.join(""); +} + export function remove(array: T[], predicate: (element: T) => boolean, numberOfElements?: number): T[] { numberOfElements = numberOfElements || 1; const index = _.findIndex(array, predicate); diff --git a/lib/services/workflow-service.ts b/lib/services/workflow-service.ts index 5b5490ef56..5cd4082b7e 100644 --- a/lib/services/workflow-service.ts +++ b/lib/services/workflow-service.ts @@ -1,8 +1,14 @@ import * as helpers from "../common/helpers"; import * as path from "path"; import * as semver from "semver"; +import { EOL } from "os"; export class WorkflowService implements IWorkflowService { + private legacyWorkflowDeprecationMessage = `With the upcoming NativeScript 6.0 the Webpack workflow will become the only way of build apps. +More info about the reason for this change and how to migrate your project can be found in the link below: +`; + private webpackWorkflowConfirmMessage = `Do you want to switch your app to the Webpack workflow?`; + constructor(private $bundleValidatorHelper: IBundleValidatorHelper, private $fs: IFileSystem, private $logger: ILogger, @@ -37,9 +43,17 @@ export class WorkflowService implements IWorkflowService { } private async handleWebpackWorkflowSwitch(projectData: IProjectData, skipWarnings: boolean, force: boolean): Promise { - let hasSwitched = false; + let hasSwitched = force; if (force || helpers.isInteractive()) { - hasSwitched = force || await this.$prompter.confirm("Please use webpack!", () => true); + if (!force) { + this.$logger.info(); + this.$logger.printMarkdown(` +__Improve your project by switching to the Webpack workflow.__ + +\`${this.legacyWorkflowDeprecationMessage}\``); + hasSwitched = await this.$prompter.confirm(this.webpackWorkflowConfirmMessage, () => true); + } + if (hasSwitched) { this.$projectDataService.setUseLegacyWorkflow(projectData.projectDir, false); await this.ensureWebpackPluginInstalled(projectData); @@ -54,11 +68,17 @@ export class WorkflowService implements IWorkflowService { } private showLegacyWorkflowWarning() { - this.$logger.warn("TODO: "); + const legacyWorkflowWarning = `You are using the Legacy Workflow.${EOL}${EOL}${this.legacyWorkflowDeprecationMessage}`; + const warningWithBorders = helpers.getMessageWithBorders(legacyWorkflowWarning); + + this.$logger.warn(warningWithBorders); } private showNoBundleWarning() { - this.$logger.warn("TODO: "); + const legacyWorkflowWarning = `You are using the '--no-bundle' flag which is switching to the Legacy Workflow.${EOL}${EOL}${this.legacyWorkflowDeprecationMessage}`; + const warningWithBorders = helpers.getMessageWithBorders(legacyWorkflowWarning); + + this.$logger.warn(warningWithBorders); } private async ensureWebpackPluginInstalled(projectData: IProjectData) { @@ -81,8 +101,8 @@ export class WorkflowService implements IWorkflowService { if (!isInstalledVersionSupported) { const webpackConfigPath = path.join(projectData.projectDir, webpackConfigFileName); if (this.$fs.exists(webpackConfigPath)) { - this.$logger.info(``); this.$fs.rename(webpackConfigPath, `${webpackConfigPath}.bak`); + this.$logger.warn(`The 'nativescript-dev-webpack' plugin was updated and your '${webpackConfigFileName}' was replaced. You can find your old '${webpackConfigPath}' in '${webpackConfigPath}.bak'.`); } const installResult = await this.$packageManager.install(`${webpackPluginName}@latest`, projectData.projectDir, { From f9be51d0fce6b1f7fed7ef6147ebda9a126dd584 Mon Sep 17 00:00:00 2001 From: DimitarTachev Date: Tue, 23 Apr 2019 10:46:24 +0300 Subject: [PATCH 5/5] chore: fix PR comments --- lib/commands/build.ts | 2 +- lib/commands/debug.ts | 2 +- lib/commands/prepare.ts | 2 +- lib/commands/preview.ts | 2 +- lib/commands/run.ts | 2 +- lib/commands/test.ts | 2 +- lib/commands/update.ts | 3 +-- lib/common/helpers.ts | 6 +++++- lib/definitions/platform.d.ts | 9 ++++++++- .../livesync/playground/preview-app-livesync-service.ts | 2 +- lib/services/platform-service.ts | 2 +- lib/services/project-data-service.ts | 4 +--- lib/services/workflow-service.ts | 7 ++++--- test/stubs.ts | 2 +- 14 files changed, 28 insertions(+), 19 deletions(-) diff --git a/lib/commands/build.ts b/lib/commands/build.ts index a748b2d2d3..79ba67eeff 100644 --- a/lib/commands/build.ts +++ b/lib/commands/build.ts @@ -16,7 +16,7 @@ export abstract class BuildCommandBase extends ValidatePlatformCommandBase { } public async executeCore(args: string[]): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); + await this.$workflowService.handleLegacyWorkflow({ projectDir: this.$projectData.projectDir, settings: this.$options, skipWarnings: true }); const platform = args[0].toLowerCase(); const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: !!this.$options.bundle, diff --git a/lib/commands/debug.ts b/lib/commands/debug.ts index 1ce3e40830..734b546b5b 100644 --- a/lib/commands/debug.ts +++ b/lib/commands/debug.ts @@ -24,7 +24,7 @@ export class DebugPlatformCommand extends ValidatePlatformCommandBase implements } public async execute(args: string[]): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); + await this.$workflowService.handleLegacyWorkflow({ projectDir: this.$projectData.projectDir, settings: this.$options, skipWarnings: true }); await this.$devicesService.initialize({ platform: this.platform, deviceId: this.$options.device, diff --git a/lib/commands/prepare.ts b/lib/commands/prepare.ts index 91e8734411..d0f821c808 100644 --- a/lib/commands/prepare.ts +++ b/lib/commands/prepare.ts @@ -14,7 +14,7 @@ export class PrepareCommand extends ValidatePlatformCommandBase implements IComm } public async execute(args: string[]): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); + await this.$workflowService.handleLegacyWorkflow({ projectDir: this.$projectData.projectDir, settings: this.$options, skipWarnings: true }); const appFilesUpdaterOptions: IAppFilesUpdaterOptions = { bundle: !!this.$options.bundle, release: this.$options.release, diff --git a/lib/commands/preview.ts b/lib/commands/preview.ts index 7e03dc87a8..59cf02ad7e 100644 --- a/lib/commands/preview.ts +++ b/lib/commands/preview.ts @@ -21,7 +21,7 @@ export class PreviewCommand implements ICommand { } public async execute(): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); + await this.$workflowService.handleLegacyWorkflow({ projectDir: this.$projectData.projectDir, settings: this.$options, skipWarnings: true }); this.$previewAppLogProvider.on(DEVICE_LOG_EVENT_NAME, (deviceId: string, message: string) => { this.$logger.info(message); }); diff --git a/lib/commands/run.ts b/lib/commands/run.ts index af0846f9e2..cf83c86dd5 100644 --- a/lib/commands/run.ts +++ b/lib/commands/run.ts @@ -19,7 +19,7 @@ export class RunCommandBase implements ICommand { public allowedParameters: ICommandParameter[] = []; public async execute(args: string[]): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); + await this.$workflowService.handleLegacyWorkflow({ projectDir: this.$projectData.projectDir, settings: this.$options, skipWarnings: true }); await this.$analyticsService.trackPreviewAppData(this.platform, this.$projectData.projectDir); return this.$liveSyncCommandHelper.executeCommandLiveSync(this.platform, this.liveSyncCommandHelperAdditionalOptions); } diff --git a/lib/commands/test.ts b/lib/commands/test.ts index 50b4e3a110..51fd1efd64 100644 --- a/lib/commands/test.ts +++ b/lib/commands/test.ts @@ -14,7 +14,7 @@ abstract class TestCommandBase { protected abstract $workflowService: IWorkflowService; async execute(args: string[]): Promise { - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, true); + await this.$workflowService.handleLegacyWorkflow({ projectDir: this.$projectData.projectDir, settings: this.$options, skipWarnings: true }); await this.$testExecutionService.startKarmaServer(this.platform, this.$projectData, this.projectFilesConfig); } diff --git a/lib/commands/update.ts b/lib/commands/update.ts index 07054ac7be..bcdc250e2e 100644 --- a/lib/commands/update.ts +++ b/lib/commands/update.ts @@ -30,8 +30,7 @@ export class UpdateCommand extends ValidatePlatformCommandBase implements IComma public async execute(args: string[]): Promise { if (this.$options.workflow) { - const forceWebpackWorkflow = true; - await this.$workflowService.handleLegacyWorkflow(this.$projectData.projectDir, this.$options, forceWebpackWorkflow); + await this.$workflowService.handleLegacyWorkflow({ projectDir: this.$projectData.projectDir, settings: this.$options, force: true }); return; } diff --git a/lib/common/helpers.ts b/lib/common/helpers.ts index 9d188e2a36..7283ecb764 100644 --- a/lib/common/helpers.ts +++ b/lib/common/helpers.ts @@ -385,7 +385,11 @@ export function createTable(headers: string[], data: string[][]): any { } export function getMessageWithBorders(message: string, spanLength = 3): string { - const longestRowLength = message.split(EOL).sort(function (a, b) { return b.length - a.length; })[0].length; + if (!message) { + return ""; + } + + const longestRowLength = message.split(EOL).sort((a, b) => { return b.length - a.length; })[0].length; let border = "*".repeat(longestRowLength + 2 * spanLength); // * 2 for both sides if (border.length % 2 === 0) { border += "*"; // the * should always be an odd number in order to get * in each edge (we will remove the even *s below) diff --git a/lib/definitions/platform.d.ts b/lib/definitions/platform.d.ts index c1a1973bed..2ded89ea0f 100644 --- a/lib/definitions/platform.d.ts +++ b/lib/definitions/platform.d.ts @@ -15,7 +15,14 @@ interface IBuildPlatformAction { } interface IWorkflowService { - handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, skipWarnings?: boolean, force?: boolean): Promise; + handleLegacyWorkflow(options: IHandleLegacyWorkflowOptions): Promise; +} + +interface IHandleLegacyWorkflowOptions { + projectDir: string; + settings: IWebpackWorkflowSettings; + skipWarnings?: boolean; + force?: boolean; } interface IWebpackWorkflowSettings { diff --git a/lib/services/livesync/playground/preview-app-livesync-service.ts b/lib/services/livesync/playground/preview-app-livesync-service.ts index b7db6b59ba..1b18380916 100644 --- a/lib/services/livesync/playground/preview-app-livesync-service.ts +++ b/lib/services/livesync/playground/preview-app-livesync-service.ts @@ -30,7 +30,7 @@ export class PreviewAppLiveSyncService extends EventEmitter implements IPreviewA @performanceLog() public async initialize(data: IPreviewAppLiveSyncData): Promise { await this.$previewSdkService.initialize(data.projectDir, async (device: Device) => { - await this.$workflowService.handleLegacyWorkflow(data.projectDir, data); + await this.$workflowService.handleLegacyWorkflow({ projectDir: data.projectDir, settings: data }); try { if (!device) { this.$errors.failWithoutHelp("Sending initial preview files without a specified device is not supported."); diff --git a/lib/services/platform-service.ts b/lib/services/platform-service.ts index b5d8a20885..ed8a29c189 100644 --- a/lib/services/platform-service.ts +++ b/lib/services/platform-service.ts @@ -222,7 +222,7 @@ export class PlatformService extends EventEmitter implements IPlatformService { @performanceLog() public async preparePlatform(platformInfo: IPreparePlatformInfo): Promise { - await this.$workflowService.handleLegacyWorkflow(platformInfo.projectData.projectDir, platformInfo.appFilesUpdaterOptions); + await this.$workflowService.handleLegacyWorkflow({ projectDir: platformInfo.projectData.projectDir, settings: platformInfo.appFilesUpdaterOptions }); const changesInfo = await this.getChangesInfo(platformInfo); const shouldPrepare = await this.shouldPrepare({ platformInfo, changesInfo }); diff --git a/lib/services/project-data-service.ts b/lib/services/project-data-service.ts index 4d1544bf13..9a443bbc12 100644 --- a/lib/services/project-data-service.ts +++ b/lib/services/project-data-service.ts @@ -1,7 +1,6 @@ import * as path from "path"; import * as constants from "../constants"; import { ProjectData } from "../project-data"; -import { parseJson } from "../common/helpers"; import { exported } from "../common/decorators"; import { NATIVESCRIPT_PROPS_INTERNAL_DELIMITER, @@ -197,9 +196,8 @@ export class ProjectDataService implements IProjectDataService { private getNsConfig(nsConfigPath: string): INsConfig { let result = this.getNsConfigDefaultObject(); if (this.$fs.exists(nsConfigPath)) { - const nsConfigContent = this.$fs.readText(nsConfigPath); try { - result = parseJson(nsConfigContent); + result = this.$fs.readJson(nsConfigPath); } catch (e) { // default } diff --git a/lib/services/workflow-service.ts b/lib/services/workflow-service.ts index 5cd4082b7e..210dcbea35 100644 --- a/lib/services/workflow-service.ts +++ b/lib/services/workflow-service.ts @@ -4,8 +4,8 @@ import * as semver from "semver"; import { EOL } from "os"; export class WorkflowService implements IWorkflowService { - private legacyWorkflowDeprecationMessage = `With the upcoming NativeScript 6.0 the Webpack workflow will become the only way of build apps. -More info about the reason for this change and how to migrate your project can be found in the link below: + private legacyWorkflowDeprecationMessage = `With the upcoming NativeScript 6.0 the Webpack workflow will become the only way of building apps. +More info about the reasons for this change and how to migrate your project can be found in the link below: `; private webpackWorkflowConfirmMessage = `Do you want to switch your app to the Webpack workflow?`; @@ -19,7 +19,8 @@ More info about the reason for this change and how to migrate your project can b ) { } - public async handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, skipWarnings?: boolean, force?: boolean): Promise { + public async handleLegacyWorkflow(options: IHandleLegacyWorkflowOptions): Promise { + const { projectDir, settings, skipWarnings, force } = options; if (!settings.bundle || force) { const projectData = this.$projectDataService.getProjectData(projectDir); if (typeof (projectData.useLegacyWorkflow) !== "boolean" || force) { diff --git a/test/stubs.ts b/test/stubs.ts index da6e615e55..7556081a47 100644 --- a/test/stubs.ts +++ b/test/stubs.ts @@ -917,7 +917,7 @@ export class PerformanceService implements IPerformanceService { } export class WorkflowServiceStub implements IWorkflowService { - handleLegacyWorkflow(projectDir: string, settings: IWebpackWorkflowSettings, skipWarnings?: boolean, force?: boolean): Promise { + handleLegacyWorkflow(options: IHandleLegacyWorkflowOptions): Promise { return; } }