@npmcli/arborist 2.7.1 → 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 +49 -0
- 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 +246 -757
- package/lib/arborist/deduper.js +2 -1
- package/lib/arborist/index.js +8 -4
- package/lib/arborist/load-actual.js +32 -15
- 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 +332 -119
- package/lib/audit-report.js +42 -22
- package/lib/calc-dep-flags.js +18 -9
- package/lib/can-place-dep.js +430 -0
- package/lib/case-insensitive-map.js +50 -0
- package/lib/consistent-resolve.js +2 -1
- package/lib/deepest-nesting-target.js +18 -0
- package/lib/dep-valid.js +8 -4
- package/lib/diff.js +74 -22
- package/lib/edge.js +29 -14
- package/lib/gather-dep-set.js +2 -1
- package/lib/inventory.js +12 -6
- package/lib/link.js +14 -9
- package/lib/node.js +269 -118
- package/lib/optional-set.js +4 -2
- package/lib/peer-entry-sets.js +77 -0
- package/lib/place-dep.js +578 -0
- package/lib/printable.js +48 -18
- package/lib/realpath.js +12 -6
- package/lib/shrinkwrap.js +168 -91
- 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 +9 -13
- package/lib/peer-set.js +0 -25
package/lib/arborist/deduper.js
CHANGED
|
@@ -6,8 +6,9 @@ module.exports = cls => class Deduper extends cls {
|
|
|
6
6
|
const tree = await this.loadVirtual().catch(() => this.loadActual())
|
|
7
7
|
const names = []
|
|
8
8
|
for (const name of tree.inventory.query('name')) {
|
|
9
|
-
if (tree.inventory.query('name', name).size > 1)
|
|
9
|
+
if (tree.inventory.query('name', name).size > 1) {
|
|
10
10
|
names.push(name)
|
|
11
|
+
}
|
|
11
12
|
}
|
|
12
13
|
return this.reify({
|
|
13
14
|
...options,
|
package/lib/arborist/index.js
CHANGED
|
@@ -59,8 +59,9 @@ class Arborist extends Base {
|
|
|
59
59
|
packumentCache: options.packumentCache || new Map(),
|
|
60
60
|
log: options.log || procLog,
|
|
61
61
|
}
|
|
62
|
-
if (options.saveType && !saveTypeMap.get(options.saveType))
|
|
62
|
+
if (options.saveType && !saveTypeMap.get(options.saveType)) {
|
|
63
63
|
throw new Error(`Invalid saveType ${options.saveType}`)
|
|
64
|
+
}
|
|
64
65
|
this.cache = resolve(this.options.cache)
|
|
65
66
|
this.path = resolve(this.options.path)
|
|
66
67
|
process.emit('timeEnd', 'arborist:ctor')
|
|
@@ -81,17 +82,20 @@ class Arborist extends Base {
|
|
|
81
82
|
const dep = edge.to
|
|
82
83
|
if (dep) {
|
|
83
84
|
set.add(dep)
|
|
84
|
-
if (dep.isLink)
|
|
85
|
+
if (dep.isLink) {
|
|
85
86
|
set.add(dep.target)
|
|
87
|
+
}
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
for (const child of node.children.values()) {
|
|
89
|
-
if (child.extraneous)
|
|
91
|
+
if (child.extraneous) {
|
|
90
92
|
extraneous.add(child)
|
|
93
|
+
}
|
|
91
94
|
}
|
|
92
95
|
}
|
|
93
|
-
for (const extra of extraneous)
|
|
96
|
+
for (const extra of extraneous) {
|
|
94
97
|
set.add(extra)
|
|
98
|
+
}
|
|
95
99
|
return set
|
|
96
100
|
}
|
|
97
101
|
}
|
|
@@ -78,8 +78,9 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
78
78
|
[_resetDepFlags] (tree, root) {
|
|
79
79
|
// reset all deps to extraneous prior to recalc
|
|
80
80
|
if (!root) {
|
|
81
|
-
for (const node of tree.inventory.values())
|
|
81
|
+
for (const node of tree.inventory.values()) {
|
|
82
82
|
node.extraneous = true
|
|
83
|
+
}
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
// only reset root flags if we're not re-rooting,
|
|
@@ -176,8 +177,9 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
176
177
|
await this[_loadFSTree](this[_actualTree])
|
|
177
178
|
await this[_loadWorkspaces](this[_actualTree])
|
|
178
179
|
await this[_loadWorkspaceTargets](this[_actualTree])
|
|
179
|
-
if (!ignoreMissing)
|
|
180
|
+
if (!ignoreMissing) {
|
|
180
181
|
await this[_findMissingEdges]()
|
|
182
|
+
}
|
|
181
183
|
this[_findFSParents]()
|
|
182
184
|
this[_transplant](root)
|
|
183
185
|
|
|
@@ -188,8 +190,10 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
188
190
|
const tree = this[_actualTree]
|
|
189
191
|
const actualRoot = tree.isLink ? tree.target : tree
|
|
190
192
|
const { dependencies = {} } = actualRoot.package
|
|
191
|
-
for (const name of actualRoot.children.
|
|
192
|
-
|
|
193
|
+
for (const [name, kid] of actualRoot.children.entries()) {
|
|
194
|
+
const def = kid.isLink ? `file:${kid.realpath}` : '*'
|
|
195
|
+
dependencies[name] = dependencies[name] || def
|
|
196
|
+
}
|
|
193
197
|
actualRoot.package = { ...actualRoot.package, dependencies }
|
|
194
198
|
}
|
|
195
199
|
return this[_actualTree]
|
|
@@ -198,8 +202,9 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
198
202
|
// if there are workspace targets without Link nodes created, load
|
|
199
203
|
// the targets, so that we know what they are.
|
|
200
204
|
async [_loadWorkspaceTargets] (tree) {
|
|
201
|
-
if (!tree.workspaces || !tree.workspaces.size)
|
|
205
|
+
if (!tree.workspaces || !tree.workspaces.size) {
|
|
202
206
|
return
|
|
207
|
+
}
|
|
203
208
|
|
|
204
209
|
const promises = []
|
|
205
210
|
for (const path of tree.workspaces.values()) {
|
|
@@ -213,18 +218,21 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
213
218
|
}
|
|
214
219
|
|
|
215
220
|
[_transplant] (root) {
|
|
216
|
-
if (!root || root === this[_actualTree])
|
|
221
|
+
if (!root || root === this[_actualTree]) {
|
|
217
222
|
return
|
|
223
|
+
}
|
|
218
224
|
|
|
219
225
|
this[_actualTree][_changePath](root.path)
|
|
220
226
|
for (const node of this[_actualTree].children.values()) {
|
|
221
|
-
if (!this[_transplantFilter](node))
|
|
227
|
+
if (!this[_transplantFilter](node)) {
|
|
222
228
|
node.root = null
|
|
229
|
+
}
|
|
223
230
|
}
|
|
224
231
|
|
|
225
232
|
root.replace(this[_actualTree])
|
|
226
|
-
for (const node of this[_actualTree].fsChildren)
|
|
233
|
+
for (const node of this[_actualTree].fsChildren) {
|
|
227
234
|
node.root = this[_transplantFilter](node) ? root : null
|
|
235
|
+
}
|
|
228
236
|
|
|
229
237
|
this[_actualTree] = root
|
|
230
238
|
}
|
|
@@ -289,8 +297,9 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
289
297
|
// it'll get parented later, making the fsParent scan a no-op, but better
|
|
290
298
|
// safe than sorry, since it's cheap.
|
|
291
299
|
const { parent, realpath } = options
|
|
292
|
-
if (!parent)
|
|
300
|
+
if (!parent) {
|
|
293
301
|
this[_topNodes].add(realpath)
|
|
302
|
+
}
|
|
294
303
|
return process.env._TEST_ARBORIST_SLOW_LINK_TARGET_ === '1'
|
|
295
304
|
? new Promise(res => setTimeout(() => res(new Node(options)), 100))
|
|
296
305
|
: new Node(options)
|
|
@@ -307,8 +316,9 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
307
316
|
// if a link target points at a node outside of the root tree's
|
|
308
317
|
// node_modules hierarchy, then load that node as well.
|
|
309
318
|
return this[_loadFSTree](link.target).then(() => link)
|
|
310
|
-
} else if (target.then)
|
|
319
|
+
} else if (target.then) {
|
|
311
320
|
target.then(node => link.target = node)
|
|
321
|
+
}
|
|
312
322
|
|
|
313
323
|
return link
|
|
314
324
|
}
|
|
@@ -319,13 +329,15 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
319
329
|
|
|
320
330
|
// if a Link target has started, but not completed, then
|
|
321
331
|
// a Promise will be in the cache to indicate this.
|
|
322
|
-
if (node.then)
|
|
332
|
+
if (node.then) {
|
|
323
333
|
return node.then(node => this[_loadFSTree](node))
|
|
334
|
+
}
|
|
324
335
|
|
|
325
336
|
// impossible except in pathological ELOOP cases
|
|
326
337
|
/* istanbul ignore if */
|
|
327
|
-
if (did.has(node.realpath))
|
|
338
|
+
if (did.has(node.realpath)) {
|
|
328
339
|
return Promise.resolve(node)
|
|
340
|
+
}
|
|
329
341
|
|
|
330
342
|
did.add(node.realpath)
|
|
331
343
|
return this[_loadFSChildren](node)
|
|
@@ -369,8 +381,11 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
369
381
|
|
|
370
382
|
const depPromises = []
|
|
371
383
|
for (const [name, edge] of node.edgesOut.entries()) {
|
|
372
|
-
|
|
384
|
+
const notMissing = !edge.missing &&
|
|
385
|
+
!(edge.to && (edge.to.dummy || edge.to.parent !== node))
|
|
386
|
+
if (notMissing) {
|
|
373
387
|
continue
|
|
388
|
+
}
|
|
374
389
|
|
|
375
390
|
// start the walk from the dirname, because we would have found
|
|
376
391
|
// the dep in the loadFSTree step already if it was local.
|
|
@@ -381,14 +396,16 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
381
396
|
// allows for finding the transitive deps of link targets.
|
|
382
397
|
// ie, if it has to go up and back out to get to the path
|
|
383
398
|
// from the nearest common ancestor, we've gone too far.
|
|
384
|
-
if (ancestor && /^\.\.(?:[\\/]|$)/.test(relative(ancestor, p)))
|
|
399
|
+
if (ancestor && /^\.\.(?:[\\/]|$)/.test(relative(ancestor, p))) {
|
|
385
400
|
break
|
|
401
|
+
}
|
|
386
402
|
|
|
387
403
|
const entries = nmContents.get(p) ||
|
|
388
404
|
await readdir(p + '/node_modules').catch(() => [])
|
|
389
405
|
nmContents.set(p, entries)
|
|
390
|
-
if (!entries.includes(name))
|
|
406
|
+
if (!entries.includes(name)) {
|
|
391
407
|
continue
|
|
408
|
+
}
|
|
392
409
|
|
|
393
410
|
const d = this[_cache].has(p) ? await this[_cache].get(p)
|
|
394
411
|
: new Node({ path: p, root: node.root, dummy: true })
|
|
@@ -40,8 +40,9 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
40
40
|
|
|
41
41
|
// public method
|
|
42
42
|
async loadVirtual (options = {}) {
|
|
43
|
-
if (this.virtualTree)
|
|
43
|
+
if (this.virtualTree) {
|
|
44
44
|
return this.virtualTree
|
|
45
|
+
}
|
|
45
46
|
|
|
46
47
|
// allow the user to set reify options on the ctor as well.
|
|
47
48
|
// XXX: deprecate separate reify() options object.
|
|
@@ -85,18 +86,21 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
85
86
|
root.optional = false
|
|
86
87
|
root.devOptional = false
|
|
87
88
|
root.peer = false
|
|
88
|
-
} else
|
|
89
|
+
} else {
|
|
89
90
|
this[flagsSuspect] = true
|
|
91
|
+
}
|
|
90
92
|
|
|
91
93
|
this[checkRootEdges](s, root)
|
|
92
94
|
root.meta = s
|
|
93
95
|
this.virtualTree = root
|
|
94
96
|
const {links, nodes} = this[resolveNodes](s, root)
|
|
95
97
|
await this[resolveLinks](links, nodes)
|
|
96
|
-
if (!(s.originalLockfileVersion >= 2))
|
|
98
|
+
if (!(s.originalLockfileVersion >= 2)) {
|
|
97
99
|
this[assignBundles](nodes)
|
|
98
|
-
|
|
100
|
+
}
|
|
101
|
+
if (this[flagsSuspect]) {
|
|
99
102
|
this[reCalcDepFlags](nodes.values())
|
|
103
|
+
}
|
|
100
104
|
return root
|
|
101
105
|
}
|
|
102
106
|
|
|
@@ -104,8 +108,9 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
104
108
|
// reset all dep flags
|
|
105
109
|
// can't use inventory here, because virtualTree might not be root
|
|
106
110
|
for (const node of nodes) {
|
|
107
|
-
if (node.isRoot || node === this[rootOptionProvided])
|
|
111
|
+
if (node.isRoot || node === this[rootOptionProvided]) {
|
|
108
112
|
continue
|
|
113
|
+
}
|
|
109
114
|
node.extraneous = true
|
|
110
115
|
node.dev = true
|
|
111
116
|
node.optional = true
|
|
@@ -123,8 +128,9 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
123
128
|
// loaded virtually from tree, no chance of being out of sync
|
|
124
129
|
// ancient lockfiles are critically damaged by this process,
|
|
125
130
|
// so we need to just hope for the best in those cases.
|
|
126
|
-
if (!s.loadedFromDisk || s.ancientLockfile)
|
|
131
|
+
if (!s.loadedFromDisk || s.ancientLockfile) {
|
|
127
132
|
return
|
|
133
|
+
}
|
|
128
134
|
|
|
129
135
|
const lock = s.get('')
|
|
130
136
|
const prod = lock.dependencies || {}
|
|
@@ -140,16 +146,18 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
140
146
|
}
|
|
141
147
|
}
|
|
142
148
|
}
|
|
143
|
-
for (const name of Object.keys(optional))
|
|
149
|
+
for (const name of Object.keys(optional)) {
|
|
144
150
|
delete prod[name]
|
|
151
|
+
}
|
|
145
152
|
|
|
146
153
|
const lockWS = []
|
|
147
154
|
const workspaces = this[loadWorkspacesVirtual]({
|
|
148
155
|
cwd: this.path,
|
|
149
156
|
lockfile: s.data,
|
|
150
157
|
})
|
|
151
|
-
for (const [name, path] of workspaces.entries())
|
|
158
|
+
for (const [name, path] of workspaces.entries()) {
|
|
152
159
|
lockWS.push(['workspace', name, `file:${path}`])
|
|
160
|
+
}
|
|
153
161
|
|
|
154
162
|
const lockEdges = [
|
|
155
163
|
...depsToEdges('prod', prod),
|
|
@@ -174,8 +182,9 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
174
182
|
for (let i = 0; i < lockEdges.length; i++) {
|
|
175
183
|
if (rootEdges[i][0] !== lockEdges[i][0] ||
|
|
176
184
|
rootEdges[i][1] !== lockEdges[i][1] ||
|
|
177
|
-
rootEdges[i][2] !== lockEdges[i][2])
|
|
185
|
+
rootEdges[i][2] !== lockEdges[i][2]) {
|
|
178
186
|
return this[flagsSuspect] = true
|
|
187
|
+
}
|
|
179
188
|
}
|
|
180
189
|
}
|
|
181
190
|
|
|
@@ -185,13 +194,15 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
185
194
|
const nodes = new Map([['', root]])
|
|
186
195
|
for (const [location, meta] of Object.entries(s.data.packages)) {
|
|
187
196
|
// skip the root because we already got it
|
|
188
|
-
if (!location)
|
|
197
|
+
if (!location) {
|
|
189
198
|
continue
|
|
199
|
+
}
|
|
190
200
|
|
|
191
|
-
if (meta.link)
|
|
201
|
+
if (meta.link) {
|
|
192
202
|
links.set(location, meta)
|
|
193
|
-
else
|
|
203
|
+
} else {
|
|
194
204
|
nodes.set(location, this[loadNode](location, meta))
|
|
205
|
+
}
|
|
195
206
|
}
|
|
196
207
|
return {links, nodes}
|
|
197
208
|
}
|
|
@@ -212,8 +223,9 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
212
223
|
if (!link.target.parent) {
|
|
213
224
|
const pj = link.realpath + '/package.json'
|
|
214
225
|
const pkg = await rpj(pj).catch(() => null)
|
|
215
|
-
if (pkg)
|
|
226
|
+
if (pkg) {
|
|
216
227
|
link.target.package = pkg
|
|
228
|
+
}
|
|
217
229
|
}
|
|
218
230
|
}
|
|
219
231
|
}
|
|
@@ -221,12 +233,14 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
221
233
|
[assignBundles] (nodes) {
|
|
222
234
|
for (const [location, node] of nodes) {
|
|
223
235
|
// Skip assignment of parentage for the root package
|
|
224
|
-
if (!location || node.isLink && !node.target.location)
|
|
236
|
+
if (!location || node.isLink && !node.target.location) {
|
|
225
237
|
continue
|
|
238
|
+
}
|
|
226
239
|
const { name, parent, package: { inBundle }} = node
|
|
227
240
|
|
|
228
|
-
if (!parent)
|
|
241
|
+
if (!parent) {
|
|
229
242
|
continue
|
|
243
|
+
}
|
|
230
244
|
|
|
231
245
|
// read inBundle from package because 'package' here is
|
|
232
246
|
// actually a v2 lockfile metadata entry.
|
|
@@ -236,10 +250,11 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
236
250
|
const { package: ppkg } = parent
|
|
237
251
|
const { inBundle: parentBundled } = ppkg
|
|
238
252
|
if (inBundle && !parentBundled && parent.edgesOut.has(node.name)) {
|
|
239
|
-
if (!ppkg.bundleDependencies)
|
|
253
|
+
if (!ppkg.bundleDependencies) {
|
|
240
254
|
ppkg.bundleDependencies = [name]
|
|
241
|
-
else
|
|
255
|
+
} else {
|
|
242
256
|
ppkg.bundleDependencies.push(name)
|
|
257
|
+
}
|
|
243
258
|
}
|
|
244
259
|
}
|
|
245
260
|
}
|
|
@@ -248,8 +263,9 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
248
263
|
const p = this.virtualTree ? this.virtualTree.realpath : this.path
|
|
249
264
|
const path = resolve(p, location)
|
|
250
265
|
// shrinkwrap doesn't include package name unless necessary
|
|
251
|
-
if (!sw.name)
|
|
266
|
+
if (!sw.name) {
|
|
252
267
|
sw.name = nameFromFolder(path)
|
|
268
|
+
}
|
|
253
269
|
|
|
254
270
|
const dev = sw.dev
|
|
255
271
|
const optional = sw.optional
|
|
@@ -7,15 +7,17 @@ const _loadWorkspacesVirtual = Symbol.for('loadWorkspacesVirtual')
|
|
|
7
7
|
|
|
8
8
|
module.exports = cls => class MapWorkspaces extends cls {
|
|
9
9
|
[_appendWorkspaces] (node, workspaces) {
|
|
10
|
-
if (node && workspaces.size)
|
|
10
|
+
if (node && workspaces.size) {
|
|
11
11
|
node.workspaces = workspaces
|
|
12
|
+
}
|
|
12
13
|
|
|
13
14
|
return node
|
|
14
15
|
}
|
|
15
16
|
|
|
16
17
|
async [_loadWorkspaces] (node) {
|
|
17
|
-
if (node.workspaces)
|
|
18
|
+
if (node.workspaces) {
|
|
18
19
|
return node
|
|
20
|
+
}
|
|
19
21
|
|
|
20
22
|
const workspaces = await mapWorkspaces({
|
|
21
23
|
cwd: node.path,
|
package/lib/arborist/rebuild.js
CHANGED
|
@@ -61,8 +61,9 @@ module.exports = cls => class Builder extends cls {
|
|
|
61
61
|
|
|
62
62
|
async rebuild ({ nodes, handleOptionalFailure = false } = {}) {
|
|
63
63
|
// nothing to do if we're not building anything!
|
|
64
|
-
if (this[_ignoreScripts] && !this[_binLinks])
|
|
64
|
+
if (this[_ignoreScripts] && !this[_binLinks]) {
|
|
65
65
|
return
|
|
66
|
+
}
|
|
66
67
|
|
|
67
68
|
// when building for the first time, as part of reify, we ignore
|
|
68
69
|
// failures in optional nodes, and just delete them. however, when
|
|
@@ -76,8 +77,9 @@ module.exports = cls => class Builder extends cls {
|
|
|
76
77
|
if (this[_workspaces] && this[_workspaces].length) {
|
|
77
78
|
const filterSet = this.workspaceDependencySet(tree, this[_workspaces])
|
|
78
79
|
nodes = tree.inventory.filter(node => filterSet.has(node))
|
|
79
|
-
} else
|
|
80
|
+
} else {
|
|
80
81
|
nodes = tree.inventory.values()
|
|
82
|
+
}
|
|
81
83
|
}
|
|
82
84
|
|
|
83
85
|
// separates links nodes so that it can run
|
|
@@ -88,10 +90,11 @@ module.exports = cls => class Builder extends cls {
|
|
|
88
90
|
for (const node of nodes) {
|
|
89
91
|
// we skip the target nodes to that workspace in order to make sure
|
|
90
92
|
// we only run lifecycle scripts / place bin links once per workspace
|
|
91
|
-
if (node.isLink)
|
|
93
|
+
if (node.isLink) {
|
|
92
94
|
linkNodes.add(node)
|
|
93
|
-
else
|
|
95
|
+
} else {
|
|
94
96
|
depNodes.add(node)
|
|
97
|
+
}
|
|
95
98
|
}
|
|
96
99
|
|
|
97
100
|
await this[_build](depNodes, {})
|
|
@@ -118,17 +121,20 @@ module.exports = cls => class Builder extends cls {
|
|
|
118
121
|
process.emit('time', `build:${type}`)
|
|
119
122
|
|
|
120
123
|
await this[_buildQueues](nodes)
|
|
121
|
-
if (!this[_ignoreScripts])
|
|
124
|
+
if (!this[_ignoreScripts]) {
|
|
122
125
|
await this[_runScripts]('preinstall')
|
|
123
|
-
|
|
126
|
+
}
|
|
127
|
+
if (this[_binLinks] && type !== 'links') {
|
|
124
128
|
await this[_linkAllBins]()
|
|
129
|
+
}
|
|
125
130
|
|
|
126
131
|
// links should also run prepare scripts and only link bins after that
|
|
127
132
|
if (type === 'links') {
|
|
128
133
|
await this[_runScripts]('prepare')
|
|
129
134
|
|
|
130
|
-
if (this[_binLinks])
|
|
135
|
+
if (this[_binLinks]) {
|
|
131
136
|
await this[_linkAllBins]()
|
|
137
|
+
}
|
|
132
138
|
}
|
|
133
139
|
|
|
134
140
|
if (!this[_ignoreScripts]) {
|
|
@@ -173,8 +179,9 @@ module.exports = cls => class Builder extends cls {
|
|
|
173
179
|
const { preinstall, install, postinstall, prepare } = scripts
|
|
174
180
|
const tests = { bin, preinstall, install, postinstall, prepare }
|
|
175
181
|
for (const [key, has] of Object.entries(tests)) {
|
|
176
|
-
if (has)
|
|
182
|
+
if (has) {
|
|
177
183
|
this[_queues][key].push(node)
|
|
184
|
+
}
|
|
178
185
|
}
|
|
179
186
|
}
|
|
180
187
|
process.emit('timeEnd', 'build:queue')
|
|
@@ -186,15 +193,17 @@ module.exports = cls => class Builder extends cls {
|
|
|
186
193
|
// the node path. Otherwise a package can have a preinstall script
|
|
187
194
|
// that unlinks something, to allow them to silently overwrite system
|
|
188
195
|
// binaries, which is unsafe and insecure.
|
|
189
|
-
if (!node.globalTop || this[_force])
|
|
196
|
+
if (!node.globalTop || this[_force]) {
|
|
190
197
|
return
|
|
198
|
+
}
|
|
191
199
|
const { path, package: pkg } = node
|
|
192
200
|
await binLinks.checkBins({ pkg, path, top: true, global: true })
|
|
193
201
|
}
|
|
194
202
|
|
|
195
203
|
async [_addToBuildSet] (node, set, refreshed = false) {
|
|
196
|
-
if (set.has(node))
|
|
204
|
+
if (set.has(node)) {
|
|
197
205
|
return
|
|
206
|
+
}
|
|
198
207
|
|
|
199
208
|
if (this[_oldMeta] === null) {
|
|
200
209
|
const {root: {meta}} = node
|
|
@@ -233,8 +242,9 @@ module.exports = cls => class Builder extends cls {
|
|
|
233
242
|
await isNodeGypPackage(node.path)
|
|
234
243
|
|
|
235
244
|
if (bin || preinstall || install || postinstall || prepare || isGyp) {
|
|
236
|
-
if (bin)
|
|
245
|
+
if (bin) {
|
|
237
246
|
await this[_checkBins](node)
|
|
247
|
+
}
|
|
238
248
|
if (isGyp) {
|
|
239
249
|
scripts.install = defaultGypInstallScript
|
|
240
250
|
node.package.scripts = scripts
|
|
@@ -246,8 +256,9 @@ module.exports = cls => class Builder extends cls {
|
|
|
246
256
|
async [_runScripts] (event) {
|
|
247
257
|
const queue = this[_queues][event]
|
|
248
258
|
|
|
249
|
-
if (!queue.length)
|
|
259
|
+
if (!queue.length) {
|
|
250
260
|
return
|
|
261
|
+
}
|
|
251
262
|
|
|
252
263
|
process.emit('time', `build:run:${event}`)
|
|
253
264
|
const stdio = this.options.foregroundScripts ? 'inherit' : 'pipe'
|
|
@@ -266,8 +277,9 @@ module.exports = cls => class Builder extends cls {
|
|
|
266
277
|
} = node.target
|
|
267
278
|
|
|
268
279
|
// skip any that we know we'll be deleting
|
|
269
|
-
if (this[_trashList].has(path))
|
|
280
|
+
if (this[_trashList].has(path)) {
|
|
270
281
|
return
|
|
282
|
+
}
|
|
271
283
|
|
|
272
284
|
const timer = `build:run:${event}:${location}`
|
|
273
285
|
process.emit('time', timer)
|
|
@@ -321,23 +333,26 @@ module.exports = cls => class Builder extends cls {
|
|
|
321
333
|
|
|
322
334
|
async [_linkAllBins] () {
|
|
323
335
|
const queue = this[_queues].bin
|
|
324
|
-
if (!queue.length)
|
|
336
|
+
if (!queue.length) {
|
|
325
337
|
return
|
|
338
|
+
}
|
|
326
339
|
|
|
327
340
|
process.emit('time', 'build:link')
|
|
328
341
|
const promises = []
|
|
329
342
|
// sort the queue by node path, so that the module-local collision
|
|
330
343
|
// detector in bin-links will always resolve the same way.
|
|
331
|
-
for (const node of queue.sort(sortNodes))
|
|
344
|
+
for (const node of queue.sort(sortNodes)) {
|
|
332
345
|
promises.push(this[_createBinLinks](node))
|
|
346
|
+
}
|
|
333
347
|
|
|
334
348
|
await promiseAllRejectLate(promises)
|
|
335
349
|
process.emit('timeEnd', 'build:link')
|
|
336
350
|
}
|
|
337
351
|
|
|
338
352
|
async [_createBinLinks] (node) {
|
|
339
|
-
if (this[_trashList].has(node.path))
|
|
353
|
+
if (this[_trashList].has(node.path)) {
|
|
340
354
|
return
|
|
355
|
+
}
|
|
341
356
|
|
|
342
357
|
process.emit('time', `build:link:${node.location}`)
|
|
343
358
|
|