@npmcli/arborist 2.2.4 → 2.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/arborist/build-ideal-tree.js +20 -4
- package/lib/arborist/index.js +2 -0
- package/lib/arborist/reify.js +18 -2
- package/lib/edge.js +9 -1
- package/lib/printable.js +14 -3
- package/lib/shrinkwrap.js +37 -5
- package/lib/tracker.js +2 -3
- package/package.json +11 -6
|
@@ -431,11 +431,13 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
431
431
|
// ie, doing `foo@bar` we just return foo
|
|
432
432
|
// but if it's a url or git, we don't know the name until we
|
|
433
433
|
// fetch it and look in its manifest.
|
|
434
|
-
return Promise.all(add.map(rawSpec =>
|
|
435
|
-
|
|
434
|
+
return Promise.all(add.map(rawSpec => {
|
|
435
|
+
// We do NOT provide the path here, because user-additions need
|
|
436
|
+
// to be resolved relative to the CWD the user is in.
|
|
437
|
+
return this[_retrieveSpecName](npa(rawSpec))
|
|
436
438
|
.then(add => this[_updateFilePath](add))
|
|
437
439
|
.then(add => this[_followSymlinkPath](add))
|
|
438
|
-
)).then(add => {
|
|
440
|
+
})).then(add => {
|
|
439
441
|
this[_resolvedAdd] = add
|
|
440
442
|
// now add is a list of spec objects with names.
|
|
441
443
|
// find a home for each of them!
|
|
@@ -881,6 +883,8 @@ This is a one-time fix-up, please be patient...
|
|
|
881
883
|
// create a virtual root node with the same deps as the node that
|
|
882
884
|
// is requesting this one, so that we can get all the peer deps in
|
|
883
885
|
// a context where they're likely to be resolvable.
|
|
886
|
+
// Note that the virtual root will also have virtual copies of the
|
|
887
|
+
// targets of any child Links, so that they resolve appropriately.
|
|
884
888
|
const parent = parent_ || this[_virtualRoot](edge.from)
|
|
885
889
|
const realParent = edge.peer ? edge.from.resolveParent : edge.from
|
|
886
890
|
|
|
@@ -934,11 +938,23 @@ This is a one-time fix-up, please be patient...
|
|
|
934
938
|
return this[_virtualRoots].get(node)
|
|
935
939
|
|
|
936
940
|
const vr = new Node({
|
|
937
|
-
path:
|
|
941
|
+
path: node.realpath,
|
|
938
942
|
sourceReference: node,
|
|
939
943
|
legacyPeerDeps: this.legacyPeerDeps,
|
|
940
944
|
})
|
|
941
945
|
|
|
946
|
+
// also need to set up any targets from any link deps, so that
|
|
947
|
+
// they are properly reflected in the virtual environment
|
|
948
|
+
for (const child of node.children.values()) {
|
|
949
|
+
if (child.isLink) {
|
|
950
|
+
new Node({
|
|
951
|
+
path: child.realpath,
|
|
952
|
+
sourceReference: child.target,
|
|
953
|
+
root: vr,
|
|
954
|
+
})
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
|
|
942
958
|
this[_virtualRoots].set(node, vr)
|
|
943
959
|
return vr
|
|
944
960
|
}
|
package/lib/arborist/index.js
CHANGED
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
|
|
29
29
|
const {resolve} = require('path')
|
|
30
30
|
const {homedir} = require('os')
|
|
31
|
+
const procLog = require('../proc-log.js')
|
|
31
32
|
|
|
32
33
|
const mixins = [
|
|
33
34
|
require('../tracker.js'),
|
|
@@ -54,6 +55,7 @@ class Arborist extends Base {
|
|
|
54
55
|
path: options.path || '.',
|
|
55
56
|
cache: options.cache || `${homedir()}/.npm/_cacache`,
|
|
56
57
|
packumentCache: new Map(),
|
|
58
|
+
log: options.log || procLog,
|
|
57
59
|
}
|
|
58
60
|
this.cache = resolve(this.options.cache)
|
|
59
61
|
this.path = resolve(this.options.path)
|
package/lib/arborist/reify.js
CHANGED
|
@@ -6,6 +6,7 @@ const rpj = require('read-package-json-fast')
|
|
|
6
6
|
const { updateDepSpec } = require('../dep-spec.js')
|
|
7
7
|
const AuditReport = require('../audit-report.js')
|
|
8
8
|
const {subset} = require('semver')
|
|
9
|
+
const npa = require('npm-package-arg')
|
|
9
10
|
|
|
10
11
|
const {dirname, resolve, relative} = require('path')
|
|
11
12
|
const {depth: dfwalk} = require('treeverse')
|
|
@@ -881,11 +882,17 @@ module.exports = cls => class Reifier extends cls {
|
|
|
881
882
|
|
|
882
883
|
process.emit('time', 'reify:save')
|
|
883
884
|
|
|
885
|
+
// resolvedAdd is the list of user add requests, but with names added
|
|
886
|
+
// to things like git repos and tarball file/urls. However, if the
|
|
887
|
+
// user requested 'foo@', and we have a foo@file:../foo, then we should
|
|
888
|
+
// end up saving the spec we actually used, not whatever they gave us.
|
|
884
889
|
if (this[_resolvedAdd]) {
|
|
885
890
|
const root = this.idealTree
|
|
886
891
|
const pkg = root.package
|
|
887
|
-
for (const
|
|
888
|
-
const
|
|
892
|
+
for (const { name } of this[_resolvedAdd]) {
|
|
893
|
+
const req = npa(root.edgesOut.get(name).spec, root.realpath)
|
|
894
|
+
const {rawSpec, subSpec} = req
|
|
895
|
+
|
|
889
896
|
const spec = subSpec ? subSpec.rawSpec : rawSpec
|
|
890
897
|
const child = root.children.get(name)
|
|
891
898
|
|
|
@@ -910,6 +917,15 @@ module.exports = cls => class Reifier extends cls {
|
|
|
910
917
|
const save = h.https && h.auth ? `git+${h.https(opt)}`
|
|
911
918
|
: h.shortcut(opt)
|
|
912
919
|
updateDepSpec(pkg, name, save)
|
|
920
|
+
} else if (req.type === 'directory' || req.type === 'file') {
|
|
921
|
+
// save the relative path in package.json
|
|
922
|
+
// Normally saveSpec is updated with the proper relative
|
|
923
|
+
// path already, but it's possible to specify a full absolute
|
|
924
|
+
// path initially, in which case we can end up with the wrong
|
|
925
|
+
// thing, so just get the ultimate fetchSpec and relativize it.
|
|
926
|
+
const p = req.fetchSpec.replace(/^file:/, '')
|
|
927
|
+
const rel = relpath(root.realpath, p)
|
|
928
|
+
updateDepSpec(pkg, name, `file:${rel}`)
|
|
913
929
|
} else
|
|
914
930
|
updateDepSpec(pkg, name, req.saveSpec)
|
|
915
931
|
}
|
package/lib/edge.js
CHANGED
|
@@ -87,16 +87,24 @@ class Edge {
|
|
|
87
87
|
|
|
88
88
|
// return the edge data, and an explanation of how that edge came to be here
|
|
89
89
|
[_explain] (seen) {
|
|
90
|
-
const { error, from } = this
|
|
90
|
+
const { error, from, bundled } = this
|
|
91
91
|
return {
|
|
92
92
|
type: this.type,
|
|
93
93
|
name: this.name,
|
|
94
94
|
spec: this.spec,
|
|
95
|
+
...(bundled ? { bundled } : {}),
|
|
95
96
|
...(error ? { error } : {}),
|
|
96
97
|
...(from ? { from: from.explain(null, seen) } : {}),
|
|
97
98
|
}
|
|
98
99
|
}
|
|
99
100
|
|
|
101
|
+
get bundled () {
|
|
102
|
+
if (!this.from)
|
|
103
|
+
return false
|
|
104
|
+
const { package: { bundleDependencies = [] } } = this.from
|
|
105
|
+
return bundleDependencies.includes(this.name)
|
|
106
|
+
}
|
|
107
|
+
|
|
100
108
|
get workspace () {
|
|
101
109
|
return this[_type] === 'workspace'
|
|
102
110
|
}
|
package/lib/printable.js
CHANGED
|
@@ -63,6 +63,13 @@ class ArboristNode {
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
class ArboristVirtualNode extends ArboristNode {
|
|
67
|
+
constructor (tree, path) {
|
|
68
|
+
super(tree, path)
|
|
69
|
+
this.sourceReference = printableTree(tree.sourceReference, path)
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
66
73
|
class ArboristLink extends ArboristNode {
|
|
67
74
|
constructor (tree, path) {
|
|
68
75
|
super(tree, path)
|
|
@@ -119,10 +126,14 @@ class EdgeIn extends Edge {
|
|
|
119
126
|
}
|
|
120
127
|
|
|
121
128
|
const printableTree = (tree, path = []) => {
|
|
122
|
-
|
|
123
|
-
|
|
129
|
+
const Cls = tree.isLink ? ArboristLink
|
|
130
|
+
: tree.sourceReference ? ArboristVirtualNode
|
|
131
|
+
: ArboristNode
|
|
132
|
+
if (path.includes(tree)) {
|
|
133
|
+
const obj = Object.create(Cls.prototype)
|
|
134
|
+
return Object.assign(obj, { location: tree.location })
|
|
135
|
+
}
|
|
124
136
|
path.push(tree)
|
|
125
|
-
const Cls = tree.isLink ? ArboristLink : ArboristNode
|
|
126
137
|
return new Cls(tree, path)
|
|
127
138
|
}
|
|
128
139
|
|
package/lib/shrinkwrap.js
CHANGED
|
@@ -32,6 +32,7 @@ const mismatch = (a, b) => a && b && a !== b
|
|
|
32
32
|
// After calling this.commit(), any nodes not present in the tree will have
|
|
33
33
|
// been removed from the shrinkwrap data as well.
|
|
34
34
|
|
|
35
|
+
const procLog = require('./proc-log.js')
|
|
35
36
|
const YarnLock = require('./yarn-lock.js')
|
|
36
37
|
const {promisify} = require('util')
|
|
37
38
|
const rimraf = promisify(require('rimraf'))
|
|
@@ -39,7 +40,24 @@ const fs = require('fs')
|
|
|
39
40
|
const readFile = promisify(fs.readFile)
|
|
40
41
|
const writeFile = promisify(fs.writeFile)
|
|
41
42
|
const stat = promisify(fs.stat)
|
|
42
|
-
const
|
|
43
|
+
const readdir_ = promisify(fs.readdir)
|
|
44
|
+
const readlink = promisify(fs.readlink)
|
|
45
|
+
|
|
46
|
+
// XXX remove when drop support for node v10
|
|
47
|
+
const lstat = promisify(fs.lstat)
|
|
48
|
+
/* istanbul ignore next - version specific polyfill */
|
|
49
|
+
const readdir = async (path, opt) => {
|
|
50
|
+
if (!opt || !opt.withFileTypes)
|
|
51
|
+
return readdir_(path, opt)
|
|
52
|
+
const ents = await readdir_(path, opt)
|
|
53
|
+
if (typeof ents[0] === 'string') {
|
|
54
|
+
return Promise.all(ents.map(async ent => {
|
|
55
|
+
return Object.assign(await lstat(path + '/' + ent), { name: ent })
|
|
56
|
+
}))
|
|
57
|
+
}
|
|
58
|
+
return ents
|
|
59
|
+
}
|
|
60
|
+
|
|
43
61
|
const { resolve, basename } = require('path')
|
|
44
62
|
const specFromLock = require('./spec-from-lock.js')
|
|
45
63
|
const versionFromTgz = require('./version-from-tgz.js')
|
|
@@ -159,10 +177,19 @@ const assertNoNewer = async (path, data, lockTime, dir = path, seen = null) => {
|
|
|
159
177
|
: readdir(parent, { withFileTypes: true })
|
|
160
178
|
|
|
161
179
|
return children.catch(() => [])
|
|
162
|
-
.then(ents => Promise.all(
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
180
|
+
.then(ents => Promise.all(ents.map(async ent => {
|
|
181
|
+
const child = resolve(parent, ent.name)
|
|
182
|
+
if (ent.isDirectory() && !/^\./.test(ent.name))
|
|
183
|
+
await assertNoNewer(path, data, lockTime, child, seen)
|
|
184
|
+
else if (ent.isSymbolicLink()) {
|
|
185
|
+
const target = resolve(parent, await readlink(child))
|
|
186
|
+
const tstat = await stat(target).catch(() => null)
|
|
187
|
+
seen.add(relpath(path, child))
|
|
188
|
+
if (tstat && tstat.isDirectory() && !seen.has(relpath(path, target)))
|
|
189
|
+
await assertNoNewer(path, data, lockTime, target, seen)
|
|
190
|
+
}
|
|
191
|
+
})))
|
|
192
|
+
.then(() => {
|
|
166
193
|
if (dir !== path)
|
|
167
194
|
return
|
|
168
195
|
|
|
@@ -265,7 +292,10 @@ class Shrinkwrap {
|
|
|
265
292
|
newline = '\n',
|
|
266
293
|
shrinkwrapOnly = false,
|
|
267
294
|
hiddenLockfile = false,
|
|
295
|
+
log = procLog,
|
|
268
296
|
} = options
|
|
297
|
+
|
|
298
|
+
this.log = log
|
|
269
299
|
this[_awaitingUpdate] = new Map()
|
|
270
300
|
this.tree = null
|
|
271
301
|
this.path = resolve(path || '.')
|
|
@@ -398,6 +428,8 @@ class Shrinkwrap {
|
|
|
398
428
|
// all good! hidden lockfile is the newest thing in here.
|
|
399
429
|
return data
|
|
400
430
|
}).catch(er => {
|
|
431
|
+
const rel = relpath(this.path, this.filename)
|
|
432
|
+
this.log.verbose('shrinkwrap', `failed to load ${rel}`, er)
|
|
401
433
|
this.loadingError = er
|
|
402
434
|
this.loadedFromDisk = false
|
|
403
435
|
this.ancientLockfile = false
|
package/lib/tracker.js
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
const procLog = require('./proc-log.js')
|
|
2
|
-
|
|
3
1
|
const _progress = Symbol('_progress')
|
|
4
2
|
const _onError = Symbol('_onError')
|
|
3
|
+
const procLog = require('./proc-log.js')
|
|
5
4
|
|
|
6
5
|
module.exports = cls => class Tracker extends cls {
|
|
7
6
|
constructor (options = {}) {
|
|
8
7
|
super(options)
|
|
9
|
-
this[_progress] = new Map()
|
|
10
8
|
this.log = options.log || procLog
|
|
9
|
+
this[_progress] = new Map()
|
|
11
10
|
}
|
|
12
11
|
|
|
13
12
|
addTracker (section, subsection = null, key = null) {
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/arborist",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.8",
|
|
4
4
|
"description": "Manage node_modules trees",
|
|
5
5
|
"dependencies": {
|
|
6
|
-
"@npmcli/installed-package-contents": "^1.0.
|
|
6
|
+
"@npmcli/installed-package-contents": "^1.0.7",
|
|
7
7
|
"@npmcli/map-workspaces": "^1.0.2",
|
|
8
8
|
"@npmcli/metavuln-calculator": "^1.1.0",
|
|
9
9
|
"@npmcli/move-file": "^1.1.0",
|
|
@@ -46,7 +46,8 @@
|
|
|
46
46
|
"tcompare": "^3.0.4"
|
|
47
47
|
},
|
|
48
48
|
"scripts": {
|
|
49
|
-
"test": "
|
|
49
|
+
"test": "npm run test-only --",
|
|
50
|
+
"test-only": "tap",
|
|
50
51
|
"posttest": "npm run lint",
|
|
51
52
|
"snap": "tap",
|
|
52
53
|
"postsnap": "npm run lint",
|
|
@@ -76,12 +77,16 @@
|
|
|
76
77
|
},
|
|
77
78
|
"tap": {
|
|
78
79
|
"100": true,
|
|
79
|
-
"node-arg": [
|
|
80
|
-
"--unhandled-rejections=strict"
|
|
81
|
-
],
|
|
82
80
|
"after": "test/fixtures/cleanup.js",
|
|
83
81
|
"coverage-map": "map.js",
|
|
84
82
|
"esm": false,
|
|
83
|
+
"test-env": [
|
|
84
|
+
"NODE_OPTIONS=--no-warnings"
|
|
85
|
+
],
|
|
86
|
+
"node-arg": [
|
|
87
|
+
"--no-warnings",
|
|
88
|
+
"--no-deprecation"
|
|
89
|
+
],
|
|
85
90
|
"timeout": "120"
|
|
86
91
|
}
|
|
87
92
|
}
|