Skip to content

Commit

Permalink
Merge pull request #173 from snyk/fix/dverbose-cyrcular-deps
Browse files Browse the repository at this point in the history
fix: Cyclic deps support for dverbose
  • Loading branch information
MarcusArdelean authored Apr 24, 2024
2 parents cb21c33 + e89fd3b commit f32664a
Show file tree
Hide file tree
Showing 4 changed files with 634 additions and 5 deletions.
29 changes: 24 additions & 5 deletions lib/parse/dep-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@ export function buildDepGraph(
const builder = new DepGraphBuilder({ name: 'maven' }, parsedRoot.pkgInfo);
const visitedMap: Record<string, DepInfo> = {};
const queue: QueueItem[] = [];
queue.push(...getItems(rootId, nodes[rootId]));
queue.push(...getItems(rootId, [], nodes[rootId]));

// breadth first search
while (queue.length > 0) {
const item = queue.shift();

if (!item) continue;
const { id, parentId } = item;
const { id, ancestry, parentId } = item;
const parsed = parseId(id);
const node = nodes[id];
if (!includeTestScope && parsed.scope === 'test' && !node.reachesProdDep) {
Expand All @@ -34,6 +35,18 @@ export function buildDepGraph(
builder.connectDep(parentId, prunedId);
continue; // don't queue any more children
}

// If verbose is enabled and our ancestry includes ourselves
// we are cyclic and should be pruned :)
if (verboseEnabled && ancestry.includes(id)) {
const prunedId = visited.id + ':pruned-cycle';
builder.addPkgNode(visited.pkgInfo, prunedId, {
labels: { pruned: 'cyclic' },
});
builder.connectDep(parentId, prunedId);
continue; // don't queue any more children
}

const parentNodeId = parentId === rootId ? builder.rootNodeId : parentId;
if (verboseEnabled && visited) {
// use visited node when omited dependencies found (verbose)
Expand All @@ -44,21 +57,27 @@ export function buildDepGraph(
builder.connectDep(parentNodeId, id);
visitedMap[parsed.key] = parsed;
}
queue.push(...getItems(id, node));
// Remember to push updated ancestry here
queue.push(...getItems(id, [...ancestry, id], node));
}

return builder.build();
}

interface QueueItem {
id: string;
ancestry: string[]; // This is an easy trick to maintain ancestry at cost of space
parentId: string;
}

function getItems(parentId: string, node?: MavenGraphNode): QueueItem[] {
function getItems(
parentId: string,
ancestry: string[],
node?: MavenGraphNode,
): QueueItem[] {
const items: QueueItem[] = [];
for (const id of node?.dependsOn || []) {
items.push({ id, parentId });
items.push({ id, ancestry, parentId });
}
return items;
}
Expand Down
Loading

0 comments on commit f32664a

Please sign in to comment.