diff --git a/src/default-rules/circular-dependencies/index.ts b/src/default-rules/circular-dependencies/index.ts index 8d493fad..4b45db46 100644 --- a/src/default-rules/circular-dependencies/index.ts +++ b/src/default-rules/circular-dependencies/index.ts @@ -48,8 +48,44 @@ export const validateRegistries = (maybeRegistries: string | string[] | undefine export const createNodeName = (node: string, commonPrefix: string): string => node.substring(commonPrefix.length, node.length) || commonPrefix; -const createUserOutput = (commonPrefix: string, cycleGraph: graphlib.Graph): string => - `cyclic root folder: ${commonPrefix}${EOL}${dot.write(cycleGraph)}`; +const createUserOutput = ( + commonPrefix: string, + cycleGraph: graphlib.Graph, + cycle: string[], +): string => + `cyclic root folder: ${commonPrefix}${EOL}${dot.write(cycleGraph)}${EOL}Cycle:${cycle.join( + ' -> ', + )}`; + +function findShortestCycle(graph: graphlib.Graph): string[] | null { + let shortestCycle: string[] | null = null; + function dfs(node: string, visited: string[], allNodes: string[]): void { + visited.push(node); + allNodes.push(node); + + const successors = graph.successors(node); + if (successors) { + for (const successor of successors) { + if (!visited.includes(successor)) { + dfs(successor, visited, allNodes); + } else if (allNodes[0] === successor) { + if (!shortestCycle || allNodes.length < shortestCycle.length) { + shortestCycle = [...allNodes]; + } + } + } + } + + visited.pop(); + allNodes.pop(); + } + + for (const node of graph.nodes()) { + dfs(node, [], []); + } + + return shortestCycle; +} const createMappedCycleMessage = (cycle: string[], mapping: Mapping, graph: graphlib.Graph) => { const cycleGraph = new graphlib.Graph(); @@ -77,7 +113,7 @@ const createMappedCycleMessage = (cycle: string[], mapping: Mapping, graph: grap ); }); - return createUserOutput(commonPrefix, cycleGraph); + return createUserOutput(commonPrefix, cycleGraph, findShortestCycle(cycleGraph) || []); }; const createCycleMessage = (cycle: string[], graph: graphlib.Graph) =>