Skip to content

Commit

Permalink
fix(bazel): Make sure only single copy of @angular/bazel is install…
Browse files Browse the repository at this point in the history
…ed (#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
  • Loading branch information
kyliau authored and AndrewKushnir committed Apr 24, 2019
1 parent e8d3246 commit 2905bf5
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
16 changes: 11 additions & 5 deletions packages/bazel/src/schematics/ng-add/index.ts
Expand Up @@ -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;
Expand Down
17 changes: 15 additions & 2 deletions packages/bazel/src/schematics/ng-add/index_spec.ts
Expand Up @@ -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';
Expand All @@ -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', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/bazel/src/schematics/utility/json-utils.ts
Expand Up @@ -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;
}
Expand Down

0 comments on commit 2905bf5

Please sign in to comment.