Skip to content

Commit

Permalink
deps: @npmcli/[email protected]
Browse files Browse the repository at this point in the history
PR-URL: #4116
Credit: @nlf
Close: #4116
Reviewed-by: @wraithgar
  • Loading branch information
nlf authored and wraithgar committed Dec 8, 2021
1 parent 4dbeb00 commit 4b0c29a
Show file tree
Hide file tree
Showing 11 changed files with 258 additions and 19 deletions.
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

0 comments on commit 4b0c29a

Please sign in to comment.