@npmcli/arborist 6.1.2 → 6.1.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/lib/arborist/build-ideal-tree.js +5 -5
- package/lib/place-dep.js +82 -141
- package/package.json +3 -3
|
@@ -941,15 +941,15 @@ This is a one-time fix-up, please be patient...
|
|
|
941
941
|
edge,
|
|
942
942
|
dep,
|
|
943
943
|
|
|
944
|
-
explicitRequest: this[_explicitRequests].has(edge),
|
|
945
|
-
updateNames: this[_updateNames],
|
|
946
944
|
auditReport: this.auditReport,
|
|
945
|
+
explicitRequest: this[_explicitRequests].has(edge),
|
|
947
946
|
force: this[_force],
|
|
948
|
-
preferDedupe: this[_preferDedupe],
|
|
949
|
-
strictPeerDeps: this[_strictPeerDeps],
|
|
950
947
|
installLinks: this.installLinks,
|
|
951
|
-
legacyPeerDeps: this.legacyPeerDeps,
|
|
952
948
|
installStrategy: this[_installStrategy],
|
|
949
|
+
legacyPeerDeps: this.legacyPeerDeps,
|
|
950
|
+
preferDedupe: this[_preferDedupe],
|
|
951
|
+
strictPeerDeps: this[_strictPeerDeps],
|
|
952
|
+
updateNames: this[_updateNames],
|
|
953
953
|
}))
|
|
954
954
|
|
|
955
955
|
const promises = []
|
package/lib/place-dep.js
CHANGED
|
@@ -23,71 +23,39 @@ const peerEntrySets = require('./peer-entry-sets.js')
|
|
|
23
23
|
|
|
24
24
|
class PlaceDep {
|
|
25
25
|
constructor (options) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
this.
|
|
32
|
-
this.
|
|
33
|
-
this.
|
|
34
|
-
this.
|
|
35
|
-
|
|
36
|
-
this.
|
|
37
|
-
this.
|
|
38
|
-
|
|
39
|
-
// inherit all these fields from the parent to ensure consistency.
|
|
40
|
-
const {
|
|
41
|
-
preferDedupe,
|
|
42
|
-
force,
|
|
43
|
-
explicitRequest,
|
|
44
|
-
updateNames,
|
|
45
|
-
auditReport,
|
|
46
|
-
strictPeerDeps,
|
|
47
|
-
installLinks,
|
|
48
|
-
legacyPeerDeps,
|
|
49
|
-
installStrategy,
|
|
50
|
-
} = parent || options
|
|
51
|
-
Object.assign(this, {
|
|
52
|
-
preferDedupe,
|
|
53
|
-
force,
|
|
54
|
-
explicitRequest,
|
|
55
|
-
updateNames,
|
|
56
|
-
auditReport,
|
|
57
|
-
strictPeerDeps,
|
|
58
|
-
installLinks,
|
|
59
|
-
installStrategy,
|
|
60
|
-
legacyPeerDeps,
|
|
61
|
-
})
|
|
26
|
+
this.auditReport = options.auditReport
|
|
27
|
+
this.dep = options.dep
|
|
28
|
+
this.edge = options.edge
|
|
29
|
+
this.explicitRequest = options.explicitRequest
|
|
30
|
+
this.force = options.force
|
|
31
|
+
this.installLinks = options.installLinks
|
|
32
|
+
this.installStrategy = options.installStrategy
|
|
33
|
+
this.legacyPeerDeps = options.legacyPeerDeps
|
|
34
|
+
this.parent = options.parent || null
|
|
35
|
+
this.preferDedupe = options.preferDedupe
|
|
36
|
+
this.strictPeerDeps = options.strictPeerDeps
|
|
37
|
+
this.updateNames = options.updateNames
|
|
62
38
|
|
|
39
|
+
this.canPlace = null
|
|
40
|
+
this.canPlaceSelf = null
|
|
41
|
+
// XXX this only appears to be used by tests
|
|
42
|
+
this.checks = new Map()
|
|
63
43
|
this.children = []
|
|
64
|
-
this.parent = parent
|
|
65
|
-
this.peerConflict = null
|
|
66
|
-
|
|
67
44
|
this.needEvaluation = new Set()
|
|
45
|
+
this.peerConflict = null
|
|
46
|
+
this.placed = null
|
|
47
|
+
this.target = null
|
|
68
48
|
|
|
69
|
-
this.
|
|
70
|
-
|
|
71
|
-
this.
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
place () {
|
|
75
|
-
const {
|
|
76
|
-
edge,
|
|
77
|
-
dep,
|
|
78
|
-
preferDedupe,
|
|
79
|
-
explicitRequest,
|
|
80
|
-
updateNames,
|
|
81
|
-
installStrategy,
|
|
82
|
-
checks,
|
|
83
|
-
} = this
|
|
49
|
+
this.current = this.edge.to
|
|
50
|
+
this.name = this.edge.name
|
|
51
|
+
this.top = this.parent?.top || this
|
|
84
52
|
|
|
85
53
|
// nothing to do if the edge is fine as it is
|
|
86
|
-
if (edge.to &&
|
|
87
|
-
!edge.error &&
|
|
88
|
-
!explicitRequest &&
|
|
89
|
-
!updateNames.includes(edge.name) &&
|
|
90
|
-
!this.isVulnerable(edge.to)) {
|
|
54
|
+
if (this.edge.to &&
|
|
55
|
+
!this.edge.error &&
|
|
56
|
+
!this.explicitRequest &&
|
|
57
|
+
!this.updateNames.includes(this.edge.name) &&
|
|
58
|
+
!this.auditReport?.isVulnerable(this.edge.to)) {
|
|
91
59
|
return
|
|
92
60
|
}
|
|
93
61
|
|
|
@@ -95,8 +63,6 @@ class PlaceDep {
|
|
|
95
63
|
// where the dep is not a peer dep.
|
|
96
64
|
const start = this.getStartNode()
|
|
97
65
|
|
|
98
|
-
let canPlace = null
|
|
99
|
-
let canPlaceSelf = null
|
|
100
66
|
for (const target of start.ancestry()) {
|
|
101
67
|
// if the current location has a peerDep on it, then we can't place here
|
|
102
68
|
// this is pretty rare to hit, since we always prefer deduping peers,
|
|
@@ -112,14 +78,14 @@ class PlaceDep {
|
|
|
112
78
|
// Then we check under b, and can't, because of the optional peer dep.
|
|
113
79
|
// but we CAN place it under a, so the correct thing to do is keep
|
|
114
80
|
// walking up the tree.
|
|
115
|
-
const targetEdge = target.edgesOut.get(edge.name)
|
|
81
|
+
const targetEdge = target.edgesOut.get(this.edge.name)
|
|
116
82
|
if (!target.isTop && targetEdge && targetEdge.peer) {
|
|
117
83
|
continue
|
|
118
84
|
}
|
|
119
85
|
|
|
120
86
|
const cpd = new CanPlaceDep({
|
|
121
|
-
dep,
|
|
122
|
-
edge,
|
|
87
|
+
dep: this.dep,
|
|
88
|
+
edge: this.edge,
|
|
123
89
|
// note: this sets the parent's canPlace as the parent of this
|
|
124
90
|
// canPlace, but it does NOT add this canPlace to the parent's
|
|
125
91
|
// children. This way, we can know that it's a peer dep, and
|
|
@@ -127,10 +93,10 @@ class PlaceDep {
|
|
|
127
93
|
// tree of checks that factored into the original decision.
|
|
128
94
|
parent: this.parent && this.parent.canPlace,
|
|
129
95
|
target,
|
|
130
|
-
preferDedupe,
|
|
96
|
+
preferDedupe: this.preferDedupe,
|
|
131
97
|
explicitRequest: this.explicitRequest,
|
|
132
98
|
})
|
|
133
|
-
checks.set(target, cpd)
|
|
99
|
+
this.checks.set(target, cpd)
|
|
134
100
|
|
|
135
101
|
// It's possible that a "conflict" is a conflict among the *peers* of
|
|
136
102
|
// a given node we're trying to place, but there actually is no current
|
|
@@ -146,13 +112,13 @@ class PlaceDep {
|
|
|
146
112
|
// where they did not themselves conflict, and skip c@2 if conflict
|
|
147
113
|
// is ok by virtue of being forced or not ours and not strict.
|
|
148
114
|
if (cpd.canPlaceSelf !== CONFLICT) {
|
|
149
|
-
canPlaceSelf = cpd
|
|
115
|
+
this.canPlaceSelf = cpd
|
|
150
116
|
}
|
|
151
117
|
|
|
152
118
|
// we found a place this can go, along with all its peer friends.
|
|
153
119
|
// we break when we get the first conflict
|
|
154
120
|
if (cpd.canPlace !== CONFLICT) {
|
|
155
|
-
canPlace = cpd
|
|
121
|
+
this.canPlace = cpd
|
|
156
122
|
} else {
|
|
157
123
|
break
|
|
158
124
|
}
|
|
@@ -161,19 +127,19 @@ class PlaceDep {
|
|
|
161
127
|
// since we're going to crash the build or prune it out anyway.
|
|
162
128
|
// but, this will frequently NOT be a successful canPlace, because
|
|
163
129
|
// it'll have no version or other information.
|
|
164
|
-
if (dep.errors.length) {
|
|
130
|
+
if (this.dep.errors.length) {
|
|
165
131
|
break
|
|
166
132
|
}
|
|
167
133
|
|
|
168
134
|
// nest packages like npm v1 and v2
|
|
169
135
|
// very disk-inefficient
|
|
170
|
-
if (installStrategy === 'nested') {
|
|
136
|
+
if (this.installStrategy === 'nested') {
|
|
171
137
|
break
|
|
172
138
|
}
|
|
173
139
|
|
|
174
140
|
// when installing globally, or just in global style, we never place
|
|
175
141
|
// deps above the first level.
|
|
176
|
-
if (installStrategy === 'shallow') {
|
|
142
|
+
if (this.installStrategy === 'shallow') {
|
|
177
143
|
const rp = target.resolveParent
|
|
178
144
|
if (rp && rp.isProjectRoot) {
|
|
179
145
|
break
|
|
@@ -181,18 +147,12 @@ class PlaceDep {
|
|
|
181
147
|
}
|
|
182
148
|
}
|
|
183
149
|
|
|
184
|
-
Object.assign(this, {
|
|
185
|
-
canPlace,
|
|
186
|
-
canPlaceSelf,
|
|
187
|
-
})
|
|
188
|
-
this.current = edge.to
|
|
189
|
-
|
|
190
150
|
// if we can't find a target, that means that the last place checked,
|
|
191
151
|
// and all the places before it, had a conflict.
|
|
192
|
-
if (!canPlace) {
|
|
193
|
-
// if not forced,
|
|
152
|
+
if (!this.canPlace) {
|
|
153
|
+
// if not forced, and it's our dep, or strictPeerDeps is set, then
|
|
194
154
|
// this is an ERESOLVE error.
|
|
195
|
-
if (!this.
|
|
155
|
+
if (!this.force && (this.isMine || this.strictPeerDeps)) {
|
|
196
156
|
return this.failPeerConflict()
|
|
197
157
|
}
|
|
198
158
|
|
|
@@ -200,54 +160,45 @@ class PlaceDep {
|
|
|
200
160
|
// if we have a current, then we treat CONFLICT as a KEEP.
|
|
201
161
|
// otherwise, we just skip it. Only warn on the one that actually
|
|
202
162
|
// could not be placed somewhere.
|
|
203
|
-
if (!canPlaceSelf) {
|
|
163
|
+
if (!this.canPlaceSelf) {
|
|
204
164
|
this.warnPeerConflict()
|
|
205
165
|
return
|
|
206
166
|
}
|
|
207
167
|
|
|
208
|
-
this.canPlace = canPlaceSelf
|
|
168
|
+
this.canPlace = this.canPlaceSelf
|
|
209
169
|
}
|
|
210
170
|
|
|
211
171
|
// now we have a target, a tree of CanPlaceDep results for the peer group,
|
|
212
172
|
// and we are ready to go
|
|
213
|
-
this.placeInTree()
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
placeInTree () {
|
|
217
|
-
const {
|
|
218
|
-
dep,
|
|
219
|
-
canPlace,
|
|
220
|
-
edge,
|
|
221
|
-
} = this
|
|
222
173
|
|
|
223
174
|
/* istanbul ignore next */
|
|
224
|
-
if (!canPlace) {
|
|
175
|
+
if (!this.canPlace) {
|
|
225
176
|
debug(() => {
|
|
226
177
|
throw new Error('canPlace not set, but trying to place in tree')
|
|
227
178
|
})
|
|
228
179
|
return
|
|
229
180
|
}
|
|
230
181
|
|
|
231
|
-
const { target } = canPlace
|
|
182
|
+
const { target } = this.canPlace
|
|
232
183
|
|
|
233
184
|
log.silly(
|
|
234
185
|
'placeDep',
|
|
235
186
|
target.location || 'ROOT',
|
|
236
|
-
`${dep.name}@${dep.version}`,
|
|
237
|
-
canPlace.description,
|
|
187
|
+
`${this.dep.name}@${this.dep.version}`,
|
|
188
|
+
this.canPlace.description,
|
|
238
189
|
`for: ${this.edge.from.package._id || this.edge.from.location}`,
|
|
239
|
-
`want: ${edge.spec || '*'}`
|
|
190
|
+
`want: ${this.edge.spec || '*'}`
|
|
240
191
|
)
|
|
241
192
|
|
|
242
|
-
const placementType = canPlace.canPlace === CONFLICT
|
|
243
|
-
? canPlace.canPlaceSelf
|
|
244
|
-
: canPlace.canPlace
|
|
193
|
+
const placementType = this.canPlace.canPlace === CONFLICT
|
|
194
|
+
? this.canPlace.canPlaceSelf
|
|
195
|
+
: this.canPlace.canPlace
|
|
245
196
|
|
|
246
197
|
// if we're placing in the tree with --force, we can get here even though
|
|
247
198
|
// it's a conflict. Treat it as a KEEP, but warn and move on.
|
|
248
199
|
if (placementType === KEEP) {
|
|
249
200
|
// this was a peerConflicted peer dep
|
|
250
|
-
if (edge.peer && !edge.valid) {
|
|
201
|
+
if (this.edge.peer && !this.edge.valid) {
|
|
251
202
|
this.warnPeerConflict()
|
|
252
203
|
}
|
|
253
204
|
|
|
@@ -276,7 +227,7 @@ class PlaceDep {
|
|
|
276
227
|
// instead of nesting forever, when the loop occurs, create
|
|
277
228
|
// a symbolic link to the earlier instance
|
|
278
229
|
for (let p = target; p; p = p.resolveParent) {
|
|
279
|
-
if (p.matches(dep) && !p.isTop) {
|
|
230
|
+
if (p.matches(this.dep) && !p.isTop) {
|
|
280
231
|
this.placed = new Link({ parent: target, target: p })
|
|
281
232
|
return
|
|
282
233
|
}
|
|
@@ -286,17 +237,17 @@ class PlaceDep {
|
|
|
286
237
|
// remove any that are not being replaced and will now be invalid, and
|
|
287
238
|
// re-evaluate them deeper into the tree.
|
|
288
239
|
|
|
289
|
-
const virtualRoot = dep.parent
|
|
290
|
-
this.placed = new dep.constructor({
|
|
291
|
-
name: dep.name,
|
|
292
|
-
pkg: dep.package,
|
|
293
|
-
resolved: dep.resolved,
|
|
294
|
-
integrity: dep.integrity,
|
|
240
|
+
const virtualRoot = this.dep.parent
|
|
241
|
+
this.placed = new this.dep.constructor({
|
|
242
|
+
name: this.dep.name,
|
|
243
|
+
pkg: this.dep.package,
|
|
244
|
+
resolved: this.dep.resolved,
|
|
245
|
+
integrity: this.dep.integrity,
|
|
295
246
|
installLinks: this.installLinks,
|
|
296
247
|
legacyPeerDeps: this.legacyPeerDeps,
|
|
297
|
-
error: dep.errors[0],
|
|
298
|
-
...(dep.overrides ? { overrides: dep.overrides } : {}),
|
|
299
|
-
...(dep.isLink ? { target: dep.target, realpath: dep.realpath } : {}),
|
|
248
|
+
error: this.dep.errors[0],
|
|
249
|
+
...(this.dep.overrides ? { overrides: this.dep.overrides } : {}),
|
|
250
|
+
...(this.dep.isLink ? { target: this.dep.target, realpath: this.dep.realpath } : {}),
|
|
300
251
|
})
|
|
301
252
|
|
|
302
253
|
this.oldDep = target.children.get(this.name)
|
|
@@ -307,7 +258,7 @@ class PlaceDep {
|
|
|
307
258
|
}
|
|
308
259
|
|
|
309
260
|
// if it's a peerConflicted peer dep, warn about it
|
|
310
|
-
if (edge.peer && !this.placed.satisfies(edge)) {
|
|
261
|
+
if (this.edge.peer && !this.placed.satisfies(this.edge)) {
|
|
311
262
|
this.warnPeerConflict()
|
|
312
263
|
}
|
|
313
264
|
|
|
@@ -315,8 +266,8 @@ class PlaceDep {
|
|
|
315
266
|
// MAY end up putting a better/identical node further up the tree in
|
|
316
267
|
// a way that causes an unnecessary duplication. If so, remove the
|
|
317
268
|
// now-unnecessary node.
|
|
318
|
-
if (edge.valid && edge.to && edge.to !== this.placed) {
|
|
319
|
-
this.pruneDedupable(edge.to, false)
|
|
269
|
+
if (this.edge.valid && this.edge.to && this.edge.to !== this.placed) {
|
|
270
|
+
this.pruneDedupable(this.edge.to, false)
|
|
320
271
|
}
|
|
321
272
|
|
|
322
273
|
// in case we just made some duplicates that can be removed,
|
|
@@ -360,6 +311,15 @@ class PlaceDep {
|
|
|
360
311
|
}
|
|
361
312
|
|
|
362
313
|
this.children.push(new PlaceDep({
|
|
314
|
+
auditReport: this.auditReport,
|
|
315
|
+
explicitRequest: this.explicitRequest,
|
|
316
|
+
force: this.force,
|
|
317
|
+
installLinks: this.installLinks,
|
|
318
|
+
installStrategy: this.installStrategy,
|
|
319
|
+
legacyPeerDeps: this.legaycPeerDeps,
|
|
320
|
+
preferDedupe: this.preferDedupe,
|
|
321
|
+
strictPeerDeps: this.strictPeerDeps,
|
|
322
|
+
updateNames: this.updateName,
|
|
363
323
|
parent: this,
|
|
364
324
|
dep: peer,
|
|
365
325
|
node: this.placed,
|
|
@@ -492,10 +452,6 @@ class PlaceDep {
|
|
|
492
452
|
}
|
|
493
453
|
}
|
|
494
454
|
|
|
495
|
-
get conflictOk () {
|
|
496
|
-
return this.force || (!this.isMine && !this.strictPeerDeps)
|
|
497
|
-
}
|
|
498
|
-
|
|
499
455
|
get isMine () {
|
|
500
456
|
const { edge } = this.top
|
|
501
457
|
const { from: node } = edge
|
|
@@ -550,10 +506,15 @@ class PlaceDep {
|
|
|
550
506
|
const { from: node } = edge
|
|
551
507
|
const curNode = node.resolve(edge.name)
|
|
552
508
|
|
|
509
|
+
// XXX decorate more with this.canPlace and this.canPlaceSelf,
|
|
510
|
+
// this.checks, this.children, walk over conflicted peers, etc.
|
|
553
511
|
const expl = {
|
|
554
512
|
code: 'ERESOLVE',
|
|
555
513
|
edge: edge.explain(),
|
|
556
514
|
dep: dep.explain(edge),
|
|
515
|
+
force: this.force,
|
|
516
|
+
isMine: this.isMine,
|
|
517
|
+
strictPeerDeps: this.strictPeerDeps,
|
|
557
518
|
}
|
|
558
519
|
|
|
559
520
|
if (this.parent) {
|
|
@@ -582,37 +543,17 @@ class PlaceDep {
|
|
|
582
543
|
}
|
|
583
544
|
}
|
|
584
545
|
|
|
585
|
-
const {
|
|
586
|
-
strictPeerDeps,
|
|
587
|
-
force,
|
|
588
|
-
isMine,
|
|
589
|
-
} = this
|
|
590
|
-
Object.assign(expl, {
|
|
591
|
-
strictPeerDeps,
|
|
592
|
-
force,
|
|
593
|
-
isMine,
|
|
594
|
-
})
|
|
595
|
-
|
|
596
|
-
// XXX decorate more with this.canPlace and this.canPlaceSelf,
|
|
597
|
-
// this.checks, this.children, walk over conflicted peers, etc.
|
|
598
546
|
return expl
|
|
599
547
|
}
|
|
600
548
|
|
|
601
549
|
getStartNode () {
|
|
602
|
-
// if we are a peer, then we MUST be at least as shallow as the
|
|
603
|
-
//
|
|
604
|
-
const from = this.parent
|
|
550
|
+
// if we are a peer, then we MUST be at least as shallow as the peer
|
|
551
|
+
// dependent
|
|
552
|
+
const from = this.parent?.getStartNode() || this.edge.from
|
|
605
553
|
return deepestNestingTarget(from, this.name)
|
|
606
554
|
}
|
|
607
555
|
|
|
608
|
-
|
|
609
|
-
return this.parent ? this.parent.top : this
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
isVulnerable (node) {
|
|
613
|
-
return this.auditReport && this.auditReport.isVulnerable(node)
|
|
614
|
-
}
|
|
615
|
-
|
|
556
|
+
// XXX this only appears to be used by tests
|
|
616
557
|
get allChildren () {
|
|
617
558
|
const set = new Set(this.children)
|
|
618
559
|
for (const child of set) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npmcli/arborist",
|
|
3
|
-
"version": "6.1.
|
|
3
|
+
"version": "6.1.3",
|
|
4
4
|
"description": "Manage node_modules trees",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@isaacs/string-locale-compare": "^1.1.0",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@npmcli/eslint-config": "^4.0.0",
|
|
42
|
-
"@npmcli/template-oss": "4.
|
|
42
|
+
"@npmcli/template-oss": "4.10.0",
|
|
43
43
|
"benchmark": "^2.1.4",
|
|
44
44
|
"chalk": "^4.1.0",
|
|
45
45
|
"minify-registry-metadata": "^2.1.0",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
},
|
|
102
102
|
"templateOSS": {
|
|
103
103
|
"//@npmcli/template-oss": "This file is partially managed by @npmcli/template-oss. Edits may be overwritten.",
|
|
104
|
-
"version": "4.
|
|
104
|
+
"version": "4.10.0",
|
|
105
105
|
"content": "../../scripts/template-oss/index.js"
|
|
106
106
|
}
|
|
107
107
|
}
|