Skip to content

Commit

Permalink
fix(@angular-devkit/schematics): check merge ancestry of delegate & s…
Browse files Browse the repository at this point in the history
…coped trees

This change ensures correct merge behavior when a `HostTree` is wrapped in a `ScopedTree` or `DelegateTree`.  Previously the ancestry of the HostTree was not available to the merge.

(cherry picked from commit 8688de4)
  • Loading branch information
clydin authored and alan-agius4 committed Feb 1, 2021
1 parent 9a8ff9f commit 13bedc3
Showing 1 changed file with 18 additions and 2 deletions.
20 changes: 18 additions & 2 deletions packages/angular_devkit/schematics/src/tree/host-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
OverwriteFileAction,
RenameFileAction,
} from './action';
import { DelegateTree } from './delegate';
import { LazyFileEntry } from './entry';
import {
DirEntry,
Expand All @@ -45,6 +46,7 @@ import {
UpdateRecorder,
} from './interface';
import { UpdateRecorderBase } from './recorder';
import { ScopedTree } from './scoped';


let _uniqueId = 0;
Expand Down Expand Up @@ -156,13 +158,27 @@ export class HostTree implements Tree {
return branchedTree;
}

private isAncestorOf(tree: Tree): boolean {
if (tree instanceof HostTree) {
return tree._ancestry.has(this._id);
}
if (tree instanceof DelegateTree) {
return this.isAncestorOf((tree as unknown as { _other: Tree})._other);
}
if (tree instanceof ScopedTree) {
return this.isAncestorOf((tree as unknown as { _base: Tree})._base);
}

return false;
}

merge(other: Tree, strategy: MergeStrategy = MergeStrategy.Default): void {
if (other === this) {
// Merging with yourself? Tsk tsk. Nothing to do at least.
return;
}

if (other instanceof HostTree && other._ancestry.has(this._id)) {
if (this.isAncestorOf(other)) {
// Workaround for merging a branch back into one of its ancestors
// More complete branch point tracking is required to avoid
strategy |= MergeStrategy.Overwrite;
Expand All @@ -173,7 +189,7 @@ export class HostTree implements Tree {
const overwriteConflictAllowed =
(strategy & MergeStrategy.AllowOverwriteConflict) == MergeStrategy.AllowOverwriteConflict;
const deleteConflictAllowed =
(strategy & MergeStrategy.AllowOverwriteConflict) == MergeStrategy.AllowDeleteConflict;
(strategy & MergeStrategy.AllowDeleteConflict) == MergeStrategy.AllowDeleteConflict;

other.actions.forEach(action => {
switch (action.kind) {
Expand Down

0 comments on commit 13bedc3

Please sign in to comment.