Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deps: @npmcli/arborist@4.1.0 #4116

Merged
merged 1 commit into from
Dec 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
optional: false,
global: this[_global],
legacyPeerDeps: this.legacyPeerDeps,
loadOverrides: true,
})
if (root.isLink) {
root.target = new Node({
Expand Down Expand Up @@ -676,6 +677,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
// calls rather than walking over everything in the tree.
const set = this.idealTree.inventory
.filter(n => this[_shouldUpdateNode](n))
// XXX add any invalid edgesOut to the queue
for (const node of set) {
for (const edge of node.edgesIn) {
this.addTracker('idealTree', edge.from.name, edge.from.location)
Expand Down Expand Up @@ -772,7 +774,10 @@ This is a one-time fix-up, please be patient...
[_buildDeps] () {
process.emit('time', 'idealTree:buildDeps')
const tree = this.idealTree.target
tree.assertRootOverrides()
this[_depsQueue].push(tree)
// XXX also push anything that depends on a node with a name
// in the override list
this.log.silly('idealTree', 'buildDeps')
this.addTracker('idealTree', tree.name, '')
return this[_buildDepStep]()
Expand Down Expand Up @@ -1112,6 +1117,7 @@ This is a one-time fix-up, please be patient...
path: node.realpath,
sourceReference: node,
legacyPeerDeps: this.legacyPeerDeps,
overrides: node.overrides,
})

// also need to set up any targets from any link deps, so that
Expand Down
24 changes: 21 additions & 3 deletions node_modules/@npmcli/arborist/lib/arborist/load-actual.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ module.exports = cls => class ActualLoader extends cls {
realpath: real,
pkg: {},
global,
loadOverrides: true,
})
return this[_loadActualActually]({ root, ignoreMissing, global })
}
Expand All @@ -135,8 +136,11 @@ module.exports = cls => class ActualLoader extends cls {
this[_actualTree] = await this[_loadFSNode]({
path: this.path,
real: await realpath(this.path, this[_rpcache], this[_stcache]),
loadOverrides: true,
})

this[_actualTree].assertRootOverrides()

// Note: hidden lockfile will be rejected if it's not the latest thing
// in the folder, or if any of the entries in the hidden lockfile are
// missing.
Expand Down Expand Up @@ -236,13 +240,26 @@ module.exports = cls => class ActualLoader extends cls {
this[_actualTree] = root
}

[_loadFSNode] ({ path, parent, real, root }) {
[_loadFSNode] ({ path, parent, real, root, loadOverrides }) {
if (!real) {
return realpath(path, this[_rpcache], this[_stcache])
.then(
real => this[_loadFSNode]({ path, parent, real, root }),
real => this[_loadFSNode]({
path,
parent,
real,
root,
loadOverrides,
}),
// if realpath fails, just provide a dummy error node
error => new Node({ error, path, realpath: path, parent, root })
error => new Node({
error,
path,
realpath: path,
parent,
root,
loadOverrides,
})
)
}

Expand Down Expand Up @@ -271,6 +288,7 @@ module.exports = cls => class ActualLoader extends cls {
error,
parent,
root,
loadOverrides,
})
})
.then(node => {
Expand Down
1 change: 1 addition & 0 deletions node_modules/@npmcli/arborist/lib/arborist/load-virtual.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ module.exports = cls => class VirtualLoader extends cls {
this[rootOptionProvided] = options.root

await this[loadFromShrinkwrap](s, root)
root.assertRootOverrides()
return treeCheck(this.virtualTree)
}

Expand Down
41 changes: 38 additions & 3 deletions node_modules/@npmcli/arborist/lib/edge.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ArboristEdge {}
const printableEdge = (edge) => {
const edgeFrom = edge.from && edge.from.location
const edgeTo = edge.to && edge.to.location
const override = edge.overrides && edge.overrides.value

return Object.assign(new ArboristEdge(), {
name: edge.name,
Expand All @@ -38,12 +39,13 @@ const printableEdge = (edge) => {
...(edgeTo ? { to: edgeTo } : {}),
...(edge.error ? { error: edge.error } : {}),
...(edge.peerConflicted ? { peerConflicted: true } : {}),
...(override ? { overridden: override } : {}),
})
}

class Edge {
constructor (options) {
const { type, name, spec, accept, from } = options
const { type, name, spec, accept, from, overrides } = options

if (typeof spec !== 'string') {
throw new TypeError('must provide string spec')
Expand All @@ -55,6 +57,10 @@ class Edge {

this[_spec] = spec

if (overrides !== undefined) {
this.overrides = overrides
}

if (accept !== undefined) {
if (typeof accept !== 'string') {
throw new TypeError('accept field must be a string if provided')
Expand Down Expand Up @@ -82,8 +88,11 @@ class Edge {
}

satisfiedBy (node) {
return node.name === this.name &&
depValid(node, this.spec, this.accept, this.from)
if (node.name !== this.name) {
return false
}

return depValid(node, this.spec, this.accept, this.from)
}

explain (seen = []) {
Expand All @@ -101,6 +110,10 @@ class Edge {
type: this.type,
name: this.name,
spec: this.spec,
...(this.rawSpec !== this.spec ? {
rawSpec: this.rawSpec,
overridden: true,
} : {}),
...(bundled ? { bundled } : {}),
...(error ? { error } : {}),
...(from ? { from: from.explain(null, seen) } : {}),
Expand Down Expand Up @@ -143,7 +156,28 @@ class Edge {
return this[_name]
}

get rawSpec () {
return this[_spec]
}

get spec () {
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
const overrideSpec = (pkg.devDependencies && pkg.devDependencies[ref]) ||
(pkg.optionalDependencies && pkg.optionalDependencies[ref]) ||
(pkg.dependencies && pkg.dependencies[ref]) ||
(pkg.peerDependencies && pkg.peerDependencies[ref])

if (overrideSpec) {
return overrideSpec
}

throw new Error(`Unable to resolve reference ${this.overrides.value}`)
}
return this.overrides.value
}
return this[_spec]
}

Expand Down Expand Up @@ -213,6 +247,7 @@ class Edge {
if (node.edgesOut.has(this.name)) {
node.edgesOut.get(this.name).detach()
}

node.addEdgeOut(this)
this.reload()
}
Expand Down
45 changes: 45 additions & 0 deletions node_modules/@npmcli/arborist/lib/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const semver = require('semver')
const nameFromFolder = require('@npmcli/name-from-folder')
const Edge = require('./edge.js')
const Inventory = require('./inventory.js')
const OverrideSet = require('./override-set.js')
const { normalize } = require('read-package-json-fast')
const { getPaths: getBinPaths } = require('bin-links')
const npa = require('npm-package-arg')
Expand Down Expand Up @@ -88,6 +89,8 @@ class Node {
legacyPeerDeps = false,
linksIn,
hasShrinkwrap,
overrides,
loadOverrides = false,
extraneous = true,
dev = true,
optional = true,
Expand Down Expand Up @@ -190,6 +193,17 @@ class Node {
// because this.package is read when adding to inventory
this[_package] = pkg && typeof pkg === 'object' ? pkg : {}

if (overrides) {
this.overrides = overrides
} else if (loadOverrides) {
const overrides = this[_package].overrides || {}
if (Object.keys(overrides).length > 0) {
this.overrides = new OverrideSet({
overrides: this[_package].overrides,
})
}
}

// only relevant for the root and top nodes
this.meta = meta

Expand Down Expand Up @@ -963,6 +977,11 @@ class Node {
return false
}

// XXX need to check for two root nodes?
if (node.overrides !== this.overrides) {
return false
}

ignorePeers = new Set(ignorePeers)

// gather up all the deps of this node and that are only depended
Expand Down Expand Up @@ -1208,6 +1227,10 @@ class Node {
this[_changePath](newPath)
}

if (parent.overrides) {
this.overrides = parent.overrides.getNodeRule(this)
}

// clobbers anything at that path, resets all appropriate references
this.root = parent.root
}
Expand Down Expand Up @@ -1279,11 +1302,33 @@ class Node {
}
}

assertRootOverrides () {
if (!this.isProjectRoot || !this.overrides) {
return
}

for (const edge of this.edgesOut.values()) {
// if these differ an override has been applied, those are not allowed
// for top level dependencies so throw an error
if (edge.spec !== edge.rawSpec && !edge.spec.startsWith('$')) {
throw Object.assign(new Error(`Override for ${edge.name}@${edge.rawSpec} conflicts with direct dependency`), { code: 'EOVERRIDE' })
}
}
}

addEdgeOut (edge) {
if (this.overrides) {
edge.overrides = this.overrides.getEdgeRule(edge)
}

this.edgesOut.set(edge.name, edge)
}

addEdgeIn (edge) {
if (edge.overrides) {
this.overrides = edge.overrides
}

this.edgesIn.add(edge)

// try to get metadata from the yarn.lock file
Expand Down
Loading