@npmcli/arborist 2.8.2 → 2.8.3
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/bin/actual.js +4 -2
- package/bin/audit.js +12 -6
- package/bin/dedupe.js +6 -3
- package/bin/funding.js +4 -2
- package/bin/ideal.js +2 -1
- package/bin/lib/logging.js +4 -3
- package/bin/lib/options.js +14 -12
- package/bin/lib/timers.js +6 -3
- package/bin/license.js +9 -5
- package/bin/prune.js +6 -3
- package/bin/reify.js +6 -3
- package/bin/virtual.js +4 -2
- package/lib/add-rm-pkg-deps.js +25 -14
- package/lib/arborist/audit.js +2 -1
- package/lib/arborist/build-ideal-tree.js +129 -68
- package/lib/arborist/deduper.js +2 -1
- package/lib/arborist/index.js +8 -4
- package/lib/arborist/load-actual.js +28 -13
- package/lib/arborist/load-virtual.js +34 -18
- package/lib/arborist/load-workspaces.js +4 -2
- package/lib/arborist/rebuild.js +31 -16
- package/lib/arborist/reify.js +153 -76
- package/lib/audit-report.js +42 -22
- package/lib/calc-dep-flags.js +18 -9
- package/lib/can-place-dep.js +56 -28
- package/lib/case-insensitive-map.js +4 -2
- package/lib/consistent-resolve.js +2 -1
- package/lib/deepest-nesting-target.js +4 -2
- package/lib/dep-valid.js +8 -4
- package/lib/diff.js +74 -22
- package/lib/edge.js +26 -13
- package/lib/gather-dep-set.js +2 -1
- package/lib/inventory.js +12 -6
- package/lib/link.js +14 -9
- package/lib/node.js +216 -113
- package/lib/optional-set.js +4 -2
- package/lib/peer-entry-sets.js +10 -5
- package/lib/place-dep.js +56 -29
- package/lib/printable.js +41 -21
- package/lib/realpath.js +12 -6
- package/lib/shrinkwrap.js +162 -89
- package/lib/signal-handling.js +6 -3
- package/lib/spec-from-lock.js +7 -4
- package/lib/tracker.js +24 -18
- package/lib/tree-check.js +12 -6
- package/lib/version-from-tgz.js +4 -2
- package/lib/vuln.js +28 -16
- package/lib/yarn-lock.js +27 -15
- package/package.json +7 -10
package/lib/optional-set.js
CHANGED
|
@@ -10,8 +10,9 @@
|
|
|
10
10
|
|
|
11
11
|
const gatherDepSet = require('./gather-dep-set.js')
|
|
12
12
|
const optionalSet = node => {
|
|
13
|
-
if (!node.optional)
|
|
13
|
+
if (!node.optional) {
|
|
14
14
|
return new Set()
|
|
15
|
+
}
|
|
15
16
|
|
|
16
17
|
// start with the node, then walk up the dependency graph until we
|
|
17
18
|
// get to the boundaries that define the optional set. since the
|
|
@@ -21,8 +22,9 @@ const optionalSet = node => {
|
|
|
21
22
|
const set = new Set([node])
|
|
22
23
|
for (const node of set) {
|
|
23
24
|
for (const edge of node.edgesIn) {
|
|
24
|
-
if (!edge.optional)
|
|
25
|
+
if (!edge.optional) {
|
|
25
26
|
set.add(edge.from)
|
|
27
|
+
}
|
|
26
28
|
}
|
|
27
29
|
}
|
|
28
30
|
|
package/lib/peer-entry-sets.js
CHANGED
|
@@ -15,12 +15,14 @@ const peerEntrySets = node => {
|
|
|
15
15
|
const unionSet = new Set([node])
|
|
16
16
|
for (const node of unionSet) {
|
|
17
17
|
for (const edge of node.edgesOut.values()) {
|
|
18
|
-
if (edge.valid && edge.peer && edge.to)
|
|
18
|
+
if (edge.valid && edge.peer && edge.to) {
|
|
19
19
|
unionSet.add(edge.to)
|
|
20
|
+
}
|
|
20
21
|
}
|
|
21
22
|
for (const edge of node.edgesIn) {
|
|
22
|
-
if (edge.valid && edge.peer)
|
|
23
|
+
if (edge.valid && edge.peer) {
|
|
23
24
|
unionSet.add(edge.from)
|
|
25
|
+
}
|
|
24
26
|
}
|
|
25
27
|
}
|
|
26
28
|
const entrySets = new Map()
|
|
@@ -28,16 +30,18 @@ const peerEntrySets = node => {
|
|
|
28
30
|
for (const edge of peer.edgesIn) {
|
|
29
31
|
// if not valid, it doesn't matter anyway. either it's been previously
|
|
30
32
|
// overridden, or it's the thing we're interested in replacing.
|
|
31
|
-
if (!edge.valid)
|
|
33
|
+
if (!edge.valid) {
|
|
32
34
|
continue
|
|
35
|
+
}
|
|
33
36
|
// this is the entry point into the peer set
|
|
34
37
|
if (!edge.peer || edge.from.isTop) {
|
|
35
38
|
// get the subset of peer brought in by this peer entry edge
|
|
36
39
|
const sub = new Set([peer])
|
|
37
40
|
for (const peer of sub) {
|
|
38
41
|
for (const edge of peer.edgesOut.values()) {
|
|
39
|
-
if (edge.valid && edge.peer && edge.to)
|
|
42
|
+
if (edge.valid && edge.peer && edge.to) {
|
|
40
43
|
sub.add(edge.to)
|
|
44
|
+
}
|
|
41
45
|
}
|
|
42
46
|
}
|
|
43
47
|
// if this subset does not include the node we are focused on,
|
|
@@ -60,8 +64,9 @@ const peerEntrySets = node => {
|
|
|
60
64
|
// Edge(a->b) => Set(b, d, e, f, g)
|
|
61
65
|
// Edge(a->d) => Set(d, e, f, g)
|
|
62
66
|
// }
|
|
63
|
-
if (sub.has(node))
|
|
67
|
+
if (sub.has(node)) {
|
|
64
68
|
entrySets.set(edge, sub)
|
|
69
|
+
}
|
|
65
70
|
}
|
|
66
71
|
}
|
|
67
72
|
}
|
package/lib/place-dep.js
CHANGED
|
@@ -85,8 +85,9 @@ class PlaceDep {
|
|
|
85
85
|
!edge.error &&
|
|
86
86
|
!explicitRequest &&
|
|
87
87
|
!updateNames.includes(edge.name) &&
|
|
88
|
-
!this.isVulnerable(edge.to))
|
|
88
|
+
!this.isVulnerable(edge.to)) {
|
|
89
89
|
return
|
|
90
|
+
}
|
|
90
91
|
|
|
91
92
|
// walk up the tree until we hit either a top/root node, or a place
|
|
92
93
|
// where the dep is not a peer dep.
|
|
@@ -110,8 +111,9 @@ class PlaceDep {
|
|
|
110
111
|
// but we CAN place it under a, so the correct thing to do is keep
|
|
111
112
|
// walking up the tree.
|
|
112
113
|
const targetEdge = target.edgesOut.get(edge.name)
|
|
113
|
-
if (!target.isTop && targetEdge && targetEdge.peer)
|
|
114
|
+
if (!target.isTop && targetEdge && targetEdge.peer) {
|
|
114
115
|
continue
|
|
116
|
+
}
|
|
115
117
|
|
|
116
118
|
const cpd = new CanPlaceDep({
|
|
117
119
|
dep,
|
|
@@ -141,34 +143,39 @@ class PlaceDep {
|
|
|
141
143
|
// should treat (b) and (d) as OK, and place them in the last place
|
|
142
144
|
// where they did not themselves conflict, and skip c@2 if conflict
|
|
143
145
|
// is ok by virtue of being forced or not ours and not strict.
|
|
144
|
-
if (cpd.canPlaceSelf !== CONFLICT)
|
|
146
|
+
if (cpd.canPlaceSelf !== CONFLICT) {
|
|
145
147
|
canPlaceSelf = cpd
|
|
148
|
+
}
|
|
146
149
|
|
|
147
150
|
// we found a place this can go, along with all its peer friends.
|
|
148
151
|
// we break when we get the first conflict
|
|
149
|
-
if (cpd.canPlace !== CONFLICT)
|
|
152
|
+
if (cpd.canPlace !== CONFLICT) {
|
|
150
153
|
canPlace = cpd
|
|
151
|
-
else
|
|
154
|
+
} else {
|
|
152
155
|
break
|
|
156
|
+
}
|
|
153
157
|
|
|
154
158
|
// if it's a load failure, just plop it in the first place attempted,
|
|
155
159
|
// since we're going to crash the build or prune it out anyway.
|
|
156
160
|
// but, this will frequently NOT be a successful canPlace, because
|
|
157
161
|
// it'll have no version or other information.
|
|
158
|
-
if (dep.errors.length)
|
|
162
|
+
if (dep.errors.length) {
|
|
159
163
|
break
|
|
164
|
+
}
|
|
160
165
|
|
|
161
166
|
// nest packages like npm v1 and v2
|
|
162
167
|
// very disk-inefficient
|
|
163
|
-
if (legacyBundling)
|
|
168
|
+
if (legacyBundling) {
|
|
164
169
|
break
|
|
170
|
+
}
|
|
165
171
|
|
|
166
172
|
// when installing globally, or just in global style, we never place
|
|
167
173
|
// deps above the first level.
|
|
168
174
|
if (globalStyle) {
|
|
169
175
|
const rp = target.resolveParent
|
|
170
|
-
if (rp && rp.isProjectRoot)
|
|
176
|
+
if (rp && rp.isProjectRoot) {
|
|
171
177
|
break
|
|
178
|
+
}
|
|
172
179
|
}
|
|
173
180
|
}
|
|
174
181
|
|
|
@@ -183,8 +190,9 @@ class PlaceDep {
|
|
|
183
190
|
if (!canPlace) {
|
|
184
191
|
// if not forced, or it's our dep, or strictPeerDeps is set, then
|
|
185
192
|
// this is an ERESOLVE error.
|
|
186
|
-
if (!this.conflictOk)
|
|
193
|
+
if (!this.conflictOk) {
|
|
187
194
|
return this.failPeerConflict()
|
|
195
|
+
}
|
|
188
196
|
|
|
189
197
|
// ok! we're gonna allow the conflict, but we should still warn
|
|
190
198
|
// if we have a current, then we treat CONFLICT as a KEEP.
|
|
@@ -237,8 +245,9 @@ class PlaceDep {
|
|
|
237
245
|
// it's a conflict. Treat it as a KEEP, but warn and move on.
|
|
238
246
|
if (placementType === KEEP) {
|
|
239
247
|
// this was an overridden peer dep
|
|
240
|
-
if (edge.peer && !edge.valid)
|
|
248
|
+
if (edge.peer && !edge.valid) {
|
|
241
249
|
this.warnPeerConflict()
|
|
250
|
+
}
|
|
242
251
|
|
|
243
252
|
// if we get a KEEP in a update scenario, then we MAY have something
|
|
244
253
|
// already duplicating this unnecessarily! For example:
|
|
@@ -287,21 +296,24 @@ class PlaceDep {
|
|
|
287
296
|
})
|
|
288
297
|
|
|
289
298
|
this.oldDep = target.children.get(this.name)
|
|
290
|
-
if (this.oldDep)
|
|
299
|
+
if (this.oldDep) {
|
|
291
300
|
this.replaceOldDep()
|
|
292
|
-
else
|
|
301
|
+
} else {
|
|
293
302
|
this.placed.parent = target
|
|
303
|
+
}
|
|
294
304
|
|
|
295
305
|
// if it's an overridden peer dep, warn about it
|
|
296
|
-
if (edge.peer && !this.placed.satisfies(edge))
|
|
306
|
+
if (edge.peer && !this.placed.satisfies(edge)) {
|
|
297
307
|
this.warnPeerConflict()
|
|
308
|
+
}
|
|
298
309
|
|
|
299
310
|
// If the edge is not an error, then we're updating something, and
|
|
300
311
|
// MAY end up putting a better/identical node further up the tree in
|
|
301
312
|
// a way that causes an unnecessary duplication. If so, remove the
|
|
302
313
|
// now-unnecessary node.
|
|
303
|
-
if (edge.valid && edge.to && edge.to !== this.placed)
|
|
314
|
+
if (edge.valid && edge.to && edge.to !== this.placed) {
|
|
304
315
|
this.pruneDedupable(edge.to, false)
|
|
316
|
+
}
|
|
305
317
|
|
|
306
318
|
// in case we just made some duplicates that can be removed,
|
|
307
319
|
// prune anything deeper in the tree that can be replaced by this
|
|
@@ -310,8 +322,9 @@ class PlaceDep {
|
|
|
310
322
|
this.pruneDedupable(node, false)
|
|
311
323
|
// only walk the direct children of the ones we kept
|
|
312
324
|
if (node.root === target.root) {
|
|
313
|
-
for (const kid of node.children.values())
|
|
325
|
+
for (const kid of node.children.values()) {
|
|
314
326
|
this.pruneDedupable(kid, false)
|
|
327
|
+
}
|
|
315
328
|
}
|
|
316
329
|
}
|
|
317
330
|
}
|
|
@@ -323,8 +336,9 @@ class PlaceDep {
|
|
|
323
336
|
// otherwise they'd be gone and the peer set would change throughout
|
|
324
337
|
// this loop.
|
|
325
338
|
for (const peerEdge of this.placed.edgesOut.values()) {
|
|
326
|
-
if (peerEdge.valid || !peerEdge.peer || peerEdge.overridden)
|
|
339
|
+
if (peerEdge.valid || !peerEdge.peer || peerEdge.overridden) {
|
|
327
340
|
continue
|
|
341
|
+
}
|
|
328
342
|
|
|
329
343
|
const peer = virtualRoot.children.get(peerEdge.name)
|
|
330
344
|
|
|
@@ -332,12 +346,14 @@ class PlaceDep {
|
|
|
332
346
|
// it's an optional peer dep. If it's not being properly met (ie,
|
|
333
347
|
// peerEdge.valid is false), then this is likely heading for an
|
|
334
348
|
// ERESOLVE error, unless it can walk further up the tree.
|
|
335
|
-
if (!peer)
|
|
349
|
+
if (!peer) {
|
|
336
350
|
continue
|
|
351
|
+
}
|
|
337
352
|
|
|
338
353
|
// overridden peerEdge, just accept what's there already
|
|
339
|
-
if (!peer.satisfies(peerEdge))
|
|
354
|
+
if (!peer.satisfies(peerEdge)) {
|
|
340
355
|
continue
|
|
356
|
+
}
|
|
341
357
|
|
|
342
358
|
this.children.push(new PlaceDep({
|
|
343
359
|
parent: this,
|
|
@@ -363,8 +379,9 @@ class PlaceDep {
|
|
|
363
379
|
// later anyway.
|
|
364
380
|
const oldDeps = []
|
|
365
381
|
for (const [name, edge] of this.oldDep.edgesOut.entries()) {
|
|
366
|
-
if (!this.placed.edgesOut.has(name) && edge.to)
|
|
382
|
+
if (!this.placed.edgesOut.has(name) && edge.to) {
|
|
367
383
|
oldDeps.push(...gatherDepSet([edge.to], e => e.to !== edge.to))
|
|
384
|
+
}
|
|
368
385
|
}
|
|
369
386
|
this.placed.replace(this.oldDep)
|
|
370
387
|
this.pruneForReplacement(this.placed, oldDeps)
|
|
@@ -377,8 +394,9 @@ class PlaceDep {
|
|
|
377
394
|
.filter(e => e.to && !e.valid).map(e => e.to))
|
|
378
395
|
for (const dep of oldDeps) {
|
|
379
396
|
const set = gatherDepSet([dep], e => e.to !== dep && e.valid)
|
|
380
|
-
for (const dep of set)
|
|
397
|
+
for (const dep of set) {
|
|
381
398
|
invalidDeps.add(dep)
|
|
399
|
+
}
|
|
382
400
|
}
|
|
383
401
|
|
|
384
402
|
// ignore dependency edges from the node being replaced, but
|
|
@@ -388,8 +406,9 @@ class PlaceDep {
|
|
|
388
406
|
edge.from !== node && edge.to !== node && edge.valid)
|
|
389
407
|
|
|
390
408
|
// now just delete whatever's left, because it's junk
|
|
391
|
-
for (const dep of deps)
|
|
409
|
+
for (const dep of deps) {
|
|
392
410
|
dep.root = null
|
|
411
|
+
}
|
|
393
412
|
}
|
|
394
413
|
|
|
395
414
|
// prune all the nodes in a branch of the tree that can be safely removed
|
|
@@ -402,8 +421,9 @@ class PlaceDep {
|
|
|
402
421
|
// the dep set, except for this node we're deduping, so that we
|
|
403
422
|
// also prune deps that would be made extraneous.
|
|
404
423
|
const deps = gatherDepSet([node], e => e.to !== node && e.valid)
|
|
405
|
-
for (const node of deps)
|
|
424
|
+
for (const node of deps) {
|
|
406
425
|
node.root = null
|
|
426
|
+
}
|
|
407
427
|
return
|
|
408
428
|
}
|
|
409
429
|
if (descend) {
|
|
@@ -413,13 +433,15 @@ class PlaceDep {
|
|
|
413
433
|
const nodeSort = (a, b) => a.location.localeCompare(b.location, 'en')
|
|
414
434
|
|
|
415
435
|
const children = [...node.children.values()].sort(nodeSort)
|
|
416
|
-
for (const child of children)
|
|
436
|
+
for (const child of children) {
|
|
417
437
|
this.pruneDedupable(child)
|
|
438
|
+
}
|
|
418
439
|
const fsChildren = [...node.fsChildren].sort(nodeSort)
|
|
419
440
|
for (const topNode of fsChildren) {
|
|
420
441
|
const children = [...topNode.children.values()].sort(nodeSort)
|
|
421
|
-
for (const child of children)
|
|
442
|
+
for (const child of children) {
|
|
422
443
|
this.pruneDedupable(child)
|
|
444
|
+
}
|
|
423
445
|
}
|
|
424
446
|
}
|
|
425
447
|
}
|
|
@@ -432,11 +454,13 @@ class PlaceDep {
|
|
|
432
454
|
const { edge } = this.top
|
|
433
455
|
const { from: node } = edge
|
|
434
456
|
|
|
435
|
-
if (node.isWorkspace || node.isProjectRoot)
|
|
457
|
+
if (node.isWorkspace || node.isProjectRoot) {
|
|
436
458
|
return true
|
|
459
|
+
}
|
|
437
460
|
|
|
438
|
-
if (!edge.peer)
|
|
461
|
+
if (!edge.peer) {
|
|
439
462
|
return false
|
|
463
|
+
}
|
|
440
464
|
|
|
441
465
|
// re-entry case. check if any non-peer edges come from the project,
|
|
442
466
|
// or any entryEdges on peer groups are from the root.
|
|
@@ -446,13 +470,15 @@ class PlaceDep {
|
|
|
446
470
|
hasPeerEdges = true
|
|
447
471
|
continue
|
|
448
472
|
}
|
|
449
|
-
if (edge.from.isWorkspace || edge.from.isProjectRoot)
|
|
473
|
+
if (edge.from.isWorkspace || edge.from.isProjectRoot) {
|
|
450
474
|
return true
|
|
475
|
+
}
|
|
451
476
|
}
|
|
452
477
|
if (hasPeerEdges) {
|
|
453
478
|
for (const edge of peerEntrySets(node).keys()) {
|
|
454
|
-
if (edge.from.isWorkspace || edge.from.isProjectRoot)
|
|
479
|
+
if (edge.from.isWorkspace || edge.from.isProjectRoot) {
|
|
455
480
|
return true
|
|
481
|
+
}
|
|
456
482
|
}
|
|
457
483
|
}
|
|
458
484
|
|
|
@@ -541,8 +567,9 @@ class PlaceDep {
|
|
|
541
567
|
get allChildren () {
|
|
542
568
|
const set = new Set(this.children)
|
|
543
569
|
for (const child of set) {
|
|
544
|
-
for (const grandchild of child.children)
|
|
570
|
+
for (const grandchild of child.children) {
|
|
545
571
|
set.add(grandchild)
|
|
572
|
+
}
|
|
546
573
|
}
|
|
547
574
|
return [...set]
|
|
548
575
|
}
|
package/lib/printable.js
CHANGED
|
@@ -7,45 +7,62 @@ const relpath = require('./relpath.js')
|
|
|
7
7
|
class ArboristNode {
|
|
8
8
|
constructor (tree, path) {
|
|
9
9
|
this.name = tree.name
|
|
10
|
-
if (tree.packageName && tree.packageName !== this.name)
|
|
10
|
+
if (tree.packageName && tree.packageName !== this.name) {
|
|
11
11
|
this.packageName = tree.packageName
|
|
12
|
-
|
|
12
|
+
}
|
|
13
|
+
if (tree.version) {
|
|
13
14
|
this.version = tree.version
|
|
15
|
+
}
|
|
14
16
|
this.location = tree.location
|
|
15
17
|
this.path = tree.path
|
|
16
|
-
if (tree.realpath !== this.path)
|
|
18
|
+
if (tree.realpath !== this.path) {
|
|
17
19
|
this.realpath = tree.realpath
|
|
18
|
-
|
|
20
|
+
}
|
|
21
|
+
if (tree.resolved !== null) {
|
|
19
22
|
this.resolved = tree.resolved
|
|
20
|
-
|
|
23
|
+
}
|
|
24
|
+
if (tree.extraneous) {
|
|
21
25
|
this.extraneous = true
|
|
22
|
-
|
|
26
|
+
}
|
|
27
|
+
if (tree.dev) {
|
|
23
28
|
this.dev = true
|
|
24
|
-
|
|
29
|
+
}
|
|
30
|
+
if (tree.optional) {
|
|
25
31
|
this.optional = true
|
|
26
|
-
|
|
32
|
+
}
|
|
33
|
+
if (tree.devOptional && !tree.dev && !tree.optional) {
|
|
27
34
|
this.devOptional = true
|
|
28
|
-
|
|
35
|
+
}
|
|
36
|
+
if (tree.peer) {
|
|
29
37
|
this.peer = true
|
|
30
|
-
|
|
38
|
+
}
|
|
39
|
+
if (tree.inBundle) {
|
|
31
40
|
this.bundled = true
|
|
32
|
-
|
|
41
|
+
}
|
|
42
|
+
if (tree.inDepBundle) {
|
|
33
43
|
this.bundler = tree.getBundler().location
|
|
34
|
-
|
|
44
|
+
}
|
|
45
|
+
if (tree.isProjectRoot) {
|
|
35
46
|
this.isProjectRoot = true
|
|
36
|
-
|
|
47
|
+
}
|
|
48
|
+
if (tree.isWorkspace) {
|
|
37
49
|
this.isWorkspace = true
|
|
50
|
+
}
|
|
38
51
|
const bd = tree.package && tree.package.bundleDependencies
|
|
39
|
-
if (bd && bd.length)
|
|
52
|
+
if (bd && bd.length) {
|
|
40
53
|
this.bundleDependencies = bd
|
|
41
|
-
|
|
54
|
+
}
|
|
55
|
+
if (tree.inShrinkwrap) {
|
|
42
56
|
this.inShrinkwrap = true
|
|
43
|
-
else if (tree.hasShrinkwrap)
|
|
57
|
+
} else if (tree.hasShrinkwrap) {
|
|
44
58
|
this.hasShrinkwrap = true
|
|
45
|
-
|
|
59
|
+
}
|
|
60
|
+
if (tree.error) {
|
|
46
61
|
this.error = treeError(tree.error)
|
|
47
|
-
|
|
62
|
+
}
|
|
63
|
+
if (tree.errors && tree.errors.length) {
|
|
48
64
|
this.errors = tree.errors.map(treeError)
|
|
65
|
+
}
|
|
49
66
|
|
|
50
67
|
// edgesOut sorted by name
|
|
51
68
|
if (tree.edgesOut.size) {
|
|
@@ -109,10 +126,12 @@ class Edge {
|
|
|
109
126
|
this.type = edge.type
|
|
110
127
|
this.name = edge.name
|
|
111
128
|
this.spec = edge.spec || '*'
|
|
112
|
-
if (edge.error)
|
|
129
|
+
if (edge.error) {
|
|
113
130
|
this.error = edge.error
|
|
114
|
-
|
|
131
|
+
}
|
|
132
|
+
if (edge.overridden) {
|
|
115
133
|
this.overridden = edge.overridden
|
|
134
|
+
}
|
|
116
135
|
}
|
|
117
136
|
}
|
|
118
137
|
|
|
@@ -151,8 +170,9 @@ class EdgeIn extends Edge {
|
|
|
151
170
|
}
|
|
152
171
|
|
|
153
172
|
const printableTree = (tree, path = []) => {
|
|
154
|
-
if (!tree)
|
|
173
|
+
if (!tree) {
|
|
155
174
|
return tree
|
|
175
|
+
}
|
|
156
176
|
|
|
157
177
|
const Cls = tree.isLink ? ArboristLink
|
|
158
178
|
: tree.sourceReference ? ArboristVirtualNode
|
package/lib/realpath.js
CHANGED
|
@@ -14,18 +14,21 @@ const { resolve, basename, dirname } = require('path')
|
|
|
14
14
|
const realpathCached = (path, rpcache, stcache, depth) => {
|
|
15
15
|
// just a safety against extremely deep eloops
|
|
16
16
|
/* istanbul ignore next */
|
|
17
|
-
if (depth > 2000)
|
|
17
|
+
if (depth > 2000) {
|
|
18
18
|
throw eloop(path)
|
|
19
|
+
}
|
|
19
20
|
|
|
20
21
|
path = resolve(path)
|
|
21
|
-
if (rpcache.has(path))
|
|
22
|
+
if (rpcache.has(path)) {
|
|
22
23
|
return Promise.resolve(rpcache.get(path))
|
|
24
|
+
}
|
|
23
25
|
|
|
24
26
|
const dir = dirname(path)
|
|
25
27
|
const base = basename(path)
|
|
26
28
|
|
|
27
|
-
if (base && rpcache.has(dir))
|
|
29
|
+
if (base && rpcache.has(dir)) {
|
|
28
30
|
return realpathChild(dir, base, rpcache, stcache, depth)
|
|
31
|
+
}
|
|
29
32
|
|
|
30
33
|
// if it's the root, then we know it's real
|
|
31
34
|
if (!base) {
|
|
@@ -40,8 +43,9 @@ const realpathCached = (path, rpcache, stcache, depth) => {
|
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
const lstatCached = (path, stcache) => {
|
|
43
|
-
if (stcache.has(path))
|
|
46
|
+
if (stcache.has(path)) {
|
|
44
47
|
return Promise.resolve(stcache.get(path))
|
|
48
|
+
}
|
|
45
49
|
|
|
46
50
|
const p = lstat(path).then(st => {
|
|
47
51
|
stcache.set(path, st)
|
|
@@ -66,8 +70,9 @@ const realpathChild = (dir, base, rpcache, stcache, depth) => {
|
|
|
66
70
|
const realdir = rpcache.get(dir)
|
|
67
71
|
// that unpossible
|
|
68
72
|
/* istanbul ignore next */
|
|
69
|
-
if (typeof realdir === 'undefined')
|
|
73
|
+
if (typeof realdir === 'undefined') {
|
|
70
74
|
throw new Error('in realpathChild without parent being in realpath cache')
|
|
75
|
+
}
|
|
71
76
|
|
|
72
77
|
const realish = resolve(realdir, base)
|
|
73
78
|
return lstatCached(realish, stcache).then(st => {
|
|
@@ -78,8 +83,9 @@ const realpathChild = (dir, base, rpcache, stcache, depth) => {
|
|
|
78
83
|
|
|
79
84
|
return readlink(realish).then(target => {
|
|
80
85
|
const resolved = resolve(realdir, target)
|
|
81
|
-
if (realish === resolved)
|
|
86
|
+
if (realish === resolved) {
|
|
82
87
|
throw eloop(realish)
|
|
88
|
+
}
|
|
83
89
|
|
|
84
90
|
return realpathCached(resolved, rpcache, stcache, depth + 1)
|
|
85
91
|
}).then(real => {
|