Skip to content

Commit

Permalink
feat(arborist): refactor arborist bin to use consistent timing/logging
Browse files Browse the repository at this point in the history
This attempts to make the arborist bin script behave more like the npm
cli with regards to the handing of timing and logging.

It also adds the a `logfile` argument to write logs to a file instead of
(or in addition to) stderr. This can be helpful for benchmarking
performance of loggins or terminal display.
  • Loading branch information
lukekarrys committed Feb 24, 2022
1 parent 1b4385f commit 72b34f4
Show file tree
Hide file tree
Showing 17 changed files with 490 additions and 359 deletions.
2 changes: 2 additions & 0 deletions package-lock.json
Original file line number Diff line number Diff line change
Expand Up @@ -10410,6 +10410,7 @@
"json-stringify-nice": "^1.1.4",
"mkdirp": "^1.0.4",
"mkdirp-infer-owner": "^2.0.0",
"nopt": "^5.0.0",
"npm-install-checks": "^4.0.0",
"npm-package-arg": "^8.1.5",
"npm-pick-manifest": "^6.1.0",
Expand Down Expand Up @@ -11326,6 +11327,7 @@
"mkdirp": "^1.0.4",
"mkdirp-infer-owner": "^2.0.0",
"nock": "^13.2.0",
"nopt": "^5.0.0",
"npm-install-checks": "^4.0.0",
"npm-package-arg": "^8.1.5",
"npm-pick-manifest": "^6.1.0",
Expand Down
10 changes: 10 additions & 0 deletions workspaces/arborist/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -333,3 +333,13 @@ pruning nodes from the tree.

Note: `devOptional` is only set in the shrinkwrap/package-lock file if
_neither_ `dev` nor `optional` are set, as it would be redundant.

## BIN

Arborist ships with a cli that can be used to run arborist specific commands outside of the context of the npm CLI. This script is currently not part of the public API and is subject to breaking changes outside of major version bumps.

To see the usage run:

```
npx @npmcli/arborist --help
```
36 changes: 16 additions & 20 deletions workspaces/arborist/bin/actual.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
const Arborist = require('../')
const print = require('./lib/print-tree.js')
const options = require('./lib/options.js')
require('./lib/logging.js')
require('./lib/timers.js')

const start = process.hrtime()
new Arborist(options).loadActual(options).then(tree => {
const end = process.hrtime(start)
if (!process.argv.includes('--quiet')) {
print(tree)
}
const printTree = require('./lib/print-tree.js')

console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`)
if (options.save) {
tree.meta.save()
}
if (options.saveHidden) {
tree.meta.hiddenLockfile = true
tree.meta.filename = options.path + '/node_modules/.package-lock.json'
tree.meta.save()
}
}).catch(er => console.error(er))
module.exports = (options, time) => new Arborist(options)
.loadActual(options)
.then(time)
.then(async ({ timing, result: tree }) => {
printTree(tree)
if (options.save) {
await tree.meta.save()
}
if (options.saveHidden) {
tree.meta.hiddenLockfile = true
tree.meta.filename = options.path + '/node_modules/.package-lock.json'
await tree.meta.save()
}
return `read ${tree.inventory.size} deps in ${timing.ms}`
})
49 changes: 23 additions & 26 deletions workspaces/arborist/bin/audit.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
const Arborist = require('../')

const print = require('./lib/print-tree.js')
const options = require('./lib/options.js')
require('./lib/timers.js')
require('./lib/logging.js')
const printTree = require('./lib/print-tree.js')
const log = require('./lib/logging.js')

const Vuln = require('../lib/vuln.js')
const printReport = report => {
for (const vuln of report.values()) {
console.log(printVuln(vuln))
log.info(printVuln(vuln))
}
if (report.topVulns.size) {
console.log('\n# top-level vulnerabilities')
log.info('\n# top-level vulnerabilities')
for (const vuln of report.topVulns.values()) {
console.log(printVuln(vuln))
log.info(printVuln(vuln))
}
}
}
Expand All @@ -33,22 +31,21 @@ const printVuln = vuln => {

const printAdvisory = a => `${a.title}${a.url ? ' ' + a.url : ''}`

const start = process.hrtime()
process.emit('time', 'audit script')
const arb = new Arborist(options)
arb.audit(options).then(tree => {
process.emit('timeEnd', 'audit script')
const end = process.hrtime(start)
if (options.fix) {
print(tree)
}
if (!options.quiet) {
printReport(arb.auditReport)
}
if (options.fix) {
console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 1e9}s`)
}
if (tree.meta && options.save) {
tree.meta.save()
}
}).catch(er => console.error(er))
module.exports = (options, time) => {
const arb = new Arborist(options)
return arb
.audit(options)
.then(time)
.then(async ({ timing, result: tree }) => {
if (options.fix) {
printTree(tree)
}
printReport(arb.auditReport)
if (tree.meta && options.save) {
await tree.meta.save()
}
return options.fix
? `resolved ${tree.inventory.size} deps in ${timing.seconds}`
: `done in ${timing.seconds}`
})
}
66 changes: 35 additions & 31 deletions workspaces/arborist/bin/funding.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
const options = require('./lib/options.js')
require('./lib/logging.js')
require('./lib/timers.js')

const Arborist = require('../')
const a = new Arborist(options)
const query = options._.shift()
const start = process.hrtime()
a.loadVirtual().then(tree => {
// only load the actual tree if the virtual one doesn't have modern metadata
if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2)) {
console.error('old metadata, load actual')
throw 'load actual'
} else {
console.error('meta ok, return virtual tree')
return tree
}
}).catch(() => a.loadActual()).then(tree => {
const end = process.hrtime(start)
if (!query) {
for (const node of tree.inventory.values()) {
if (node.package.funding) {
console.log(node.name, node.location, node.package.funding)

const log = require('./lib/logging.js')

module.exports = (options, time) => {
const query = options._.shift()
const a = new Arborist(options)
return a
.loadVirtual()
.then(tree => {
// only load the actual tree if the virtual one doesn't have modern metadata
if (!tree.meta || !(tree.meta.originalLockfileVersion >= 2)) {
log.error('old metadata, load actual')
throw 'load actual'
} else {
log.error('meta ok, return virtual tree')
return tree
}
}
} else {
for (const node of tree.inventory.query('name', query)) {
if (node.package.funding) {
console.log(node.name, node.location, node.package.funding)
})
.catch(() => a.loadActual())
.then(time)
.then(({ timing, result: tree }) => {
if (!query) {
for (const node of tree.inventory.values()) {
if (node.package.funding) {
log.info(node.name, node.location, node.package.funding)
}
}
} else {
for (const node of tree.inventory.query('name', query)) {
if (node.package.funding) {
log.info(node.name, node.location, node.package.funding)
}
}
}
}
}
console.error(`read ${tree.inventory.size} deps in ${end[0] * 1000 + end[1] / 1e6}ms`)
})
return `read ${tree.inventory.size} deps in ${timing.ms}`
})
}
29 changes: 11 additions & 18 deletions workspaces/arborist/bin/ideal.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,14 @@
const Arborist = require('../')

const { inspect } = require('util')
const options = require('./lib/options.js')
const print = require('./lib/print-tree.js')
require('./lib/logging.js')
require('./lib/timers.js')
const printTree = require('./lib/print-tree.js')

const start = process.hrtime()
new Arborist(options).buildIdealTree(options).then(tree => {
const end = process.hrtime(start)
print(tree)
console.error(`resolved ${tree.inventory.size} deps in ${end[0] + end[1] / 10e9}s`)
if (tree.meta && options.save) {
tree.meta.save()
}
}).catch(er => {
const opt = { depth: Infinity, color: true }
console.error(er.code === 'ERESOLVE' ? inspect(er, opt) : er)
process.exitCode = 1
})
module.exports = (options, time) => new Arborist(options)
.buildIdealTree(options)
.then(time)
.then(async ({ timing, result: tree }) => {
printTree(tree)
if (tree.meta && options.save) {
await tree.meta.save()
}
return `resolved ${tree.inventory.size} deps in ${timing.seconds}`
})
Loading

0 comments on commit 72b34f4

Please sign in to comment.