diff --git a/workspaces/arborist/lib/arborist/load-actual.js b/workspaces/arborist/lib/arborist/load-actual.js index 0d260858d81c6..c06ed80265e02 100644 --- a/workspaces/arborist/lib/arborist/load-actual.js +++ b/workspaces/arborist/lib/arborist/load-actual.js @@ -212,7 +212,8 @@ module.exports = cls => class ActualLoader extends cls { const promises = [] for (const path of tree.workspaces.values()) { if (!this[_cache].has(path)) { - const p = this[_loadFSNode]({ path, root: this[_actualTree] }) + // workspace overrides use the root overrides + const p = this[_loadFSNode]({ path, root: this[_actualTree], useRootOverrides: true }) .then(node => this[_loadFSTree](node)) promises.push(p) } @@ -240,7 +241,7 @@ module.exports = cls => class ActualLoader extends cls { this[_actualTree] = root } - [_loadFSNode] ({ path, parent, real, root, loadOverrides }) { + [_loadFSNode] ({ path, parent, real, root, loadOverrides, useRootOverrides }) { if (!real) { return realpath(path, this[_rpcache], this[_stcache]) .then( @@ -250,6 +251,7 @@ module.exports = cls => class ActualLoader extends cls { real, root, loadOverrides, + useRootOverrides, }), // if realpath fails, just provide a dummy error node error => new Node({ @@ -289,6 +291,9 @@ module.exports = cls => class ActualLoader extends cls { parent, root, loadOverrides, + ...(useRootOverrides && root.overrides + ? { overrides: root.overrides.getNodeRule({ name: pkg.name, version: pkg.version }) } + : {}), }) }) .then(node => { diff --git a/workspaces/arborist/test/arborist/build-ideal-tree.js b/workspaces/arborist/test/arborist/build-ideal-tree.js index be3a40042a9fd..368df05bcfaf4 100644 --- a/workspaces/arborist/test/arborist/build-ideal-tree.js +++ b/workspaces/arborist/test/arborist/build-ideal-tree.js @@ -3744,6 +3744,50 @@ t.test('overrides', t => { t.equal(bcEdge.to.version, '2.0.0', 'b->c is 2.0.0') }) + t.test('overrides a workspace dependency', async (t) => { + generateNocks(t, { + bar: { + versions: ['1.0.0', '1.0.1', '2.0.0'], + }, + }) + + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'root', + dependencies: { + foo: '1.0.1', + }, + overrides: { + bar: '2.0.0', + }, + workspaces: [ + './workspaces/*', + ], + }), + workspaces: { + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.1', + dependencies: { + bar: '1.0.0', + }, + }), + }, + }, + }) + + const tree = await buildIdeal(path) + + const fooEdge = tree.edgesOut.get('foo') + t.equal(fooEdge.valid, true) + + // fooEdge.to is a link, so we need to look at the target for edgesOut + const fooBarEdge = fooEdge.to.target.edgesOut.get('bar') + t.equal(fooBarEdge.valid, true) + t.equal(fooBarEdge.to.version, '2.0.0') + }) + t.end() }) diff --git a/workspaces/arborist/test/arborist/load-actual.js b/workspaces/arborist/test/arborist/load-actual.js index 0da044c5aee4a..464bdc77ba058 100644 --- a/workspaces/arborist/test/arborist/load-actual.js +++ b/workspaces/arborist/test/arborist/load-actual.js @@ -422,3 +422,33 @@ t.test('load global space with link deps', async t => { }, }) }) + +t.test('loading a workspace maintains overrides', async t => { + const path = t.testdir({ + 'package.json': JSON.stringify({ + name: 'root', + version: '1.0.0', + dependencies: { + foo: '1.0.0', + }, + overrides: { + bar: '2.0.0', + }, + workspaces: ['./foo'], + }), + foo: { + 'package.json': JSON.stringify({ + name: 'foo', + version: '1.0.0', + dependencies: { + bar: '1.0.0', + }, + }), + }, + }) + + const tree = await loadActual(path) + + const fooEdge = tree.edgesOut.get('foo') + t.equal(tree.overrides, fooEdge.overrides, 'foo edge got the correct overrides') +})