@npmcli/arborist 7.5.0 → 7.5.2
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 -46
- package/lib/arborist/index.js +28 -3
- package/lib/arborist/isolated-reifier.js +1 -1
- package/lib/arborist/load-actual.js +2 -2
- package/lib/arborist/load-virtual.js +1 -1
- package/lib/arborist/reify.js +254 -318
- package/lib/dep-valid.js +1 -1
- package/lib/inventory.js +1 -1
- package/lib/node.js +2 -0
- package/lib/packument-cache.js +77 -0
- package/lib/query-selector-all.js +6 -6
- package/lib/shrinkwrap.js +2 -1
- package/package.json +18 -17
|
@@ -53,48 +53,26 @@ const _addNodeToTrashList = Symbol.for('addNodeToTrashList')
|
|
|
53
53
|
// they'll affect things deeper in, then alphabetical for consistency between
|
|
54
54
|
// installs
|
|
55
55
|
class DepsQueue {
|
|
56
|
-
// [{ sorted, items }] indexed by depth
|
|
57
56
|
#deps = []
|
|
58
57
|
#sorted = true
|
|
59
|
-
#minDepth = 0
|
|
60
|
-
#length = 0
|
|
61
58
|
|
|
62
59
|
get length () {
|
|
63
|
-
return this.#length
|
|
60
|
+
return this.#deps.length
|
|
64
61
|
}
|
|
65
62
|
|
|
66
63
|
push (item) {
|
|
67
|
-
if (!this.#deps
|
|
68
|
-
this.#
|
|
69
|
-
this.#deps
|
|
70
|
-
// no minDepth check needed, this branch is only reached when we are in
|
|
71
|
-
// the middle of a shallower depth and creating a new one
|
|
72
|
-
return
|
|
73
|
-
}
|
|
74
|
-
if (!this.#deps[item.depth].items.includes(item)) {
|
|
75
|
-
this.#length++
|
|
76
|
-
this.#deps[item.depth].sorted = false
|
|
77
|
-
this.#deps[item.depth].items.push(item)
|
|
78
|
-
if (item.depth < this.#minDepth) {
|
|
79
|
-
this.#minDepth = item.depth
|
|
80
|
-
}
|
|
64
|
+
if (!this.#deps.includes(item)) {
|
|
65
|
+
this.#sorted = false
|
|
66
|
+
this.#deps.push(item)
|
|
81
67
|
}
|
|
82
68
|
}
|
|
83
69
|
|
|
84
70
|
pop () {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
if (!depth?.items.length) {
|
|
89
|
-
this.#minDepth++
|
|
90
|
-
}
|
|
71
|
+
if (!this.#sorted) {
|
|
72
|
+
this.#deps.sort((a, b) => (a.depth - b.depth) || localeCompare(a.path, b.path))
|
|
73
|
+
this.#sorted = true
|
|
91
74
|
}
|
|
92
|
-
|
|
93
|
-
depth.items.sort((a, b) => localeCompare(a.path, b.path))
|
|
94
|
-
depth.sorted = true
|
|
95
|
-
}
|
|
96
|
-
this.#length--
|
|
97
|
-
return depth.items.shift()
|
|
75
|
+
return this.#deps.shift()
|
|
98
76
|
}
|
|
99
77
|
}
|
|
100
78
|
|
|
@@ -463,7 +441,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
|
|
|
463
441
|
}
|
|
464
442
|
const dir = resolve(nm, name)
|
|
465
443
|
const st = await lstat(dir)
|
|
466
|
-
.catch(/* istanbul ignore next */
|
|
444
|
+
.catch(/* istanbul ignore next */ () => null)
|
|
467
445
|
if (st && st.isSymbolicLink()) {
|
|
468
446
|
const target = await readlink(dir)
|
|
469
447
|
const real = resolve(dirname(dir), target).replace(/#/g, '%23')
|
|
@@ -1022,9 +1000,13 @@ This is a one-time fix-up, please be patient...
|
|
|
1022
1000
|
// may well be an optional dep that has gone missing. it'll
|
|
1023
1001
|
// fail later anyway.
|
|
1024
1002
|
for (const e of this.#problemEdges(placed)) {
|
|
1003
|
+
// XXX This is somehow load bearing. This makes tests that print
|
|
1004
|
+
// the ideal tree of a tree with tarball dependencies fail. This
|
|
1005
|
+
// can't be changed or removed till we figure out why
|
|
1006
|
+
// The test is named "tarball deps with transitive tarball deps"
|
|
1025
1007
|
promises.push(() =>
|
|
1026
1008
|
this.#fetchManifest(npa.resolve(e.name, e.spec, fromPath(placed, e)))
|
|
1027
|
-
.catch(
|
|
1009
|
+
.catch(() => null)
|
|
1028
1010
|
)
|
|
1029
1011
|
}
|
|
1030
1012
|
},
|
|
@@ -1204,6 +1186,7 @@ This is a one-time fix-up, please be patient...
|
|
|
1204
1186
|
const options = {
|
|
1205
1187
|
...this.options,
|
|
1206
1188
|
avoid: this.#avoidRange(spec.name),
|
|
1189
|
+
fullMetadata: true,
|
|
1207
1190
|
}
|
|
1208
1191
|
// get the intended spec and stored metadata from yarn.lock file,
|
|
1209
1192
|
// if available and valid.
|
|
@@ -1212,19 +1195,10 @@ This is a one-time fix-up, please be patient...
|
|
|
1212
1195
|
if (this.#manifests.has(spec.raw)) {
|
|
1213
1196
|
return this.#manifests.get(spec.raw)
|
|
1214
1197
|
} else {
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
fullMetadata: true,
|
|
1220
|
-
}
|
|
1221
|
-
const p = pacote.manifest(spec, o)
|
|
1222
|
-
.then(({ license, ...mani }) => {
|
|
1223
|
-
this.#manifests.set(spec.raw, mani)
|
|
1224
|
-
return mani
|
|
1225
|
-
})
|
|
1226
|
-
this.#manifests.set(spec.raw, p)
|
|
1227
|
-
return p
|
|
1198
|
+
log.silly('fetch manifest', spec.raw.replace(spec.rawSpec, redact(spec.rawSpec)))
|
|
1199
|
+
const mani = await pacote.manifest(spec, options)
|
|
1200
|
+
this.#manifests.set(spec.raw, mani)
|
|
1201
|
+
return mani
|
|
1228
1202
|
}
|
|
1229
1203
|
}
|
|
1230
1204
|
|
|
@@ -1273,7 +1247,7 @@ This is a one-time fix-up, please be patient...
|
|
|
1273
1247
|
})
|
|
1274
1248
|
}
|
|
1275
1249
|
|
|
1276
|
-
#linkFromSpec (name, spec, parent
|
|
1250
|
+
#linkFromSpec (name, spec, parent) {
|
|
1277
1251
|
const realpath = spec.fetchSpec
|
|
1278
1252
|
const { installLinks, legacyPeerDeps } = this
|
|
1279
1253
|
return rpj(realpath + '/package.json').catch(() => ({})).then(pkg => {
|
package/lib/arborist/index.js
CHANGED
|
@@ -31,10 +31,10 @@ const { homedir } = require('os')
|
|
|
31
31
|
const { depth } = require('treeverse')
|
|
32
32
|
const mapWorkspaces = require('@npmcli/map-workspaces')
|
|
33
33
|
const { log, time } = require('proc-log')
|
|
34
|
-
|
|
35
34
|
const { saveTypeMap } = require('../add-rm-pkg-deps.js')
|
|
36
35
|
const AuditReport = require('../audit-report.js')
|
|
37
36
|
const relpath = require('../relpath.js')
|
|
37
|
+
const PackumentCache = require('../packument-cache.js')
|
|
38
38
|
|
|
39
39
|
const mixins = [
|
|
40
40
|
require('../tracker.js'),
|
|
@@ -74,20 +74,26 @@ class Arborist extends Base {
|
|
|
74
74
|
Arborist: this.constructor,
|
|
75
75
|
binLinks: 'binLinks' in options ? !!options.binLinks : true,
|
|
76
76
|
cache: options.cache || `${homedir()}/.npm/_cacache`,
|
|
77
|
+
dryRun: !!options.dryRun,
|
|
78
|
+
formatPackageLock: 'formatPackageLock' in options ? !!options.formatPackageLock : true,
|
|
77
79
|
force: !!options.force,
|
|
78
80
|
global: !!options.global,
|
|
79
81
|
ignoreScripts: !!options.ignoreScripts,
|
|
80
82
|
installStrategy: options.global ? 'shallow' : (options.installStrategy ? options.installStrategy : 'hoisted'),
|
|
81
83
|
lockfileVersion: lockfileVersion(options.lockfileVersion),
|
|
82
|
-
|
|
84
|
+
packageLockOnly: !!options.packageLockOnly,
|
|
85
|
+
packumentCache: options.packumentCache || new PackumentCache(),
|
|
83
86
|
path: options.path || '.',
|
|
84
87
|
rebuildBundle: 'rebuildBundle' in options ? !!options.rebuildBundle : true,
|
|
85
88
|
replaceRegistryHost: options.replaceRegistryHost,
|
|
89
|
+
savePrefix: 'savePrefix' in options ? options.savePrefix : '^',
|
|
86
90
|
scriptShell: options.scriptShell,
|
|
87
91
|
workspaces: options.workspaces || [],
|
|
88
92
|
workspacesEnabled: options.workspacesEnabled !== false,
|
|
89
93
|
}
|
|
90
|
-
// TODO
|
|
94
|
+
// TODO we only ever look at this.options.replaceRegistryHost, not
|
|
95
|
+
// this.replaceRegistryHost. Defaulting needs to be written back to
|
|
96
|
+
// this.options to work properly
|
|
91
97
|
this.replaceRegistryHost = this.options.replaceRegistryHost =
|
|
92
98
|
(!this.options.replaceRegistryHost || this.options.replaceRegistryHost === 'npmjs') ?
|
|
93
99
|
'registry.npmjs.org' : this.options.replaceRegistryHost
|
|
@@ -96,6 +102,7 @@ class Arborist extends Base {
|
|
|
96
102
|
throw new Error(`Invalid saveType ${options.saveType}`)
|
|
97
103
|
}
|
|
98
104
|
this.cache = resolve(this.options.cache)
|
|
105
|
+
this.diff = null
|
|
99
106
|
this.path = resolve(this.options.path)
|
|
100
107
|
timeEnd()
|
|
101
108
|
}
|
|
@@ -250,6 +257,24 @@ class Arborist extends Base {
|
|
|
250
257
|
this.finishTracker('audit')
|
|
251
258
|
return ret
|
|
252
259
|
}
|
|
260
|
+
|
|
261
|
+
async dedupe (options = {}) {
|
|
262
|
+
// allow the user to set options on the ctor as well.
|
|
263
|
+
// XXX: deprecate separate method options objects.
|
|
264
|
+
options = { ...this.options, ...options }
|
|
265
|
+
const tree = await this.loadVirtual().catch(() => this.loadActual())
|
|
266
|
+
const names = []
|
|
267
|
+
for (const name of tree.inventory.query('name')) {
|
|
268
|
+
if (tree.inventory.query('name', name).size > 1) {
|
|
269
|
+
names.push(name)
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
return this.reify({
|
|
273
|
+
...options,
|
|
274
|
+
preferDedupe: true,
|
|
275
|
+
update: { names },
|
|
276
|
+
})
|
|
277
|
+
}
|
|
253
278
|
}
|
|
254
279
|
|
|
255
280
|
module.exports = Arborist
|
|
@@ -212,7 +212,7 @@ module.exports = cls => class IsolatedReifier extends cls {
|
|
|
212
212
|
return { edges, nodes }
|
|
213
213
|
}
|
|
214
214
|
|
|
215
|
-
async [_createIsolatedTree] (
|
|
215
|
+
async [_createIsolatedTree] () {
|
|
216
216
|
await this[_makeIdealGraph](this.options)
|
|
217
217
|
|
|
218
218
|
const proxiedIdealTree = this.idealGraph
|
|
@@ -336,8 +336,8 @@ module.exports = cls => class ActualLoader extends cls {
|
|
|
336
336
|
await this.#loadFSChildren(node.target)
|
|
337
337
|
return Promise.all(
|
|
338
338
|
[...node.target.children.entries()]
|
|
339
|
-
.filter(([
|
|
340
|
-
.map(([
|
|
339
|
+
.filter(([, kid]) => !did.has(kid.realpath))
|
|
340
|
+
.map(([, kid]) => this.#loadFSTree(kid))
|
|
341
341
|
)
|
|
342
342
|
}
|
|
343
343
|
}
|
|
@@ -283,7 +283,7 @@ module.exports = cls => class VirtualLoader extends cls {
|
|
|
283
283
|
return node
|
|
284
284
|
}
|
|
285
285
|
|
|
286
|
-
#loadLink (location, targetLoc, target
|
|
286
|
+
#loadLink (location, targetLoc, target) {
|
|
287
287
|
const path = resolve(this.path, location)
|
|
288
288
|
const link = new Link({
|
|
289
289
|
installLinks: this.installLinks,
|