@vltpkg/graph 1.0.0-rc.30 → 1.0.0-rc.32

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.
@@ -175,6 +175,19 @@ const fetchManifestsForDeps = async (packageInfo, graph, fromNode, deps, scurry,
175
175
  reuseTasks.push({ type, spec, fromNode, toNode: existingNode });
176
176
  continue;
177
177
  }
178
+ // workspace: specs can only resolve to local workspace packages.
179
+ // If we didn't find a matching workspace node above, it means either
180
+ // the workspace doesn't exist or its version doesn't satisfy the range.
181
+ if (spec.final.type === 'workspace') {
182
+ const wsVersion = graph.nodesByName
183
+ .get(spec.name)
184
+ ?.values()
185
+ .next().value?.version;
186
+ throw error(wsVersion ?
187
+ `workspace dependency ${spec} does not match the ` +
188
+ `local workspace version (${wsVersion})`
189
+ : `no workspace found matching ${spec}`, { spec });
190
+ }
178
191
  // is the current edge pointint go an optional dependency?
179
192
  const edgeOptional = type === 'optional' || type === 'peerOptional';
180
193
  // Start manifest fetch immediately for parallel processing
@@ -49,8 +49,20 @@ export const getImporterSpecs = (options) => {
49
49
  // skip if the edge exists and already uses the same spec
50
50
  if (edge?.to && depSpec === edge.spec.bareSpec)
51
51
  continue;
52
+ const spec = Spec.parse(depName, depSpec, options);
53
+ // if a workspace dep references a workspace that no longer exists
54
+ // (folder was removed), mark it for removal instead of trying to
55
+ // resolve it — the workspace can't be satisfied
56
+ if (spec.type === 'workspace' && !edge?.to) {
57
+ const wsExists = [...graph.importers].some(n => n.name === depName);
58
+ if (!wsExists) {
59
+ removeDeps.add(depName);
60
+ removeResult.modifiedDependencies = true;
61
+ continue;
62
+ }
63
+ }
52
64
  const dependency = asDependency({
53
- spec: Spec.parse(depName, depSpec, options),
65
+ spec,
54
66
  type: shorten(depType, depName, importer.manifest),
55
67
  });
56
68
  addDeps.set(depName, dependency);
@@ -7,6 +7,11 @@ import { isDependencyTypeShort } from "../dependencies.js";
7
7
  const retrieveNodeFromGraph = (key, value, graph, fromId, seenNodes) => {
8
8
  const foundNode = graph.nodes.get(asDepID(fromId));
9
9
  if (!foundNode) {
10
+ // workspace or file nodes may be missing if the folder was removed
11
+ // while still referenced in the lockfile — skip gracefully
12
+ if (fromId.startsWith('workspace') || fromId.startsWith('file')) {
13
+ return undefined;
14
+ }
10
15
  throw error('Edge info missing its `from` node', {
11
16
  found: {
12
17
  nodes: [...graph.nodes].map(([id]) => id),
@@ -59,6 +64,9 @@ export const loadEdges = (graph, edges, options) => {
59
64
  else {
60
65
  fromNode = retrieveNodeFromGraph(key, value, graph, fromId);
61
66
  }
67
+ // skip edges from workspace nodes that no longer exist
68
+ if (!fromNode)
69
+ continue;
62
70
  const toId = valRest.substring(vrSplit + 1);
63
71
  let toNode = undefined;
64
72
  if (toId !== 'MISSING') {
@@ -70,7 +70,25 @@ export const reify = async (options) => {
70
70
  const skippable = skipOptionalOnly && !options.update;
71
71
  const res = { diff };
72
72
  if (!diff.hasChanges() || skippable) {
73
- // nothing to do, so just return the diff
73
+ // Even when there are no changes to reify, ensure lockfiles
74
+ // exist on disk. This handles the case where a project has no
75
+ // dependencies (or only workspace importers) but still needs
76
+ // lockfiles written on the first install.
77
+ if (!scurry.lstatSync('vlt-lock.json') ||
78
+ !scurry.lstatSync('node_modules/.vlt-lock.json')) {
79
+ saveHidden(options);
80
+ const lfData = lockfileData(options);
81
+ saveData(lfData, scurry.resolve('vlt-lock.json'), false);
82
+ }
83
+ // Even with no reify changes, report nodes that still need building.
84
+ // Build state is persisted in the hidden lockfile and loaded into the
85
+ // actual graph, so check there for pending builds.
86
+ const pending = [...actual.nodes.values()]
87
+ .filter(n => n.buildState === 'needed')
88
+ .map(n => n.id);
89
+ if (pending.length) {
90
+ res.buildQueue = pending;
91
+ }
74
92
  done();
75
93
  return res;
76
94
  }
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.0.0-rc.30",
4
+ "version": "1.0.0-rc.32",
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.0.0-rc.30",
17
- "@vltpkg/dep-id": "1.0.0-rc.30",
18
- "@vltpkg/dss-breadcrumb": "1.0.0-rc.30",
19
- "@vltpkg/error-cause": "1.0.0-rc.30",
20
- "@vltpkg/fast-split": "1.0.0-rc.30",
21
- "@vltpkg/graph-run": "1.0.0-rc.30",
22
- "@vltpkg/init": "1.0.0-rc.30",
23
- "@vltpkg/output": "1.0.0-rc.30",
24
- "@vltpkg/package-info": "1.0.0-rc.30",
25
- "@vltpkg/package-json": "1.0.0-rc.30",
26
- "@vltpkg/pick-manifest": "1.0.0-rc.30",
27
- "@vltpkg/query": "1.0.0-rc.30",
28
- "@vltpkg/rollback-remove": "1.0.0-rc.30",
29
- "@vltpkg/run": "1.0.0-rc.30",
30
- "@vltpkg/satisfies": "1.0.0-rc.30",
31
- "@vltpkg/security-archive": "1.0.0-rc.30",
32
- "@vltpkg/spec": "1.0.0-rc.30",
33
- "@vltpkg/types": "1.0.0-rc.30",
34
- "@vltpkg/vlt-json": "1.0.0-rc.30",
35
- "@vltpkg/workspaces": "1.0.0-rc.30",
16
+ "@vltpkg/cmd-shim": "1.0.0-rc.32",
17
+ "@vltpkg/dep-id": "1.0.0-rc.32",
18
+ "@vltpkg/dss-breadcrumb": "1.0.0-rc.32",
19
+ "@vltpkg/error-cause": "1.0.0-rc.32",
20
+ "@vltpkg/fast-split": "1.0.0-rc.32",
21
+ "@vltpkg/graph-run": "1.0.0-rc.32",
22
+ "@vltpkg/init": "1.0.0-rc.32",
23
+ "@vltpkg/output": "1.0.0-rc.32",
24
+ "@vltpkg/package-info": "1.0.0-rc.32",
25
+ "@vltpkg/package-json": "1.0.0-rc.32",
26
+ "@vltpkg/pick-manifest": "1.0.0-rc.32",
27
+ "@vltpkg/query": "1.0.0-rc.32",
28
+ "@vltpkg/rollback-remove": "1.0.0-rc.32",
29
+ "@vltpkg/run": "1.0.0-rc.32",
30
+ "@vltpkg/satisfies": "1.0.0-rc.32",
31
+ "@vltpkg/security-archive": "1.0.0-rc.32",
32
+ "@vltpkg/spec": "1.0.0-rc.32",
33
+ "@vltpkg/types": "1.0.0-rc.32",
34
+ "@vltpkg/vlt-json": "1.0.0-rc.32",
35
+ "@vltpkg/workspaces": "1.0.0-rc.32",
36
36
  "path-scurry": "^2.0.1",
37
37
  "promise-call-limit": "^3.0.2"
38
38
  },