Skip to content

Commit 757bca4

Browse files
clydinmgechev
authored andcommitted
fix(@angular-devkit/schematics): fully scope merge actions in ScopedTree
1 parent 0563e96 commit 757bca4

File tree

2 files changed

+81
-4
lines changed

2 files changed

+81
-4
lines changed

packages/angular_devkit/schematics/src/tree/scoped.ts

+56-4
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
relative,
1515
} from '@angular-devkit/core';
1616
import { Action } from './action';
17+
import { DelegateTree } from './delegate';
1718
import {
1819
DirEntry,
1920
FileEntry,
@@ -89,7 +90,16 @@ export class ScopedTree implements Tree {
8990
get root(): DirEntry { return this._root; }
9091

9192
branch(): Tree { return new ScopedTree(this._base.branch(), this._root.scope); }
92-
merge(other: Tree, strategy?: MergeStrategy): void { this._base.merge(other, strategy); }
93+
merge(other: Tree, strategy?: MergeStrategy): void {
94+
const self = this;
95+
const delegate = new class extends DelegateTree {
96+
get actions(): Action[] {
97+
return other.actions.map(action => self._fullPathAction(action));
98+
}
99+
}(other);
100+
101+
this._base.merge(delegate, strategy);
102+
}
93103

94104
// Readonly.
95105
read(path: string): Buffer | null { return this._base.read(this._fullPath(path)); }
@@ -125,15 +135,57 @@ export class ScopedTree implements Tree {
125135
}
126136

127137
apply(action: Action, strategy?: MergeStrategy): void {
128-
return this._base.apply(action, strategy);
138+
return this._base.apply(this._fullPathAction(action), strategy);
139+
}
140+
141+
get actions(): Action[] {
142+
const scopedActions = [];
143+
144+
for (const action of this._base.actions) {
145+
if (!action.path.startsWith(this._root.scope + '/')) {
146+
continue;
147+
}
148+
149+
if (action.kind !== 'r') {
150+
scopedActions.push({
151+
...action,
152+
path: join(NormalizedRoot, relative(this._root.scope, action.path)),
153+
});
154+
} else if (action.to.startsWith(this._root.scope + '/')) {
155+
scopedActions.push({
156+
...action,
157+
path: join(NormalizedRoot, relative(this._root.scope, action.path)),
158+
to: join(NormalizedRoot, relative(this._root.scope, action.to)),
159+
});
160+
}
161+
}
162+
163+
return scopedActions;
129164
}
130-
get actions(): Action[] { return this._base.actions; }
131165

132166
[TreeSymbol]() {
133167
return this;
134168
}
135169

136-
private _fullPath(path: string) {
170+
private _fullPath(path: string): Path {
137171
return join(this._root.scope, normalize('/' + path));
138172
}
173+
174+
private _fullPathAction(action: Action) {
175+
let fullPathAction: Action;
176+
if (action.kind === 'r') {
177+
fullPathAction = {
178+
...action,
179+
path: this._fullPath(action.path),
180+
to: this._fullPath(action.to),
181+
};
182+
} else {
183+
fullPathAction = {
184+
...action,
185+
path: this._fullPath(action.path),
186+
};
187+
}
188+
189+
return fullPathAction;
190+
}
139191
}

packages/angular_devkit/schematics/src/tree/scoped_spec.ts

+25
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,31 @@ describe('ScopedTree', () => {
133133
]);
134134
});
135135

136+
it('supports merge into a scoped tree', () => {
137+
const other = new HostTree();
138+
other.create('other-file', 'other');
139+
140+
scoped.merge(other);
141+
142+
expect(base.exists('/level-1/other-file')).toBeTruthy();
143+
expect(base.exists('/other-file')).toBeFalsy();
144+
});
145+
146+
it('supports merge from a scoped tree', () => {
147+
const other = new HostTree();
148+
149+
other.merge(scoped);
150+
151+
expect(other.exists('/file-1-1')).toBeTruthy();
152+
expect(other.exists('file-1-1')).toBeTruthy();
153+
expect(other.exists('/file-1-2')).toBeTruthy();
154+
155+
expect(other.exists('/file-0-1')).toBeFalsy();
156+
expect(other.exists('file-0-1')).toBeFalsy();
157+
expect(other.exists('/level-1/file-1-1')).toBeFalsy();
158+
expect(other.exists('level-1/file-1-1')).toBeFalsy();
159+
});
160+
136161
it('supports root', () => {
137162
expect(scoped.root).not.toBeNull();
138163
expect(scoped.root.path as string).toBe('/');

0 commit comments

Comments
 (0)