diff --git a/packages/angular/src/migrations/update-8-3-0/upgrade-ngrx-8-0.ts b/packages/angular/src/migrations/update-8-3-0/upgrade-ngrx-8-0.ts index bd432204f9..f5a88f7ebc 100644 --- a/packages/angular/src/migrations/update-8-3-0/upgrade-ngrx-8-0.ts +++ b/packages/angular/src/migrations/update-8-3-0/upgrade-ngrx-8-0.ts @@ -4,9 +4,9 @@ import { readJsonInTree, formatFiles, updateJsonInTree, - checkAndCleanWithSemver + checkAndCleanWithSemver, + addInstallTask } from '@nrwl/workspace'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { gt } from 'semver'; function updateCLI() { @@ -39,9 +39,7 @@ function updateCLI() { return json; }), - (host, context) => { - tasks.push(context.addTask(new NodePackageInstallTask())); - } + addInstallTask() ]); return { rule, tasks }; diff --git a/packages/angular/src/migrations/update-8-5-0/upgrade-cli-8-3.ts b/packages/angular/src/migrations/update-8-5-0/upgrade-cli-8-3.ts index 6b352fda8e..1f00b1716b 100644 --- a/packages/angular/src/migrations/update-8-5-0/upgrade-cli-8-3.ts +++ b/packages/angular/src/migrations/update-8-5-0/upgrade-cli-8-3.ts @@ -4,9 +4,9 @@ import { readJsonInTree, formatFiles, updateJsonInTree, - checkAndCleanWithSemver + checkAndCleanWithSemver, + addInstallTask } from '@nrwl/workspace'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { gt } from 'semver'; const updateAngular = addUpdateTask('@angular/core', '8.2.4'); @@ -41,9 +41,7 @@ function updateCLI() { return json; }), - (host, context) => { - tasks.push(context.addTask(new NodePackageInstallTask())); - } + addInstallTask() ]); return { rule, tasks }; diff --git a/packages/workspace/index.ts b/packages/workspace/index.ts index 438ae777ed..2029b9be82 100644 --- a/packages/workspace/index.ts +++ b/packages/workspace/index.ts @@ -63,6 +63,7 @@ export { getWorkspace, updateWorkspace } from './src/utils/workspace'; export { addUpdateTask } from './src/utils/update-task'; export { addLintFiles, generateProjectLint, Linter } from './src/utils/lint'; +export { addInstallTask } from './src/utils/rules/add-install-task'; export { formatFiles } from './src/utils/rules/format-files'; export { deleteFile } from './src/utils/rules/deleteFile'; export * from './src/utils/rules/ng-add'; diff --git a/packages/workspace/src/migrations/update-8-12-0/update-package-json-deps.ts b/packages/workspace/src/migrations/update-8-12-0/update-package-json-deps.ts index cb6123b976..cb20c922b7 100644 --- a/packages/workspace/src/migrations/update-8-12-0/update-package-json-deps.ts +++ b/packages/workspace/src/migrations/update-8-12-0/update-package-json-deps.ts @@ -1,12 +1,7 @@ -import { chain, Rule, SchematicContext } from '@angular-devkit/schematics'; +import { chain, Rule } from '@angular-devkit/schematics'; import { formatFiles } from '@nrwl/workspace/src/utils/rules/format-files'; import * as path from 'path'; import { updatePackagesInPackageJson } from '../../utils/update-packages-in-package-json'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; - -const addInstall = (_: any, context: SchematicContext) => { - context.addTask(new NodePackageInstallTask()); -}; export default function(): Rule { return chain([ diff --git a/packages/workspace/src/migrations/update-8-3-0/update-cypress-to-34.ts b/packages/workspace/src/migrations/update-8-3-0/update-cypress-to-34.ts index b736241dc5..3dc6166c7f 100644 --- a/packages/workspace/src/migrations/update-8-3-0/update-cypress-to-34.ts +++ b/packages/workspace/src/migrations/update-8-3-0/update-cypress-to-34.ts @@ -1,6 +1,5 @@ -import { formatFiles, updateJsonInTree } from '@nrwl/workspace'; -import { chain, SchematicContext } from '@angular-devkit/schematics'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; +import { addInstallTask, formatFiles, updateJsonInTree } from '@nrwl/workspace'; +import { chain } from '@angular-devkit/schematics'; const updateCypress = updateJsonInTree('package.json', json => { json.devDependencies = json.devDependencies || {}; @@ -11,10 +10,6 @@ const updateCypress = updateJsonInTree('package.json', json => { return json; }); -const addInstall = (_: any, context: SchematicContext) => { - context.addTask(new NodePackageInstallTask()); -}; - export default function() { - return chain([updateCypress, addInstall, formatFiles()]); + return chain([updateCypress, addInstallTask(), formatFiles()]); } diff --git a/packages/workspace/src/migrations/update-8-3-0/update-ng-cli-8-1.ts b/packages/workspace/src/migrations/update-8-3-0/update-ng-cli-8-1.ts index 85a1694b1f..876149ee1e 100644 --- a/packages/workspace/src/migrations/update-8-3-0/update-ng-cli-8-1.ts +++ b/packages/workspace/src/migrations/update-8-3-0/update-ng-cli-8-1.ts @@ -1,6 +1,9 @@ -import { updateJsonInTree, checkAndCleanWithSemver } from '@nrwl/workspace'; -import { chain, SchematicContext } from '@angular-devkit/schematics'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; +import { + updateJsonInTree, + checkAndCleanWithSemver, + addInstallTask +} from '@nrwl/workspace'; +import { chain } from '@angular-devkit/schematics'; import { gt } from 'semver'; const updateCLI = updateJsonInTree('package.json', json => { @@ -27,10 +30,6 @@ const updateCLI = updateJsonInTree('package.json', json => { return json; }); -const addInstall = (_: any, context: SchematicContext) => { - context.addTask(new NodePackageInstallTask()); -}; - export default function() { - return chain([updateCLI, addInstall]); + return chain([updateCLI, addInstallTask()]); } diff --git a/packages/workspace/src/schematics/init/init.ts b/packages/workspace/src/schematics/init/init.ts index 6ed7350a1b..98db6a9af8 100755 --- a/packages/workspace/src/schematics/init/init.ts +++ b/packages/workspace/src/schematics/init/init.ts @@ -18,7 +18,6 @@ import { } from '../../utils/versions'; import { from } from 'rxjs'; import { mapTo, tap } from 'rxjs/operators'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { offsetFromRoot, readJsonInTree, @@ -28,7 +27,8 @@ import { updateJsonInTree, getWorkspacePath, renameSyncInTree, - renameDirSyncInTree + renameDirSyncInTree, + addInstallTask } from '@nrwl/workspace'; import { DEFAULT_NRWL_PRETTIER_CONFIG } from '../workspace/workspace'; import { JsonArray } from '@angular-devkit/core'; @@ -554,15 +554,6 @@ function checkCanConvertToWorkspace(options: Schema) { }; } -function addInstallTask(options: Schema) { - return (host: Tree, context: SchematicContext) => { - if (!options.skipInstall) { - context.addTask(new NodePackageInstallTask()); - } - return host; - }; -} - export default function(schema: Schema): Rule { const options = { ...schema, diff --git a/packages/workspace/src/utils/ast-utils.ts b/packages/workspace/src/utils/ast-utils.ts index fbe39d2ecd..5ae9dd86d2 100644 --- a/packages/workspace/src/utils/ast-utils.ts +++ b/packages/workspace/src/utils/ast-utils.ts @@ -10,12 +10,12 @@ import { Tree, SchematicContext, DirEntry, - noop + noop, + chain } from '@angular-devkit/schematics'; import * as ts from 'typescript'; import * as stripJsonComments from 'strip-json-comments'; import { serializeJson } from './fileutils'; -import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; import { getWorkspacePath } from './cli-config-utils'; import { createProjectGraph, @@ -24,10 +24,8 @@ import { } from '../core/project-graph'; import { FileData } from '../core/file-utils'; import { extname, join, normalize, Path } from '@angular-devkit/core'; -import { - NxJson, - NxJsonProjectConfig -} from '@nrwl/workspace/src/core/shared-interfaces'; +import { NxJson, NxJsonProjectConfig } from '../core/shared-interfaces'; +import { addInstallTask } from './rules/add-install-task'; function nodesByPosition(first: ts.Node, second: ts.Node): number { return first.getStart() - second.getStart(); @@ -561,8 +559,6 @@ function requiresAddingOfPackages(packageJsonFile, deps, devDeps): boolean { return needsDepsUpdate || needsDevDepsUpdate; } -let installAdded = false; - /** * Updates the package.json given the passed deps and/or devDeps. Only updates * if the packages are not yet present @@ -581,9 +577,8 @@ export function addDepsToPackageJson( const currentPackageJson = readJsonInTree(host, 'package.json'); if (requiresAddingOfPackages(currentPackageJson, deps, devDeps)) { - return updateJsonInTree( - 'package.json', - (json, context: SchematicContext) => { + return chain([ + updateJsonInTree('package.json', (json, context: SchematicContext) => { json.dependencies = { ...(json.dependencies || {}), ...deps, @@ -595,13 +590,12 @@ export function addDepsToPackageJson( ...(json.devDependencies || {}) }; - if (addInstall && !installAdded) { - context.addTask(new NodePackageInstallTask()); - installAdded = true; - } return json; - } - ); + }), + addInstallTask({ + skipInstall: !addInstall + }) + ]); } else { return noop(); } @@ -613,21 +607,22 @@ export function updatePackageJsonDependencies( devDeps: any, addInstall = true ): Rule { - return updateJsonInTree('package.json', (json, context: SchematicContext) => { - json.dependencies = { - ...(json.dependencies || {}), - ...deps - }; - json.devDependencies = { - ...(json.devDependencies || {}), - ...devDeps - }; - if (addInstall && !installAdded) { - context.addTask(new NodePackageInstallTask()); - installAdded = true; - } - return json; - }); + return chain([ + updateJsonInTree('package.json', (json, context: SchematicContext) => { + json.dependencies = { + ...(json.dependencies || {}), + ...deps + }; + json.devDependencies = { + ...(json.devDependencies || {}), + ...devDeps + }; + return json; + }), + addInstallTask({ + skipInstall: !addInstall + }) + ]); } export function getProjectConfig(host: Tree, name: string): any { diff --git a/packages/workspace/src/utils/rules/add-install-task.ts b/packages/workspace/src/utils/rules/add-install-task.ts new file mode 100644 index 0000000000..ab7fb6c38e --- /dev/null +++ b/packages/workspace/src/utils/rules/add-install-task.ts @@ -0,0 +1,14 @@ +import { Rule } from '@angular-devkit/schematics'; +import { NodePackageInstallTask } from '@angular-devkit/schematics/tasks'; + +let installAdded = false; +export function addInstallTask( + options: { skipInstall: boolean } = { skipInstall: false } +): Rule { + return (_, context) => { + if (!options.skipInstall && !installAdded) { + context.addTask(new NodePackageInstallTask()); + installAdded = true; + } + }; +} diff --git a/packages/workspace/src/utils/update-packages-in-package-json.ts b/packages/workspace/src/utils/update-packages-in-package-json.ts index 989245f760..80d953aa0c 100644 --- a/packages/workspace/src/utils/update-packages-in-package-json.ts +++ b/packages/workspace/src/utils/update-packages-in-package-json.ts @@ -1,11 +1,14 @@ +import { chain, noop } from '@angular-devkit/schematics'; import { updateJsonInTree } from './ast-utils'; import { readFileSync } from 'fs'; import { checkAndCleanWithSemver } from './version-utils'; import { lt } from 'semver'; +import { addInstallTask } from './rules/add-install-task'; export function updatePackagesInPackageJson( migrationFilePath: string, - versionName: string + versionName: string, + options: { skipInstall: boolean } = { skipInstall: false } ) { const migrations = JSON.parse(readFileSync(migrationFilePath).toString()); const packageJsonUpdates = migrations.packageJsonUpdates[versionName]; @@ -16,40 +19,47 @@ export function updatePackagesInPackageJson( } const updatedPackages = packageJsonUpdates.packages; - return updateJsonInTree('package.json', json => { - Object.keys(updatedPackages).forEach(p => { - /** - * Check the updated version against semver - */ - const cleanUpdatedVersion = checkAndCleanWithSemver( - p, - updatedPackages[p].version - ); - - if (json.devDependencies && json.devDependencies[p]) { - const cleanDevVersion = checkAndCleanWithSemver( + let needsInstall = false; + return chain([ + updateJsonInTree('package.json', json => { + Object.keys(updatedPackages).forEach(p => { + /** + * Check the updated version against semver + */ + const cleanUpdatedVersion = checkAndCleanWithSemver( p, - json.devDependencies[p] + updatedPackages[p].version ); - if (lt(cleanDevVersion, cleanUpdatedVersion)) { - json.devDependencies[p] = updatedPackages[p].version; - } - } else if (json.dependencies && json.dependencies[p]) { - const cleanVersion = checkAndCleanWithSemver(p, json.dependencies[p]); + if (json.devDependencies && json.devDependencies[p]) { + const cleanDevVersion = checkAndCleanWithSemver( + p, + json.devDependencies[p] + ); - if (lt(cleanVersion, cleanUpdatedVersion)) { - json.dependencies[p] = updatedPackages[p].version; - } - } else if (updatedPackages[p].alwaysAddToPackageJson) { - const cleanVersion = checkAndCleanWithSemver(p, json.dependencies[p]); + if (lt(cleanDevVersion, cleanUpdatedVersion)) { + json.devDependencies[p] = updatedPackages[p].version; + needsInstall = true; + } + } else if (json.dependencies && json.dependencies[p]) { + const cleanVersion = checkAndCleanWithSemver(p, json.dependencies[p]); - if (lt(cleanVersion, cleanUpdatedVersion)) { - if (!json.dependencies) json.dependencies = {}; - json.dependencies[p] = updatedPackages[p].version; + if (lt(cleanVersion, cleanUpdatedVersion)) { + json.dependencies[p] = updatedPackages[p].version; + needsInstall = true; + } + } else if (updatedPackages[p].alwaysAddToPackageJson) { + const cleanVersion = checkAndCleanWithSemver(p, json.dependencies[p]); + + if (lt(cleanVersion, cleanUpdatedVersion)) { + if (!json.dependencies) json.dependencies = {}; + json.dependencies[p] = updatedPackages[p].version; + needsInstall = true; + } } - } - }); - return json; - }); + }); + return json; + }), + needsInstall ? addInstallTask(options) : noop() + ]); }