UNPKG

snyk-mvn-plugin

Version:
124 lines 4.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildDepGraph = buildDepGraph; exports.buildWithoutVerbose = buildWithoutVerbose; exports.buildWithVerbose = buildWithVerbose; const dep_graph_1 = require("@snyk/dep-graph"); const dependency_1 = require("./dependency"); const yocto_queue_1 = require("@common.js/yocto-queue"); function buildDepGraph(mavenGraph, includeTestScope = false, verboseEnabled = false) { const { rootId, nodes } = mavenGraph; return verboseEnabled ? buildWithVerbose(rootId, nodes, includeTestScope) : buildWithoutVerbose(rootId, nodes, includeTestScope); } function buildWithoutVerbose(rootId, nodes, includeTestScope = false) { const parsedRoot = parseId(rootId); const builder = new dep_graph_1.DepGraphBuilder({ name: 'maven' }, parsedRoot.pkgInfo); const visitedMap = {}; const queue = new yocto_queue_1.default(); getItems(rootId, nodes[rootId]).forEach((item) => queue.enqueue(item)); // breadth first search while (queue.size > 0) { const item = queue.dequeue(); if (!item) continue; const { id, parentId } = item; const parsed = parseId(id); const node = nodes[id]; if (!includeTestScope && parsed.scope === 'test' && !node.reachesProdDep) { continue; } const visited = visitedMap[parsed.key]; if (visited) { const prunedId = visited.id + ':pruned'; builder.addPkgNode(visited.pkgInfo, prunedId, { labels: { pruned: 'true' }, }); builder.connectDep(parentId, prunedId); continue; // don't queue any more children } const parentNodeId = parentId === rootId ? builder.rootNodeId : parentId; builder.addPkgNode(parsed.pkgInfo, id); builder.connectDep(parentNodeId, id); visitedMap[parsed.key] = parsed; getItems(id, node).forEach((item) => queue.enqueue(item)); } return builder.build(); } function buildWithVerbose(rootId, nodes, includeTestScope = false) { const parsedRoot = parseId(rootId); const builder = new dep_graph_1.DepGraphBuilder({ name: 'maven' }, parsedRoot.pkgInfo); const visitedMap = {}; const stack = []; stack.push(...getVerboseItems(rootId, [], nodes[rootId])); // depth first search while (stack.length > 0) { const item = stack.pop(); if (!item) continue; const { id, ancestry, parentId } = item; const parsed = parseId(id, true); const node = nodes[id]; if (!includeTestScope && parsed.scope === 'test' && !node.reachesProdDep) { continue; } const visited = visitedMap[parsed.key]; // If verbose is enabled and our ancestry includes ourselves // we are cyclic and should be pruned :) if (ancestry.includes(parsed.key)) { 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 (visited) { builder.addPkgNode(visited.pkgInfo, visited.id); builder.connectDep(parentNodeId, visited.id); // use visited node when omited dependencies found (verbose) stack.push(...getVerboseItems(visited.id, [...ancestry, parsed.key], node)); } else { builder.addPkgNode(parsed.pkgInfo, id); builder.connectDep(parentNodeId, id); visitedMap[parsed.key] = parsed; // Remember to push updated ancestry here stack.push(...getVerboseItems(id, [...ancestry, parsed.key], node)); } } return builder.build(); } function getItems(parentId, node) { const items = []; for (const id of node?.dependsOn || []) { items.push({ id, parentId }); } return items; } function getVerboseItems(parentId, ancestry, node) { const items = []; for (const id of node?.dependsOn || []) { items.push({ id, ancestry, parentId }); } return items; } function parseId(id, verboseEnabled = false) { const dep = (0, dependency_1.parseDependency)(id); const maybeClassifier = dep.classifier ? `:${dep.classifier}` : ''; const name = `${dep.groupId}:${dep.artifactId}`; return { id, key: verboseEnabled ? `${name}:${dep.type}${maybeClassifier}:${dep.version}:${dep.scope}` : `${name}:${dep.type}${maybeClassifier}`, pkgInfo: { name, version: dep.version, }, scope: dep.scope, }; } //# sourceMappingURL=dep-graph.js.map