@npmcli/arborist 2.8.0 → 2.8.1

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/dedupe.js ADDED
@@ -0,0 +1,46 @@
1
+ const Arborist = require('../')
2
+
3
+ const options = require('./lib/options.js')
4
+ const print = require('./lib/print-tree.js')
5
+ require('./lib/logging.js')
6
+ require('./lib/timers.js')
7
+
8
+ const printDiff = diff => {
9
+ const {depth} = require('treeverse')
10
+ depth({
11
+ tree: diff,
12
+ visit: d => {
13
+ if (d.location === '')
14
+ return
15
+ switch (d.action) {
16
+ case 'REMOVE':
17
+ console.error('REMOVE', d.actual.location)
18
+ break
19
+ case 'ADD':
20
+ console.error('ADD', d.ideal.location, d.ideal.resolved)
21
+ break
22
+ case 'CHANGE':
23
+ console.error('CHANGE', d.actual.location, {
24
+ from: d.actual.resolved,
25
+ to: d.ideal.resolved,
26
+ })
27
+ break
28
+ }
29
+ },
30
+ getChildren: d => d.children,
31
+ })
32
+ }
33
+
34
+ const start = process.hrtime()
35
+ process.emit('time', 'install')
36
+ const arb = new Arborist(options)
37
+ arb.dedupe(options).then(tree => {
38
+ process.emit('timeEnd', 'install')
39
+ const end = process.hrtime(start)
40
+ print(tree)
41
+ if (options.dryRun)
42
+ printDiff(arb.diff)
43
+ console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`)
44
+ if (tree.meta && options.save)
45
+ tree.meta.save()
46
+ }).catch(er => console.error(require('util').inspect(er, { depth: Infinity })))
@@ -982,7 +982,6 @@ This is a one-time fix-up, please be patient...
982
982
  // Note that the virtual root will also have virtual copies of the
983
983
  // targets of any child Links, so that they resolve appropriately.
984
984
  const parent = parent_ || this[_virtualRoot](edge.from)
985
- const realParent = edge.peer ? edge.from.resolveParent : edge.from
986
985
 
987
986
  const spec = npa.resolve(edge.name, edge.spec, edge.from.path)
988
987
  const first = await this[_nodeFromSpec](edge.name, spec, parent, edge)
@@ -1013,16 +1012,6 @@ This is a one-time fix-up, please be patient...
1013
1012
  required.has(secondEdge.from) && secondEdge.type !== 'peerOptional'))
1014
1013
  required.add(node)
1015
1014
 
1016
- // handle otherwise unresolvable dependency nesting loops by
1017
- // creating a symbolic link
1018
- // a1 -> b1 -> a2 -> b2 -> a1 -> ...
1019
- // instead of nesting forever, when the loop occurs, create
1020
- // a symbolic link to the earlier instance
1021
- for (let p = edge.from.resolveParent; p; p = p.resolveParent) {
1022
- if (p.matches(node) && !p.isTop)
1023
- return new Link({ parent: realParent, target: p })
1024
- }
1025
-
1026
1015
  // keep track of the thing that caused this node to be included.
1027
1016
  const src = parent.sourceReference
1028
1017
  this[_peerSetSource].set(node, src)
@@ -73,8 +73,10 @@ class CanPlaceDep {
73
73
  if (!edge)
74
74
  throw new Error('no edge provided to CanPlaceDep')
75
75
 
76
- this._nodeSnapshot = JSON.stringify(dep)
77
- this._treeSnapshot = JSON.stringify(target.root)
76
+ this._treeSnapshot = JSON.stringify([...target.root.inventory.entries()]
77
+ .map(([loc, {packageName, version, resolved}]) => {
78
+ return [loc, packageName, version, resolved]
79
+ }).sort(([a], [b]) => a.localeCompare(b, 'en')))
78
80
  })
79
81
 
80
82
  // the result of whether we can place it or not
@@ -110,15 +112,10 @@ class CanPlaceDep {
110
112
  this.canPlaceSelf = this.canPlace
111
113
 
112
114
  debug(() => {
113
- const nodeSnapshot = JSON.stringify(dep)
114
- const treeSnapshot = JSON.stringify(target.root)
115
- /* istanbul ignore if */
116
- if (this._nodeSnapshot !== nodeSnapshot) {
117
- throw Object.assign(new Error('dep changed in CanPlaceDep'), {
118
- expect: this._nodeSnapshot,
119
- actual: nodeSnapshot,
120
- })
121
- }
115
+ const treeSnapshot = JSON.stringify([...target.root.inventory.entries()]
116
+ .map(([loc, {packageName, version, resolved}]) => {
117
+ return [loc, packageName, version, resolved]
118
+ }).sort(([a], [b]) => a.localeCompare(b, 'en')))
122
119
  /* istanbul ignore if */
123
120
  if (this._treeSnapshot !== treeSnapshot) {
124
121
  throw Object.assign(new Error('tree changed in CanPlaceDep'), {
package/lib/place-dep.js CHANGED
@@ -16,6 +16,7 @@ const {
16
16
  } = CanPlaceDep
17
17
  const debug = require('./debug.js')
18
18
 
19
+ const Link = require('./link.js')
19
20
  const gatherDepSet = require('./gather-dep-set.js')
20
21
  const peerEntrySets = require('./peer-entry-sets.js')
21
22
 
@@ -256,6 +257,20 @@ class PlaceDep {
256
257
  return
257
258
  }
258
259
 
260
+ // we were told to place it here in the target, so either it does not
261
+ // already exist in the tree, OR it's shadowed.
262
+ // handle otherwise unresolvable dependency nesting loops by
263
+ // creating a symbolic link
264
+ // a1 -> b1 -> a2 -> b2 -> a1 -> ...
265
+ // instead of nesting forever, when the loop occurs, create
266
+ // a symbolic link to the earlier instance
267
+ for (let p = target; p; p = p.resolveParent) {
268
+ if (p.matches(dep) && !p.isTop) {
269
+ this.placed = new Link({ parent: target, target: p })
270
+ return
271
+ }
272
+ }
273
+
259
274
  // XXX if we are replacing SOME of a peer entry group, we will need to
260
275
  // remove any that are not being replaced and will now be invalid, and
261
276
  // re-evaluate them deeper into the tree.
@@ -268,7 +283,7 @@ class PlaceDep {
268
283
  integrity: dep.integrity,
269
284
  legacyPeerDeps: this.legacyPeerDeps,
270
285
  error: dep.errors[0],
271
- ...(dep.isLink ? { target: dep.target, realpath: dep.target.path } : {}),
286
+ ...(dep.isLink ? { target: dep.target, realpath: dep.realpath } : {}),
272
287
  })
273
288
 
274
289
  this.oldDep = target.children.get(this.name)
package/lib/shrinkwrap.js CHANGED
@@ -255,9 +255,11 @@ class Shrinkwrap {
255
255
  if (val)
256
256
  meta[key.replace(/^_/, '')] = val
257
257
  })
258
- // we only include name if different from the node path name
258
+ // we only include name if different from the node path name, and for the
259
+ // root to help prevent churn based on the name of the directory the
260
+ // project is in
259
261
  const pname = node.packageName
260
- if (pname && pname !== node.name)
262
+ if (pname && (node === node.root || pname !== node.name))
261
263
  meta.name = pname
262
264
 
263
265
  if (node.isTop && node.package.devDependencies)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/arborist",
3
- "version": "2.8.0",
3
+ "version": "2.8.1",
4
4
  "description": "Manage node_modules trees",
5
5
  "dependencies": {
6
6
  "@npmcli/installed-package-contents": "^1.0.7",