fix(core): with-deps should handle circular dependencies

This commit is contained in:
Victor Savkin 2020-07-23 16:29:53 -04:00 committed by Victor Savkin
parent 4ec68d3464
commit 78275ef892
3 changed files with 91 additions and 19 deletions

View File

@ -499,16 +499,6 @@ forEachCli((cliName) => {
) )
); );
expect(resWithDeps.tasks).toEqual([ expect(resWithDeps.tasks).toEqual([
{
id: `${mypublishablelib}:build`,
overrides: {},
target: {
project: mypublishablelib,
target: 'build',
},
command: `npm run ${cliCommand} -- build ${mypublishablelib}`,
outputs: [`dist/libs/${mypublishablelib}`],
},
{ {
id: `${myapp}:build`, id: `${myapp}:build`,
overrides: {}, overrides: {},
@ -519,6 +509,16 @@ forEachCli((cliName) => {
command: `npm run ${cliCommand} -- build ${myapp}`, command: `npm run ${cliCommand} -- build ${myapp}`,
outputs: [`dist/apps/${myapp}`], outputs: [`dist/apps/${myapp}`],
}, },
{
id: `${mypublishablelib}:build`,
overrides: {},
target: {
project: mypublishablelib,
target: 'build',
},
command: `npm run ${cliCommand} -- build ${mypublishablelib}`,
outputs: [`dist/libs/${mypublishablelib}`],
},
]); ]);
compareTwoArrays(resWithDeps.projects, [ compareTwoArrays(resWithDeps.projects, [
mylib, mylib,

View File

@ -173,6 +173,65 @@ describe('withDeps', () => {
}, },
}); });
}); });
it('should handle circular deps', () => {
const graph: ProjectGraph = {
nodes: {
lib1: { name: 'lib1', type: 'lib', data: null },
lib2: { name: 'lib2', type: 'lib', data: null },
},
dependencies: {
lib1: [
{
type: DependencyType.static,
source: 'lib1',
target: 'lib2',
},
],
lib2: [
{
type: DependencyType.static,
source: 'lib2',
target: 'lib1',
},
],
},
};
const affectedNodes = [{ name: 'lib1', type: 'lib', data: null }];
const result = withDeps(graph, affectedNodes);
expect(result).toEqual({
nodes: {
lib1: {
name: 'lib1',
type: 'lib',
data: null,
},
lib2: {
name: 'lib2',
type: 'lib',
data: null,
},
},
dependencies: {
lib2: [
{
type: 'static',
source: 'lib2',
target: 'lib1',
},
],
lib1: [
{
type: 'static',
source: 'lib1',
target: 'lib2',
},
],
},
});
});
}); });
describe('filterNodes', () => { describe('filterNodes', () => {

View File

@ -80,22 +80,35 @@ export function withDeps(
subsetNodes: ProjectGraphNode[] subsetNodes: ProjectGraphNode[]
): ProjectGraph { ): ProjectGraph {
const builder = new ProjectGraphBuilder(); const builder = new ProjectGraphBuilder();
Object.values(subsetNodes).forEach(recur); const visitedNodes = [];
const visitedEdges = [];
Object.values(subsetNodes).forEach(recurNodes);
Object.values(subsetNodes).forEach(recurEdges);
return builder.build(); return builder.build();
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
function recur(node) { function recurNodes(node) {
const ds = original.dependencies[node.name]; if (visitedNodes.indexOf(node.name) > -1) return;
// 1. Recursively add all source nodes
ds.forEach((n) => {
recur(original.nodes[n.target]);
});
// 2. Add current node
builder.addNode(node); builder.addNode(node);
// 3. Add all source dependencies visitedNodes.push(node.name);
original.dependencies[node.name].forEach((n) => {
recurNodes(original.nodes[n.target]);
});
}
function recurEdges(node) {
if (visitedEdges.indexOf(node.name) > -1) return;
visitedEdges.push(node.name);
const ds = original.dependencies[node.name];
ds.forEach((n) => { ds.forEach((n) => {
builder.addDependency(n.type, n.source, n.target); builder.addDependency(n.type, n.source, n.target);
}); });
ds.forEach((n) => {
recurEdges(original.nodes[n.target]);
});
} }
} }