Skip to content

Commit

Permalink
feat(arborist): add support for installLinks
Browse files Browse the repository at this point in the history
when set, installLinks instructs arborist to pack and extract a file:
dependency rather than creating a symlink to it. this has the effect of
also installing the dependencies for the linked dependency, though if
local changes are made it also requires the user to reinstall the
package
  • Loading branch information
nlf authored and lukekarrys committed Apr 19, 2022
1 parent 3d96494 commit 0ebadf5
Show file tree
Hide file tree
Showing 11 changed files with 471 additions and 10 deletions.
22 changes: 15 additions & 7 deletions workspaces/arborist/lib/arborist/build-ideal-tree.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
globalStyle = false,
idealTree = null,
includeWorkspaceRoot = false,
installLinks = false,
legacyPeerDeps = false,
packageLock = true,
strictPeerDeps = false,
Expand All @@ -135,6 +136,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
this[_strictPeerDeps] = !!strictPeerDeps

this.idealTree = idealTree
this.installLinks = installLinks
this.legacyPeerDeps = legacyPeerDeps

this[_usePackageLock] = packageLock
Expand Down Expand Up @@ -410,6 +412,7 @@ Try using the package name instead, e.g:
peer: false,
optional: false,
global: this[_global],
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
loadOverrides: true,
})
Expand All @@ -424,6 +427,7 @@ Try using the package name instead, e.g:
peer: false,
optional: false,
global: this[_global],
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
root,
})
Expand Down Expand Up @@ -992,6 +996,7 @@ This is a one-time fix-up, please be patient...
preferDedupe: this[_preferDedupe],
legacyBundling: this[_legacyBundling],
strictPeerDeps: this[_strictPeerDeps],
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
globalStyle: this[_globalStyle],
}))
Expand Down Expand Up @@ -1151,6 +1156,7 @@ This is a one-time fix-up, please be patient...
const vr = new Node({
path: node.realpath,
sourceReference: node,
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
overrides: node.overrides,
})
Expand Down Expand Up @@ -1268,17 +1274,18 @@ This is a one-time fix-up, please be patient...
// the object so it doesn't get mutated.
// 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
const { installLinks, legacyPeerDeps } = this
const isWorkspace = this.idealTree.workspaces && this.idealTree.workspaces.has(spec.name)

// spec is a directory, link it
if (spec.type === 'directory') {
// spec is a directory, link it unless installLinks is set or it's a workspace
if (spec.type === 'directory' && (isWorkspace || !installLinks)) {
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)) {
if (isWorkspace) {
const existingNode = this.idealTree.edgesOut.get(spec.name).to
if (existingNode && existingNode.isWorkspace && existingNode.satisfies(edge)) {
return edge.to
Expand All @@ -1288,7 +1295,7 @@ This is a one-time fix-up, please be patient...
// 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 => {
.then(pkg => new Node({ name, pkg, parent, installLinks, legacyPeerDeps }), error => {
error.requiredBy = edge.from.location || '.'

// failed to load the spec, either because of enotarget or
Expand All @@ -1298,6 +1305,7 @@ This is a one-time fix-up, please be patient...
name,
parent,
error,
installLinks,
legacyPeerDeps,
})
this[_loadFailures].add(n)
Expand All @@ -1307,9 +1315,9 @@ This is a one-time fix-up, please be patient...

[_linkFromSpec] (name, spec, parent, edge) {
const realpath = spec.fetchSpec
const { legacyPeerDeps } = this
const { installLinks, legacyPeerDeps } = this
return rpj(realpath + '/package.json').catch(() => ({})).then(pkg => {
const link = new Link({ name, parent, realpath, pkg, legacyPeerDeps })
const link = new Link({ name, parent, realpath, pkg, installLinks, legacyPeerDeps })
this[_linkNodes].add(link)
return link
})
Expand Down
1 change: 1 addition & 0 deletions workspaces/arborist/lib/arborist/load-actual.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ module.exports = cls => class ActualLoader extends cls {
.then(pkg => [pkg, null], error => [null, error])
.then(([pkg, error]) => {
return this[normalize(path) === real ? _newNode : _newLink]({
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
path,
realpath: real,
Expand Down
2 changes: 2 additions & 0 deletions workspaces/arborist/lib/arborist/load-virtual.js
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ module.exports = cls => class VirtualLoader extends cls {
const peer = sw.peer

const node = new Node({
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
root: this.virtualTree,
path,
Expand All @@ -304,6 +305,7 @@ module.exports = cls => class VirtualLoader extends cls {
[loadLink] (location, targetLoc, target, meta) {
const path = resolve(this.path, location)
const link = new Link({
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
path,
realpath: resolve(this.path, targetLoc),
Expand Down
16 changes: 13 additions & 3 deletions workspaces/arborist/lib/dep-valid.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,7 @@ const depValid = (child, requested, requestor) => {
return semver.satisfies(child.version, requested.fetchSpec, true)

case 'directory':
// directory must be a link to the specified folder
return !!child.isLink &&
relative(child.realpath, requested.fetchSpec) === ''
return linkValid(child, requested, requestor)

case 'file':
return tarballValid(child, requested, requestor)
Expand Down Expand Up @@ -108,6 +106,18 @@ const depValid = (child, requested, requestor) => {
return false
}

const linkValid = (child, requested, requestor) => {
const isLink = !!child.isLink
// if we're installing links and the node is a link, then it's invalid because we want
// a real node to be there
if (requestor.installLinks) {
return !isLink
}

// directory must be a link to the specified folder
return isLink && relative(child.realpath, requested.fetchSpec) === ''
}

const tarballValid = (child, requested, requestor) => {
if (child.isLink) {
return false
Expand Down
2 changes: 2 additions & 0 deletions workspaces/arborist/lib/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ class Node {
name,
children,
fsChildren,
installLinks = false,
legacyPeerDeps = false,
linksIn,
hasShrinkwrap,
Expand Down Expand Up @@ -152,6 +153,7 @@ class Node {
}
this.integrity = integrity || pkg._integrity || null
this.hasShrinkwrap = hasShrinkwrap || pkg._hasShrinkwrap || false
this.installLinks = installLinks
this.legacyPeerDeps = legacyPeerDeps

this.children = new CaseInsensitiveMap()
Expand Down
3 changes: 3 additions & 0 deletions workspaces/arborist/lib/place-dep.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class PlaceDep {
auditReport,
legacyBundling,
strictPeerDeps,
installLinks,
legacyPeerDeps,
globalStyle,
} = parent || options
Expand All @@ -56,6 +57,7 @@ class PlaceDep {
auditReport,
legacyBundling,
strictPeerDeps,
installLinks,
legacyPeerDeps,
globalStyle,
})
Expand Down Expand Up @@ -293,6 +295,7 @@ class PlaceDep {
pkg: dep.package,
resolved: dep.resolved,
integrity: dep.integrity,
installLinks: this.installLinks,
legacyPeerDeps: this.legacyPeerDeps,
error: dep.errors[0],
...(dep.overrides ? { overrides: dep.overrides } : {}),
Expand Down
4 changes: 4 additions & 0 deletions workspaces/arborist/tap-snapshots/test/link.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ Link {
"extraneous": true,
"fsChildren": Set {},
"hasShrinkwrap": false,
"installLinks": false,
"integrity": null,
"inventory": Inventory {},
"legacyPeerDeps": false,
Expand All @@ -42,6 +43,7 @@ exports[`test/link.js TAP > instantiate without providing target 1`] = `
"extraneous": true,
"fsChildren": Set {},
"hasShrinkwrap": false,
"installLinks": false,
"integrity": null,
"inventory": Inventory {
"../../../../../some/other/path" => <*ref_1>,
Expand All @@ -56,6 +58,7 @@ exports[`test/link.js TAP > instantiate without providing target 1`] = `
"extraneous": true,
"fsChildren": Set {},
"hasShrinkwrap": false,
"installLinks": false,
"integrity": null,
"inventory": Inventory {},
"legacyPeerDeps": false,
Expand Down Expand Up @@ -94,6 +97,7 @@ exports[`test/link.js TAP > instantiate without providing target 1`] = `
"extraneous": true,
"fsChildren": Set {},
"hasShrinkwrap": false,
"installLinks": false,
"integrity": null,
"inventory": Inventory {},
"legacyPeerDeps": false,
Expand Down
Loading

0 comments on commit 0ebadf5

Please sign in to comment.