Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornlf <quitlahok@gmail.com>2022-02-07 20:35:36 +0300
committerGitHub <noreply@github.com>2022-02-07 20:35:36 +0300
commit2ba09cc0d7d56a064aa67bbb1881d381e6504888 (patch)
treecdcc2cab2a871d4c6a3512c0154932c0f65c15d6 /workspaces/arborist/lib
parent415a70b204b33d7e74476aa48833e8a6d0b77fc5 (diff)
fix(arborist): check if a spec is a workspace before fetching a manifest, closes #3637 (#4371)
Diffstat (limited to 'workspaces/arborist/lib')
-rw-r--r--workspaces/arborist/lib/arborist/build-ideal-tree.js50
1 files changed, 33 insertions, 17 deletions
diff --git a/workspaces/arborist/lib/arborist/build-ideal-tree.js b/workspaces/arborist/lib/arborist/build-ideal-tree.js
index 0375e1851..b7bc56f3e 100644
--- a/workspaces/arborist/lib/arborist/build-ideal-tree.js
+++ b/workspaces/arborist/lib/arborist/build-ideal-tree.js
@@ -1250,24 +1250,40 @@ This is a one-time fix-up, please be patient...
// Don't bother to load the manifest for link deps, because the target
// might be within another package that doesn't exist yet.
const { legacyPeerDeps } = this
- return spec.type === 'directory'
- ? this[_linkFromSpec](name, spec, parent, edge)
- : this[_fetchManifest](spec)
- .then(pkg => new Node({ name, pkg, parent, legacyPeerDeps }), error => {
- error.requiredBy = edge.from.location || '.'
-
- // failed to load the spec, either because of enotarget or
- // fetch failure of some other sort. save it so we can verify
- // later that it's optional, otherwise the error is fatal.
- const n = new Node({
- name,
- parent,
- error,
- legacyPeerDeps,
- })
- this[_loadFailures].add(n)
- return n
+
+ // spec is a directory, link it
+ if (spec.type === 'directory') {
+ return this[_linkFromSpec](name, spec, parent, edge)
+ }
+
+ // if the spec matches a workspace name, then see if the workspace node will
+ // satisfy the edge. if it does, we return the workspace node to make sure it
+ // takes priority.
+ if (this.idealTree.workspaces && this.idealTree.workspaces.has(spec.name)) {
+ const existingNode = this.idealTree.edgesOut.get(spec.name).to
+ if (existingNode && existingNode.isWorkspace && existingNode.satisfies(edge)) {
+ return edge.to
+ }
+ }
+
+ // spec isn't a directory, and either isn't a workspace or the workspace we have
+ // doesn't satisfy the edge. try to fetch a manifest and build a node from that.
+ return this[_fetchManifest](spec)
+ .then(pkg => new Node({ name, pkg, parent, legacyPeerDeps }), error => {
+ error.requiredBy = edge.from.location || '.'
+
+ // failed to load the spec, either because of enotarget or
+ // fetch failure of some other sort. save it so we can verify
+ // later that it's optional, otherwise the error is fatal.
+ const n = new Node({
+ name,
+ parent,
+ error,
+ legacyPeerDeps,
})
+ this[_loadFailures].add(n)
+ return n
+ })
}
[_linkFromSpec] (name, spec, parent, edge) {