Skip to content

Commit

Permalink
fix(@angular-devkit/core): track workspace targets with no original c…
Browse files Browse the repository at this point in the history
…ollection (#15413)

Fixes #15403
  • Loading branch information
clydin authored and mgechev committed Aug 23, 2019
1 parent 9296bea commit 7f6ba9e
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 15 deletions.
2 changes: 1 addition & 1 deletion etc/api/angular_devkit/core/src/_golden-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export declare function decamelize(str: string): string;

export declare function deepCopy<T extends any>(value: T): T;

export declare type DefinitionCollectionListener<V> = (name: string, action: 'add' | 'remove' | 'replace', newValue: V | undefined, oldValue: V | undefined) => void;
export declare type DefinitionCollectionListener<V extends object> = (name: string, action: 'add' | 'remove' | 'replace', newValue: V | undefined, oldValue: V | undefined, collection: DefinitionCollection<V>) => void;

export declare class DependencyNotFoundException extends BaseException {
constructor();
Expand Down
7 changes: 4 additions & 3 deletions packages/angular_devkit/core/src/workspace/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,12 @@ export interface TargetDefinition {
builder: string;
}

export type DefinitionCollectionListener<V> = (
export type DefinitionCollectionListener<V extends object> = (
name: string,
action: 'add' | 'remove' | 'replace',
newValue: V | undefined,
oldValue: V | undefined,
collection: DefinitionCollection<V>,
) => void;

class DefinitionCollection<V extends object> implements ReadonlyMap<string, V> {
Expand All @@ -50,7 +51,7 @@ class DefinitionCollection<V extends object> implements ReadonlyMap<string, V> {
const value = this._map.get(key);
const result = this._map.delete(key);
if (result && value !== undefined && this._listener) {
this._listener(key, 'remove', undefined, value);
this._listener(key, 'remove', undefined, value, this);
}

return result;
Expand All @@ -61,7 +62,7 @@ class DefinitionCollection<V extends object> implements ReadonlyMap<string, V> {
this._map.set(key, value);

if (this._listener) {
this._listener(key, existing !== undefined ? 'replace' : 'add', value, existing);
this._listener(key, existing !== undefined ? 'replace' : 'add', value, existing, this);
}

return this;
Expand Down
40 changes: 29 additions & 11 deletions packages/angular_devkit/core/src/workspace/json/reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,17 +213,35 @@ function parseProject(
}

let collectionListener: DefinitionCollectionListener<TargetDefinition> | undefined;
if (context.trackChanges && targetsNode) {
const parentNode = targetsNode;
collectionListener = (name, action, newValue) => {
jsonMetadata.addChange(
action,
`/projects/${projectName}/targets/${escapeKey(name)}`,
parentNode,
newValue,
'target',
);
};
if (context.trackChanges) {
if (targetsNode) {
const parentNode = targetsNode;
collectionListener = (name, action, newValue) => {
jsonMetadata.addChange(
action,
`/projects/${projectName}/targets/${escapeKey(name)}`,
parentNode,
newValue,
'target',
);
};
} else {
let added = false;
collectionListener = (_name, action, _new, _old, collection) => {
if (added || action !== 'add') {
return;
}

jsonMetadata.addChange(
'add',
`/projects/${projectName}/targets`,
projectNode,
collection,
'targetcollection',
);
added = true;
};
}
}

const base = {
Expand Down
49 changes: 49 additions & 0 deletions packages/angular_devkit/core/src/workspace/json/reader_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -710,4 +710,53 @@ describe('JSON ProjectDefinition Tracks Project Changes', () => {
expect(change.value).toBe('valueA');
}
});

it('tracks target additions with no original target collection', async () => {
const original = stripIndent`
{
"version": 1,
// Comment
"schematics": {
"@angular/schematics:component": {
"prefix": "abc"
}
},
"projects": {
"p1": {
"root": "p1-root"
}
},
"x-foo": {
"is": ["good", "great", "awesome"]
},
"x-bar": 5,
}
`;
const host = createTestHost(original);

const workspace = await readJsonWorkspace('', host);

const project = workspace.projects.get('p1');
expect(project).not.toBeUndefined();
if (!project) {
return;
}

project.targets.add({
name: 't1',
builder: 't1-builder',
});

const metadata = getMetadata(workspace);

expect(metadata.hasChanges).toBeTruthy();
expect(metadata.changeCount).toBe(1);

const change = metadata.findChangesForPath('/projects/p1/targets')[0];
expect(change).not.toBeUndefined();
if (change) {
expect(change.op).toBe('add');
expect(change.type).toBe('targetcollection');
}
});
});

0 comments on commit 7f6ba9e

Please sign in to comment.