@vltpkg/graph 1.3.8 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +59 -3
- package/dist/actual/load.js +28 -12
- package/dist/build.js +30 -5
- package/dist/dependencies.d.ts +11 -0
- package/dist/dependencies.js +47 -7
- package/dist/filter-nodes-by-query.d.ts +39 -0
- package/dist/filter-nodes-by-query.js +100 -0
- package/dist/ideal/append-nodes.js +19 -6
- package/dist/ideal/build-ideal-from-starting-graph.js +8 -0
- package/dist/ideal/get-importer-specs.d.ts +1 -0
- package/dist/ideal/get-importer-specs.js +27 -7
- package/dist/ideal/refresh-ideal-graph.js +6 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/install.d.ts +23 -8
- package/dist/install.js +46 -1
- package/dist/lockfile/load-edges.js +10 -4
- package/dist/modifiers.d.ts +7 -0
- package/dist/modifiers.js +24 -0
- package/dist/reify/build.d.ts +7 -0
- package/dist/reify/check-needed-build.d.ts +5 -0
- package/dist/reify/check-needed-build.js +13 -0
- package/dist/reify/index.js +9 -39
- package/dist/reify/update-importers-package-json.js +5 -9
- package/dist/skills/dirs.d.ts +58 -0
- package/dist/skills/dirs.js +211 -0
- package/dist/skills/discover.d.ts +73 -0
- package/dist/skills/discover.js +234 -0
- package/dist/skills/gitignore.d.ts +13 -0
- package/dist/skills/gitignore.js +53 -0
- package/dist/skills/index.d.ts +123 -0
- package/dist/skills/index.js +225 -0
- package/dist/skills/lazy.d.ts +8 -0
- package/dist/skills/lazy.js +8 -0
- package/dist/skills/mask.d.ts +26 -0
- package/dist/skills/mask.js +43 -0
- package/dist/skills/mounts.d.ts +64 -0
- package/dist/skills/mounts.js +136 -0
- package/dist/uninstall.d.ts +24 -7
- package/dist/uninstall.js +26 -1
- package/dist/update.d.ts +24 -4
- package/dist/update.js +24 -1
- package/dist/visualization/mermaid-output.d.ts +8 -0
- package/dist/visualization/mermaid-output.js +25 -8
- package/package.json +21 -21
package/dist/update.js
CHANGED
|
@@ -12,6 +12,8 @@ import { RollbackRemove } from '@vltpkg/rollback-remove';
|
|
|
12
12
|
import { Monorepo } from '@vltpkg/workspaces';
|
|
13
13
|
import { existsSync, rmSync } from 'node:fs';
|
|
14
14
|
import { resolve } from 'node:path';
|
|
15
|
+
import { assertQuery } from "./filter-nodes-by-query.js";
|
|
16
|
+
import { assertSkillsDirs } from "./skills/dirs.js";
|
|
15
17
|
/**
|
|
16
18
|
* Graph to update from. `-w` filtered: the lockfile (else installed)
|
|
17
19
|
* graph minus the selected workspaces' deps, so only those re-resolve
|
|
@@ -45,6 +47,16 @@ const startingGraph = (options, monorepo) => {
|
|
|
45
47
|
return graph;
|
|
46
48
|
};
|
|
47
49
|
export const update = async (options) => {
|
|
50
|
+
// unset or `:not(*)`: no skills work at all, the skills code never
|
|
51
|
+
// loads
|
|
52
|
+
const allowSkills = options.allowSkills === ':not(*)' ?
|
|
53
|
+
undefined
|
|
54
|
+
: options.allowSkills;
|
|
55
|
+
// fail before updating, not after
|
|
56
|
+
if (allowSkills) {
|
|
57
|
+
await assertQuery(allowSkills, 'allow-skills', ['skill']);
|
|
58
|
+
assertSkillsDirs(options.projectRoot, options.skillsDirs);
|
|
59
|
+
}
|
|
48
60
|
let mainManifest = undefined;
|
|
49
61
|
try {
|
|
50
62
|
mainManifest = options.packageJson.read(options.projectRoot);
|
|
@@ -66,6 +78,7 @@ export const update = async (options) => {
|
|
|
66
78
|
packageJson: options.packageJson,
|
|
67
79
|
scurry: options.scurry,
|
|
68
80
|
});
|
|
81
|
+
let result;
|
|
69
82
|
try {
|
|
70
83
|
const done = graphStep('build');
|
|
71
84
|
const graph = await buildIdealFromStartingGraph({
|
|
@@ -94,7 +107,7 @@ export const update = async (options) => {
|
|
|
94
107
|
remover,
|
|
95
108
|
update: true,
|
|
96
109
|
});
|
|
97
|
-
|
|
110
|
+
result = { buildQueue, graph, diff };
|
|
98
111
|
/* c8 ignore start */
|
|
99
112
|
}
|
|
100
113
|
catch (err) {
|
|
@@ -110,4 +123,14 @@ export const update = async (options) => {
|
|
|
110
123
|
throw err;
|
|
111
124
|
}
|
|
112
125
|
/* c8 ignore stop */
|
|
126
|
+
// after the try: a link failure must not roll back the update
|
|
127
|
+
if (!allowSkills)
|
|
128
|
+
return result;
|
|
129
|
+
const { linkSkills } = await import("./skills/index.js");
|
|
130
|
+
result.skills = await linkSkills({
|
|
131
|
+
...options,
|
|
132
|
+
graph: result.graph,
|
|
133
|
+
target: allowSkills,
|
|
134
|
+
});
|
|
135
|
+
return result;
|
|
113
136
|
};
|
|
@@ -1,9 +1,17 @@
|
|
|
1
|
+
import type { DepID } from '@vltpkg/dep-id';
|
|
1
2
|
import type { EdgeLike, NodeLike } from '@vltpkg/types';
|
|
3
|
+
/** A leaf drawn under a graph node: node label, optional edge label. */
|
|
4
|
+
export type MermaidChild = {
|
|
5
|
+
label: string;
|
|
6
|
+
edge?: string;
|
|
7
|
+
};
|
|
2
8
|
export type MermaidOutputGraph = {
|
|
3
9
|
edges: EdgeLike[];
|
|
4
10
|
importers: Set<NodeLike>;
|
|
5
11
|
nodes: NodeLike[];
|
|
6
12
|
highlightSelection?: boolean;
|
|
13
|
+
/** leaves to draw under included nodes (class `b`), eg: skills */
|
|
14
|
+
children?: Map<DepID, MermaidChild[]>;
|
|
7
15
|
};
|
|
8
16
|
/**
|
|
9
17
|
* Generates a short identifier for a given index following the pattern:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Edge } from "../edge.js";
|
|
2
2
|
import { Node } from "../node.js";
|
|
3
3
|
let missingCount = 0;
|
|
4
|
+
const escapeLabel = (s) => s.replaceAll('"', '#quot;').replaceAll('@', '#64;');
|
|
4
5
|
const isSelected = (options, edge, node) => (!node || options.nodes.includes(node)) &&
|
|
5
6
|
/* c8 ignore next */ (!edge || options.edges.includes(edge));
|
|
6
7
|
/**
|
|
@@ -72,7 +73,7 @@ const nodeRef = (node, labeledNodes, depIdMapping, options) => {
|
|
|
72
73
|
labeledNodes.add(node.id);
|
|
73
74
|
return `${shortId}("${String(node).replaceAll('@', '#64;')}")${selectedClass}`;
|
|
74
75
|
};
|
|
75
|
-
function parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options, node, isImporter = false) {
|
|
76
|
+
function parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options, leaves, node, isImporter = false) {
|
|
76
77
|
if (seenNodes.has(node.id) || !includedItems.get(node)) {
|
|
77
78
|
return '';
|
|
78
79
|
}
|
|
@@ -87,8 +88,10 @@ function parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options
|
|
|
87
88
|
...node.edgesOut.values(),
|
|
88
89
|
...(node.workspaces?.values() ?? []),
|
|
89
90
|
];
|
|
90
|
-
const edges =
|
|
91
|
-
.
|
|
91
|
+
const edges = [
|
|
92
|
+
leaves.get(node.id),
|
|
93
|
+
...allEdges.map(e => parseEdge(seenNodes, labeledNodes, includedItems, depIdMapping, options, leaves, e)),
|
|
94
|
+
]
|
|
92
95
|
.filter(Boolean)
|
|
93
96
|
.join('\n');
|
|
94
97
|
// Only render node standalone for importers, others are rendered as part of edges
|
|
@@ -98,7 +101,7 @@ function parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options
|
|
|
98
101
|
}
|
|
99
102
|
return edges;
|
|
100
103
|
}
|
|
101
|
-
function parseEdge(seenNodes, labeledNodes, includedItems, depIdMapping, options, edge) {
|
|
104
|
+
function parseEdge(seenNodes, labeledNodes, includedItems, depIdMapping, options, leaves, edge) {
|
|
102
105
|
if (!includedItems.get(edge)) {
|
|
103
106
|
return '';
|
|
104
107
|
}
|
|
@@ -112,14 +115,14 @@ function parseEdge(seenNodes, labeledNodes, includedItems, depIdMapping, options
|
|
|
112
115
|
// Label the target node first so that if it's referenced again later in the graph,
|
|
113
116
|
// it will use the short identifier instead of repeating the full label.
|
|
114
117
|
const toRef = nodeRef(edge.to, labeledNodes, depIdMapping, options);
|
|
115
|
-
const childEdges = parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options, edge.to);
|
|
118
|
+
const childEdges = parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options, leaves, edge.to);
|
|
116
119
|
return edgeResult + toRef + (childEdges ? '\n' + childEdges : '');
|
|
117
120
|
}
|
|
118
121
|
/**
|
|
119
122
|
* Returns a mermaid string representation of the graph.
|
|
120
123
|
*/
|
|
121
124
|
export function mermaidOutput(options) {
|
|
122
|
-
const { edges, importers, nodes, highlightSelection } = options;
|
|
125
|
+
const { edges, importers, nodes, highlightSelection, children } = options;
|
|
123
126
|
const seen = new Set();
|
|
124
127
|
const includedItems = new Map();
|
|
125
128
|
const traverse = new Set([...importers].map(i => ({ self: i, parent: undefined })));
|
|
@@ -157,14 +160,28 @@ export function mermaidOutput(options) {
|
|
|
157
160
|
}
|
|
158
161
|
// Create DepID to short identifier mapping
|
|
159
162
|
const depIdMapping = createDepIdMapping(importers);
|
|
163
|
+
// leaf lines per node, ids after the graph's
|
|
164
|
+
const leaves = new Map();
|
|
165
|
+
let leafIndex = depIdMapping.size;
|
|
166
|
+
for (const [id, items] of children ?? []) {
|
|
167
|
+
const from = depIdMapping.get(id);
|
|
168
|
+
if (!from || !items.length)
|
|
169
|
+
continue;
|
|
170
|
+
leaves.set(id, items
|
|
171
|
+
.map(({ label, edge }) => `${from} -->${edge === undefined ? '' : `|"${escapeLabel(edge)}"|`} ${generateShortId(leafIndex++)}("${escapeLabel(label)}"):::b`)
|
|
172
|
+
.join('\n'));
|
|
173
|
+
}
|
|
160
174
|
// Track nodes that have had their label printed (shared across all importers)
|
|
161
175
|
const labeledNodes = new Set();
|
|
162
176
|
// Track nodes that have been processed (shared across all importers to avoid duplicates)
|
|
163
177
|
const seenNodes = new Set();
|
|
164
178
|
const graphOutput = [...importers]
|
|
165
|
-
.map(i => parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options, i, true))
|
|
179
|
+
.map(i => parseNode(seenNodes, labeledNodes, includedItems, depIdMapping, options, leaves, i, true))
|
|
166
180
|
.filter(Boolean)
|
|
167
181
|
.join('\n');
|
|
168
|
-
const styleDefinition = highlightSelection ?
|
|
182
|
+
const styleDefinition = (highlightSelection ?
|
|
183
|
+
'\nclassDef a fill:gold,color:#242424'
|
|
184
|
+
: '') +
|
|
185
|
+
(leaves.size ? '\nclassDef b fill:turquoise,color:#242424' : '');
|
|
169
186
|
return 'flowchart TD\n' + graphOutput + styleDefinition;
|
|
170
187
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vltpkg/graph",
|
|
3
3
|
"description": "A library that helps understanding & expressing what happens on an install",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/vltpkg/vltpkg.git",
|
|
@@ -13,26 +13,26 @@
|
|
|
13
13
|
"url": "http://vlt.sh"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@vltpkg/cmd-shim": "1.
|
|
17
|
-
"@vltpkg/dep-id": "1.
|
|
18
|
-
"@vltpkg/dss-breadcrumb": "1.
|
|
19
|
-
"@vltpkg/error-cause": "1.
|
|
20
|
-
"@vltpkg/fast-split": "1.
|
|
21
|
-
"@vltpkg/graph-run": "1.
|
|
22
|
-
"@vltpkg/init": "1.
|
|
23
|
-
"@vltpkg/output": "1.
|
|
24
|
-
"@vltpkg/package-info": "1.
|
|
25
|
-
"@vltpkg/package-json": "1.
|
|
26
|
-
"@vltpkg/pick-manifest": "1.
|
|
27
|
-
"@vltpkg/query": "1.
|
|
28
|
-
"@vltpkg/rollback-remove": "1.
|
|
29
|
-
"@vltpkg/run": "1.
|
|
30
|
-
"@vltpkg/satisfies": "1.
|
|
31
|
-
"@vltpkg/security-archive": "1.
|
|
32
|
-
"@vltpkg/spec": "1.
|
|
33
|
-
"@vltpkg/types": "1.
|
|
34
|
-
"@vltpkg/vlt-json": "1.
|
|
35
|
-
"@vltpkg/workspaces": "1.
|
|
16
|
+
"@vltpkg/cmd-shim": "1.5.0",
|
|
17
|
+
"@vltpkg/dep-id": "1.5.0",
|
|
18
|
+
"@vltpkg/dss-breadcrumb": "1.5.0",
|
|
19
|
+
"@vltpkg/error-cause": "1.5.0",
|
|
20
|
+
"@vltpkg/fast-split": "1.5.0",
|
|
21
|
+
"@vltpkg/graph-run": "1.5.0",
|
|
22
|
+
"@vltpkg/init": "1.5.0",
|
|
23
|
+
"@vltpkg/output": "1.5.0",
|
|
24
|
+
"@vltpkg/package-info": "1.5.0",
|
|
25
|
+
"@vltpkg/package-json": "1.5.0",
|
|
26
|
+
"@vltpkg/pick-manifest": "1.5.0",
|
|
27
|
+
"@vltpkg/query": "1.5.0",
|
|
28
|
+
"@vltpkg/rollback-remove": "1.5.0",
|
|
29
|
+
"@vltpkg/run": "1.5.0",
|
|
30
|
+
"@vltpkg/satisfies": "1.5.0",
|
|
31
|
+
"@vltpkg/security-archive": "1.5.0",
|
|
32
|
+
"@vltpkg/spec": "1.5.0",
|
|
33
|
+
"@vltpkg/types": "1.5.0",
|
|
34
|
+
"@vltpkg/vlt-json": "1.5.0",
|
|
35
|
+
"@vltpkg/workspaces": "1.5.0",
|
|
36
36
|
"path-scurry": "^2.0.1",
|
|
37
37
|
"promise-call-limit": "^3.0.2"
|
|
38
38
|
},
|