UNPKG

3.79 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.buildDepGraphYarnLockV1WorkspaceCyclesPruned = void 0;
4const dep_graph_1 = require("@snyk/dep-graph");
5const util_1 = require("../util");
6const util_2 = require("./util");
7const event_loop_spinner_1 = require("event-loop-spinner");
8var Color;
9(function (Color) {
10 Color[Color["GRAY"] = 0] = "GRAY";
11 Color[Color["BLACK"] = 1] = "BLACK";
12})(Color || (Color = {}));
13// Parse a single workspace package using yarn.lock v1
14// workspaces feature
15const buildDepGraphYarnLockV1WorkspaceCyclesPruned = async (extractedYarnLockV1Pkgs, pkgJson, workspacePkgNameToVersion, options) => {
16 const { includeDevDeps, strictOutOfSync, includeOptionalDeps } = options;
17 const depGraphBuilder = new dep_graph_1.DepGraphBuilder({ name: 'yarn' }, { name: pkgJson.name, version: pkgJson.version });
18 const colorMap = {};
19 const topLevelDeps = (0, util_1.getTopLevelDeps)(pkgJson, { includeDevDeps });
20 const rootNode = {
21 id: 'root-node',
22 name: pkgJson.name,
23 version: pkgJson.version,
24 dependencies: topLevelDeps,
25 isDev: false,
26 };
27 await dfsVisit(depGraphBuilder, rootNode, colorMap, extractedYarnLockV1Pkgs, workspacePkgNameToVersion, strictOutOfSync, includeOptionalDeps);
28 return depGraphBuilder.build();
29};
30exports.buildDepGraphYarnLockV1WorkspaceCyclesPruned = buildDepGraphYarnLockV1WorkspaceCyclesPruned;
31/**
32 * Use DFS to add all nodes and edges to the depGraphBuilder and prune cyclic nodes.
33 * The colorMap keep track of the state of node during traversal.
34 * - If a node doesn't exist in the map, it means it hasn't been visited.
35 * - If a node is GRAY, it means it has already been discovered but its subtree hasn't been fully traversed.
36 * - If a node is BLACK, it means its subtree has already been fully traversed.
37 * - When first exploring an edge, if it points to a GRAY node, a cycle is found and the GRAY node is pruned.
38 * - A pruned node has id `${originalId}|1`
39 * When coming across another workspace package as child node, simply add the node and edge to the graph and mark it as BLACK.
40 */
41const dfsVisit = async (depGraphBuilder, node, colorMap, extractedYarnLockV1Pkgs, workspacePkgNameToVersion, strictOutOfSync, includeOptionalDeps) => {
42 colorMap[node.id] = Color.GRAY;
43 for (const [name, depInfo] of Object.entries(node.dependencies || {})) {
44 if (event_loop_spinner_1.eventLoopSpinner.isStarving()) {
45 await event_loop_spinner_1.eventLoopSpinner.spin();
46 }
47 const isWorkspacePkg = !!workspacePkgNameToVersion[name];
48 const childNode = (0, util_2.getChildNodeYarnLockV1Workspace)(name, depInfo, workspacePkgNameToVersion, extractedYarnLockV1Pkgs, strictOutOfSync, includeOptionalDeps);
49 if (!colorMap.hasOwnProperty(childNode.id)) {
50 (0, util_1.addPkgNodeToGraph)(depGraphBuilder, childNode, {
51 isCyclic: false,
52 isWorkspacePkg,
53 });
54 if (!isWorkspacePkg) {
55 await dfsVisit(depGraphBuilder, childNode, colorMap, extractedYarnLockV1Pkgs, workspacePkgNameToVersion, strictOutOfSync, includeOptionalDeps);
56 }
57 else {
58 colorMap[childNode.id] = Color.BLACK;
59 }
60 }
61 else if (colorMap[childNode.id] === Color.GRAY) {
62 // cycle detected
63 childNode.id = `${childNode.id}|1`;
64 (0, util_1.addPkgNodeToGraph)(depGraphBuilder, childNode, {
65 isCyclic: true,
66 isWorkspacePkg,
67 });
68 }
69 depGraphBuilder.connectDep(node.id, childNode.id);
70 }
71 colorMap[node.id] = Color.BLACK;
72};
73//# sourceMappingURL=build-depgraph-workspace-package-pruned.js.map
\No newline at end of file