@npmcli/arborist 2.6.2 → 2.6.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.
@@ -7,7 +7,7 @@ const semver = require('semver')
7
7
  const promiseCallLimit = require('promise-call-limit')
8
8
  const getPeerSet = require('../peer-set.js')
9
9
  const realpath = require('../../lib/realpath.js')
10
- const { resolve } = require('path')
10
+ const { resolve, dirname } = require('path')
11
11
  const { promisify } = require('util')
12
12
  const treeCheck = require('../tree-check.js')
13
13
  const readdir = promisify(require('readdir-scoped-modules'))
@@ -661,7 +661,7 @@ module.exports = cls => class IdealTreeBuilder extends cls {
661
661
  const ancient = meta.ancientLockfile
662
662
  const old = meta.loadedFromDisk && !(meta.originalLockfileVersion >= 2)
663
663
 
664
- if (inventory.size === 0 || !ancient && !(old && this[_complete]))
664
+ if (inventory.size === 0 || !ancient && !old)
665
665
  return
666
666
 
667
667
  // if the lockfile is from node v5 or earlier, then we'll have to reload
@@ -688,10 +688,12 @@ This is a one-time fix-up, please be patient...
688
688
  this.log.silly('inflate', node.location)
689
689
  const { resolved, version, path, name, location, integrity } = node
690
690
  // don't try to hit the registry for linked deps
691
- const useResolved = !version ||
692
- resolved && resolved.startsWith('file:')
693
- const id = useResolved ? resolved : version
694
- const spec = npa.resolve(name, id, path)
691
+ const useResolved = resolved && (
692
+ !version || resolved.startsWith('file:')
693
+ )
694
+ const id = useResolved ? resolved
695
+ : version || `file:${node.path}`
696
+ const spec = npa.resolve(name, id, dirname(path))
695
697
  const sloc = location.substr('node_modules/'.length)
696
698
  const t = `idealTree:inflate:${sloc}`
697
699
  this.addTracker(t)
@@ -28,7 +28,7 @@
28
28
 
29
29
  const {resolve} = require('path')
30
30
  const {homedir} = require('os')
31
- const procLog = require('../proc-log.js')
31
+ const procLog = require('proc-log')
32
32
  const { saveTypeMap } = require('../add-rm-pkg-deps.js')
33
33
 
34
34
  const mixins = [
@@ -22,6 +22,7 @@ const _loadFSTree = Symbol('loadFSTree')
22
22
  const _loadFSChildren = Symbol('loadFSChildren')
23
23
  const _findMissingEdges = Symbol('findMissingEdges')
24
24
  const _findFSParents = Symbol('findFSParents')
25
+ const _resetDepFlags = Symbol('resetDepFlags')
25
26
 
26
27
  const _actualTreeLoaded = Symbol('actualTreeLoaded')
27
28
  const _rpcache = Symbol.for('realpathCache')
@@ -74,6 +75,19 @@ module.exports = cls => class ActualLoader extends cls {
74
75
  this[_topNodes] = new Set()
75
76
  }
76
77
 
78
+ [_resetDepFlags] (tree, root) {
79
+ // reset all deps to extraneous prior to recalc
80
+ if (!root) {
81
+ for (const node of tree.inventory.values())
82
+ node.extraneous = true
83
+ }
84
+
85
+ // only reset root flags if we're not re-rooting,
86
+ // otherwise leave as-is
87
+ calcDepFlags(tree, !root)
88
+ return tree
89
+ }
90
+
77
91
  // public method
78
92
  async loadActual (options = {}) {
79
93
  // allow the user to set options on the ctor as well.
@@ -88,6 +102,7 @@ module.exports = cls => class ActualLoader extends cls {
88
102
  return this.actualTree ? this.actualTree
89
103
  : this[_actualTreePromise] ? this[_actualTreePromise]
90
104
  : this[_actualTreePromise] = this[_loadActual](options)
105
+ .then(tree => this[_resetDepFlags](tree, options.root))
91
106
  .then(tree => this.actualTree = treeCheck(tree))
92
107
  }
93
108
 
@@ -152,8 +167,7 @@ module.exports = cls => class ActualLoader extends cls {
152
167
  root: this[_actualTree],
153
168
  })
154
169
  await this[_loadWorkspaces](this[_actualTree])
155
- if (this[_actualTree].workspaces && this[_actualTree].workspaces.size)
156
- calcDepFlags(this[_actualTree], !root)
170
+
157
171
  this[_transplant](root)
158
172
  return this[_actualTree]
159
173
  }
@@ -178,8 +192,6 @@ module.exports = cls => class ActualLoader extends cls {
178
192
  dependencies[name] = dependencies[name] || '*'
179
193
  actualRoot.package = { ...actualRoot.package, dependencies }
180
194
  }
181
- // only reset root flags if we're not re-rooting, otherwise leave as-is
182
- calcDepFlags(this[_actualTree], !root)
183
195
  return this[_actualTree]
184
196
  }
185
197
 
@@ -2,7 +2,6 @@
2
2
 
3
3
  const onExit = require('../signal-handling.js')
4
4
  const pacote = require('pacote')
5
- const rpj = require('read-package-json-fast')
6
5
  const AuditReport = require('../audit-report.js')
7
6
  const {subset, intersects} = require('semver')
8
7
  const npa = require('npm-package-arg')
@@ -57,7 +56,6 @@ const _extractOrLink = Symbol('extractOrLink')
57
56
  const _checkBins = Symbol.for('checkBins')
58
57
  const _symlink = Symbol('symlink')
59
58
  const _warnDeprecated = Symbol('warnDeprecated')
60
- const _loadAncientPackageDetails = Symbol('loadAncientPackageDetails')
61
59
  const _loadBundlesAndUpdateTrees = Symbol.for('loadBundlesAndUpdateTrees')
62
60
  const _submitQuickAudit = Symbol('submitQuickAudit')
63
61
  const _awaitQuickAudit = Symbol('awaitQuickAudit')
@@ -522,7 +520,6 @@ module.exports = cls => class Reifier extends cls {
522
520
  await this[_checkBins](node)
523
521
  await this[_extractOrLink](node)
524
522
  await this[_warnDeprecated](node)
525
- await this[_loadAncientPackageDetails](node)
526
523
  })
527
524
 
528
525
  return this[_handleOptionalFailure](node, p)
@@ -583,32 +580,6 @@ module.exports = cls => class Reifier extends cls {
583
580
  this.log.warn('deprecated', `${_id}: ${deprecated}`)
584
581
  }
585
582
 
586
- async [_loadAncientPackageDetails] (node, forceReload = false) {
587
- // If we're loading from a v1 lockfile, load details from the package.json
588
- // that weren't recorded in the old format.
589
- const {meta} = this.idealTree
590
- const ancient = meta.ancientLockfile
591
- const old = meta.loadedFromDisk && !(meta.originalLockfileVersion >= 2)
592
-
593
- // already replaced with the manifest if it's truly ancient
594
- if (node.path && (forceReload || (old && !ancient))) {
595
- // XXX should have a shared location where package.json is read,
596
- // so we don't ever read the same pj more than necessary.
597
- let pkg
598
- try {
599
- pkg = await rpj(node.path + '/package.json')
600
- } catch (err) {}
601
-
602
- if (pkg) {
603
- node.package.bin = pkg.bin
604
- node.package.os = pkg.os
605
- node.package.cpu = pkg.cpu
606
- node.package.engines = pkg.engines
607
- meta.add(node)
608
- }
609
- }
610
- }
611
-
612
583
  // if the node is optional, then the failure of the promise is nonfatal
613
584
  // just add it and its optional set to the trash list.
614
585
  [_handleOptionalFailure] (node, p) {
@@ -1079,12 +1050,6 @@ module.exports = cls => class Reifier extends cls {
1079
1050
 
1080
1051
  const { meta } = this.idealTree
1081
1052
 
1082
- // might have to update metadata for bins and stuff that gets lost
1083
- if (meta.loadedFromDisk && !(meta.originalLockfileVersion >= 2)) {
1084
- for (const node of this.idealTree.inventory.values())
1085
- await this[_loadAncientPackageDetails](node, true)
1086
- }
1087
-
1088
1053
  return meta.save(saveOpt)
1089
1054
  }
1090
1055
 
@@ -12,7 +12,7 @@ const _fixAvailable = Symbol('fixAvailable')
12
12
  const _checkTopNode = Symbol('checkTopNode')
13
13
  const _init = Symbol('init')
14
14
  const _omit = Symbol('omit')
15
- const procLog = require('./proc-log.js')
15
+ const procLog = require('proc-log')
16
16
 
17
17
  const fetch = require('npm-registry-fetch')
18
18
 
@@ -22,6 +22,11 @@ const calcDepFlagsStep = (node) => {
22
22
  // Since we're only walking through deps that are not already flagged
23
23
  // as non-dev/non-optional, it's typically a very shallow traversal
24
24
  node.extraneous = false
25
+ resetParents(node, 'extraneous')
26
+ resetParents(node, 'dev')
27
+ resetParents(node, 'peer')
28
+ resetParents(node, 'devOptional')
29
+ resetParents(node, 'optional')
25
30
 
26
31
  // for links, map their hierarchy appropriately
27
32
  if (node.target) {
@@ -29,8 +34,7 @@ const calcDepFlagsStep = (node) => {
29
34
  node.target.optional = node.optional
30
35
  node.target.devOptional = node.devOptional
31
36
  node.target.peer = node.peer
32
- node.target.extraneous = false
33
- node = node.target
37
+ return calcDepFlagsStep(node.target)
34
38
  }
35
39
 
36
40
  node.edgesOut.forEach(({peer, optional, dev, to}) => {
@@ -71,6 +75,14 @@ const calcDepFlagsStep = (node) => {
71
75
  return node
72
76
  }
73
77
 
78
+ const resetParents = (node, flag) => {
79
+ if (node[flag])
80
+ return
81
+
82
+ for (let p = node; p && (p === node || p[flag]); p = p.resolveParent)
83
+ p[flag] = false
84
+ }
85
+
74
86
  // typically a short walk, since it only traverses deps that
75
87
  // have the flag set.
76
88
  const unsetFlag = (node, flag) => {
package/lib/inventory.js CHANGED
@@ -7,6 +7,20 @@ const _index = Symbol('_index')
7
7
  const defaultKeys = ['name', 'license', 'funding', 'realpath', 'packageName']
8
8
  const { hasOwnProperty } = Object.prototype
9
9
  const debug = require('./debug.js')
10
+
11
+ // handling for the outdated "licenses" array, just pick the first one
12
+ // also support the alternative spelling "licence"
13
+ const getLicense = pkg => {
14
+ if (pkg) {
15
+ const lic = pkg.license || pkg.licence
16
+ if (lic)
17
+ return lic
18
+ const lics = pkg.licenses || pkg.licences
19
+ if (Array.isArray(lics))
20
+ return lics[0]
21
+ }
22
+ }
23
+
10
24
  class Inventory extends Map {
11
25
  constructor (opt = {}) {
12
26
  const { primary, keys } = opt
@@ -56,7 +70,9 @@ class Inventory extends Map {
56
70
  for (const [key, map] of this[_index].entries()) {
57
71
  // if the node has the value, but it's false, then use that
58
72
  const val_ = hasOwnProperty.call(node, key) ? node[key]
59
- : node[key] || (node.package && node.package[key])
73
+ : key === 'license' ? getLicense(node.package)
74
+ : node[key] ? node[key]
75
+ : node.package && node.package[key]
60
76
  const val = typeof val_ === 'string' ? val_
61
77
  : !val_ || typeof val_ !== 'object' ? val_
62
78
  : key === 'license' ? val_.type
package/lib/node.js CHANGED
@@ -547,6 +547,8 @@ class Node {
547
547
 
548
548
  // try to find our parent/fsParent in the new root inventory
549
549
  for (const p of walkUp(dirname(this.path))) {
550
+ if (p === this.path)
551
+ continue
550
552
  const ploc = relpath(root.realpath, p)
551
553
  const parent = root.inventory.get(ploc)
552
554
  if (parent) {
@@ -783,7 +785,13 @@ class Node {
783
785
  }
784
786
 
785
787
  get fsParent () {
786
- return this[_fsParent]
788
+ const parent = this[_fsParent]
789
+ /* istanbul ignore next - should be impossible */
790
+ debug(() => {
791
+ if (parent === this)
792
+ throw new Error('node set to its own fsParent')
793
+ })
794
+ return parent
787
795
  }
788
796
 
789
797
  set fsParent (fsParent) {
@@ -1009,7 +1017,13 @@ class Node {
1009
1017
  }
1010
1018
 
1011
1019
  get parent () {
1012
- return this[_parent]
1020
+ const parent = this[_parent]
1021
+ /* istanbul ignore next - should be impossible */
1022
+ debug(() => {
1023
+ if (parent === this)
1024
+ throw new Error('node set to its own parent')
1025
+ })
1026
+ return parent
1013
1027
  }
1014
1028
 
1015
1029
  // This setter keeps everything in order when we move a node from
package/lib/shrinkwrap.js CHANGED
@@ -32,7 +32,7 @@ const mismatch = (a, b) => a && b && a !== b
32
32
  // After calling this.commit(), any nodes not present in the tree will have
33
33
  // been removed from the shrinkwrap data as well.
34
34
 
35
- const procLog = require('./proc-log.js')
35
+ const procLog = require('proc-log')
36
36
  const YarnLock = require('./yarn-lock.js')
37
37
  const {promisify} = require('util')
38
38
  const rimraf = promisify(require('rimraf'))
package/lib/tracker.js CHANGED
@@ -1,6 +1,6 @@
1
1
  const _progress = Symbol('_progress')
2
2
  const _onError = Symbol('_onError')
3
- const procLog = require('./proc-log.js')
3
+ const procLog = require('proc-log')
4
4
 
5
5
  module.exports = cls => class Tracker extends cls {
6
6
  constructor (options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@npmcli/arborist",
3
- "version": "2.6.2",
3
+ "version": "2.6.3",
4
4
  "description": "Manage node_modules trees",
5
5
  "dependencies": {
6
6
  "@npmcli/installed-package-contents": "^1.0.7",
@@ -22,6 +22,7 @@
22
22
  "npm-registry-fetch": "^11.0.0",
23
23
  "pacote": "^11.2.6",
24
24
  "parse-conflict-json": "^1.1.1",
25
+ "proc-log": "^1.0.0",
25
26
  "promise-all-reject-late": "^1.0.0",
26
27
  "promise-call-limit": "^1.0.1",
27
28
  "read-package-json-fast": "^2.0.2",
package/lib/proc-log.js DELETED
@@ -1,21 +0,0 @@
1
- // default logger.
2
- // emits 'log' events on the process
3
- const LEVELS = [
4
- 'notice',
5
- 'error',
6
- 'warn',
7
- 'info',
8
- 'verbose',
9
- 'http',
10
- 'silly',
11
- 'pause',
12
- 'resume',
13
- ]
14
-
15
- const log = level => (...args) => process.emit('log', level, ...args)
16
-
17
- const logger = {}
18
- for (const level of LEVELS)
19
- logger[level] = log(level)
20
-
21
- module.exports = logger