Skip to content

Commit

Permalink
fix(arborist): use the sourceReference root rather than the node root…
Browse files Browse the repository at this point in the history
… for overrides (#5227)

when we examine override references, if we look at only `this.from.root.package` the root could actually be a virtual one. in order to ensure we resolve references from the real root, we instead need to look at `this.from.sourceReference.root.package` to get the correct value.

closes #4395
  • Loading branch information
nlf committed Aug 1, 2022
1 parent a6153cf commit 47cc95d
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 1 deletion.
6 changes: 5 additions & 1 deletion workspaces/arborist/lib/edge.js
Expand Up @@ -169,7 +169,11 @@ class Edge {
if (this.overrides && this.overrides.value && this.overrides.name === this.name) {
if (this.overrides.value.startsWith('$')) {
const ref = this.overrides.value.slice(1)
const pkg = this.from.root.package
// we may be a virtual root, if we are we want to resolve reference overrides
// from the real root, not the virtual one
const pkg = this.from.sourceReference
? this.from.sourceReference.root.package
: this.from.root.package
const overrideSpec = (pkg.devDependencies && pkg.devDependencies[ref]) ||
(pkg.optionalDependencies && pkg.optionalDependencies[ref]) ||
(pkg.dependencies && pkg.dependencies[ref]) ||
Expand Down
141 changes: 141 additions & 0 deletions workspaces/arborist/test/edge.js
Expand Up @@ -809,6 +809,147 @@ t.same(bundledEdge.explain(), {
from: bundleParent.explain(),
}, 'bundled edge.explain as expected')

t.test('override references find the correct root', (t) => {
const overrides = new OverrideSet({
overrides: {
foo: '$foo',
},
})

const root = {
name: 'root',
packageName: 'root',
edgesOut: new Map(),
edgesIn: new Set(),
explain: () => 'root node explanation',
package: {
name: 'root',
version: '1.2.3',
dependencies: {
foo: '^1.0.0',
},
overrides: {
foo: '$foo',
},
},
get version () {
return this.package.version
},
isTop: true,
parent: null,
overrides,
resolve (n) {
return n === 'foo' ? foo : null
},
addEdgeOut (edge) {
this.edgesOut.set(edge.name, edge)
},
addEdgeIn (edge) {
this.edgesIn.add(edge)
},
}

const foo = {
name: 'foo',
packageName: 'foo',
edgesOut: new Map(),
edgesIn: new Set(),
explain: () => 'foo node explanation',
package: {
name: 'foo',
version: '1.2.3',
dependencies: {},
},
get version () {
return this.package.version
},
parent: root,
root: root,
resolve (n) {
return n === 'bar' ? bar : this.parent.resolve(n)
},
addEdgeOut (edge) {
this.edgesOut.set(edge.name, edge)
},
addEdgeIn (edge) {
this.edgesIn.add(edge)
},
}
foo.overrides = overrides.getNodeRule(foo)

const bar = {
name: 'bar',
packageName: 'bar',
edgesOut: new Map(),
edgesIn: new Set(),
explain: () => 'bar node explanation',
package: {
name: 'bar',
version: '1.2.3',
dependencies: {
foo: '^2.0.0',
},
},
get version () {
return this.package.version
},
parent: foo,
root: root,
resolve (n) {
return this.parent.resolve(n)
},
addEdgeOut (edge) {
this.edgesOut.set(edge.name, edge)
},
addEdgeIn (edge) {
this.edgesIn.add(edge)
},
}
bar.overrides = foo.overrides.getNodeRule(bar)

const virtualBar = {
name: 'bar',
packageName: 'bar',
edgesOut: new Map(),
edgesIn: new Set(),
explain: () => 'bar node explanation',
package: {
name: 'bar',
version: '1.2.3',
dependencies: {
foo: '^2.0.0',
},
},
parent: null,
root: null,
sourceReference: bar,
get version () {
return this.package.version
},
resolve (n) {
return bar.resolve(n)
},
addEdgeOut (edge) {
this.edgesOut.set(edge.name, edge)
},
addEdgeIn (edge) {
this.edgesIn.add(edge)
},
}
virtualBar.overrides = overrides

const edge = new Edge({
from: virtualBar,
type: 'prod',
spec: '^2.0.0',
name: 'foo',
overrides: overrides.getEdgeRule({ name: 'foo', spec: '^2.0.0' }),
})

t.ok(edge.valid, 'edge is valid')
t.end()
})

t.test('shrinkwrapped and bundled deps are not overridden and remain valid', (t) => {
const overrides = new OverrideSet({
overrides: {
Expand Down

0 comments on commit 47cc95d

Please sign in to comment.