From 2905bf5548c4954d3fb5bfdb9450374a5da992d1 Mon Sep 17 00:00:00 2001 From: Keen Yee Liau Date: Tue, 23 Apr 2019 12:51:13 -0700 Subject: [PATCH] fix(bazel): Make sure only single copy of `@angular/bazel` is installed (#30072) When `ng add` is invoked independently of `ng new`, a node installation of `@angular/bazel` is performed by the CLI before invoking the schematic. This step appends `@angular/bazel` to the `dependencies` section of `package.json`. The schematics then appends the same package to `devDependencies`. This leads to the warning: ``` warning package.json: "dependencies" has dependency "@angular/bazel" with range "^8.0.0-beta.13" that collides with a dependency in "devDependencies" of the same name with version "~8.0.0-beta.12" ``` PR Close #30072 --- packages/bazel/src/schematics/ng-add/index.ts | 16 +++++++++++----- .../bazel/src/schematics/ng-add/index_spec.ts | 17 +++++++++++++++-- .../bazel/src/schematics/utility/json-utils.ts | 2 +- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/bazel/src/schematics/ng-add/index.ts b/packages/bazel/src/schematics/ng-add/index.ts index 3021c7e4c9..e71beda97a 100755 --- a/packages/bazel/src/schematics/ng-add/index.ts +++ b/packages/bazel/src/schematics/ng-add/index.ts @@ -55,13 +55,19 @@ function addDevDependenciesToPackageJson(options: Schema) { }; const recorder = host.beginUpdate(packageJson); - const depsToInstall = Object.keys(devDependencies).filter((name) => { - return !findPropertyInAstObject(devDeps, name); - }); - for (const packageName of depsToInstall) { + for (const packageName of Object.keys(devDependencies)) { + const existingDep = findPropertyInAstObject(deps, packageName); + if (existingDep) { + const content = packageJsonContent.toString(); + removeKeyValueInAstObject(recorder, content, deps, packageName); + } const version = devDependencies[packageName]; const indent = 4; - insertPropertyInAstObjectInOrder(recorder, devDeps, packageName, version, indent); + if (findPropertyInAstObject(devDeps, packageName)) { + replacePropertyInAstObject(recorder, devDeps, packageName, version, indent); + } else { + insertPropertyInAstObjectInOrder(recorder, devDeps, packageName, version, indent); + } } host.commitUpdate(recorder); return host; diff --git a/packages/bazel/src/schematics/ng-add/index_spec.ts b/packages/bazel/src/schematics/ng-add/index_spec.ts index 26db953695..b01fc7a14d 100644 --- a/packages/bazel/src/schematics/ng-add/index_spec.ts +++ b/packages/bazel/src/schematics/ng-add/index_spec.ts @@ -100,7 +100,7 @@ describe('ng-add schematic', () => { expect(devDeps).toContain('@bazel/karma'); }); - it('should not add an existing dev dependency', () => { + it('should replace an existing dev dependency', () => { expect(host.files).toContain('/package.json'); const packageJson = JSON.parse(host.readContent('/package.json')); packageJson.devDependencies['@angular/bazel'] = '4.2.42'; @@ -110,7 +110,20 @@ describe('ng-add schematic', () => { // It is possible that a dep gets added twice if the package already exists. expect(content.match(/@angular\/bazel/g) !.length).toEqual(1); const json = JSON.parse(content); - expect(json.devDependencies['@angular/bazel']).toBe('4.2.42'); + expect(json.devDependencies['@angular/bazel']).toBe('1.2.3'); + }); + + it('should remove an existing dependency', () => { + expect(host.files).toContain('/package.json'); + const packageJson = JSON.parse(host.readContent('/package.json')); + packageJson.dependencies['@angular/bazel'] = '4.2.42'; + expect(Object.keys(packageJson.dependencies)).toContain('@angular/bazel'); + host.overwrite('/package.json', JSON.stringify(packageJson)); + host = schematicRunner.runSchematic('ng-add', defaultOptions, host); + const content = host.readContent('/package.json'); + const json = JSON.parse(content); + expect(Object.keys(json.dependencies)).not.toContain('@angular/bazel'); + expect(json.devDependencies['@angular/bazel']).toBe('1.2.3'); }); it('should not create Bazel workspace file', () => { diff --git a/packages/bazel/src/schematics/utility/json-utils.ts b/packages/bazel/src/schematics/utility/json-utils.ts index 37526b5f6e..0c42716dbd 100644 --- a/packages/bazel/src/schematics/utility/json-utils.ts +++ b/packages/bazel/src/schematics/utility/json-utils.ts @@ -40,7 +40,7 @@ export function removeKeyValueInAstObject( const start = prop.start.offset; const end = prop.end.offset; let length = end - start; - const match = content.slice(end).match(/[,\s]+/); + const match = content.slice(end).match(/^[,\s]+/); if (match) { length += match.pop() !.length; }