@snyk/dep-graph
Version:
Snyk dependency graph library
65 lines • 3.09 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.createChangedPackagesGraph = void 0;
const dep_graph_1 = require("./dep-graph");
const builder_1 = require("./builder");
const event_loop_spinner_1 = require("event-loop-spinner");
/**
* Creates an induced subgraph of {@param graphB} with only packages
* that are not present in {@param graphA} or have a different version.
*
* @param graphA
* @param graphB
*/
async function createChangedPackagesGraph(graphA, graphB) {
const depGraph = graphB;
const graphAPackageIds = new Set(graphA.getDepPkgs().map(dep_graph_1.DepGraphImpl.getPkgId));
const addedOrUpdatedPackages = depGraph
.getDepPkgs()
.filter((pkg) => !graphAPackageIds.has(dep_graph_1.DepGraphImpl.getPkgId(pkg)));
const depGraphBuilder = new builder_1.DepGraphBuilder(depGraph.pkgManager, depGraph.rootPkg);
const parentQueue = [];
for (const changedPackage of addedOrUpdatedPackages) {
for (const changedNodeId of depGraph.getPkgNodeIds(changedPackage)) {
//we add all nodes with new and changed packages to the new graph.
//a newly added node will also have its dependencies added here, since they are "new".
depGraphBuilder.addPkgNode(depGraph.getNodePkg(changedNodeId), changedNodeId, getNodeInfo(depGraph, changedNodeId));
//Push all direct parents of the changed nodes to a queue to later build up a path to root from that node
for (const parentId of depGraph.getNodeParentsNodeIds(changedNodeId)) {
parentQueue.push([parentId, changedNodeId]);
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
await event_loop_spinner_1.eventLoopSpinner.spin();
}
}
}
}
//add direct and transitive parents for the changed nodes
const visited = new Set([depGraph.rootNodeId]);
while (parentQueue.length > 0) {
const [nodeId, dependencyNodeId] = parentQueue.pop();
if (visited.has(nodeId)) {
//ensure we link parents even if visited through another path
depGraphBuilder.connectDep(nodeId, dependencyNodeId);
continue;
}
visited.add(nodeId);
depGraphBuilder.addPkgNode(depGraph.getNodePkg(nodeId), nodeId, getNodeInfo(depGraph, nodeId));
depGraphBuilder.connectDep(nodeId, dependencyNodeId);
for (const parentId of depGraph.getNodeParentsNodeIds(nodeId)) {
parentQueue.push([parentId, nodeId]);
if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
await event_loop_spinner_1.eventLoopSpinner.spin();
}
}
}
return depGraphBuilder.build();
}
exports.createChangedPackagesGraph = createChangedPackagesGraph;
function getNodeInfo(depGraph, nodeId) {
const nodeInfo = depGraph.getNode(nodeId);
if (!nodeInfo || Object.keys(nodeInfo).length === 0) {
return undefined;
}
return nodeInfo;
}
//# sourceMappingURL=create-changed-packages-graph.js.map
;