diff options
author | nlf <quitlahok@gmail.com> | 2022-02-07 20:35:36 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-02-07 20:35:36 +0300 |
commit | 2ba09cc0d7d56a064aa67bbb1881d381e6504888 (patch) | |
tree | cdcc2cab2a871d4c6a3512c0154932c0f65c15d6 /workspaces/arborist/lib | |
parent | 415a70b204b33d7e74476aa48833e8a6d0b77fc5 (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.js | 50 |
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) { |