diff options
author | isaacs <i@izs.me> | 2020-09-07 03:11:49 +0300 |
---|---|---|
committer | isaacs <i@izs.me> | 2020-09-07 03:11:52 +0300 |
commit | 7418970f03229dd2bce7973b99b981779aee6916 (patch) | |
tree | 4d34e1152375aa6012dcde39c1bce01714d7ad9d /lib/utils | |
parent | 58c215543103d52c4b44b0fa8f479e8537c1e472 (diff) |
Tighten up the output of dep node explanations
Reduce visual noise, make the more important information more obvious.
Diffstat (limited to 'lib/utils')
-rw-r--r-- | lib/utils/explain-dep.js | 101 | ||||
-rw-r--r-- | lib/utils/explain-eresolve.js | 66 |
2 files changed, 107 insertions, 60 deletions
diff --git a/lib/utils/explain-dep.js b/lib/utils/explain-dep.js new file mode 100644 index 000000000..773cc5942 --- /dev/null +++ b/lib/utils/explain-dep.js @@ -0,0 +1,101 @@ +const chalk = require('chalk') +const nocolor = { + bold: s => s, + dim: s => s, + red: s => s, + yellow: s => s, + cyan: s => s, + magenta: s => s +} + +const explainNode = (node, depth, color) => + printNode(node, color) + + explainDependents(node, depth, color) + +const colorType = (type, color) => { + const { red, yellow, cyan, magenta } = color ? chalk : nocolor + const style = type === 'extraneous' ? red + : type === 'dev' ? yellow + : type === 'optional' ? cyan + : type === 'peer' ? magenta + : /* istanbul ignore next */ s => s + return style(type) +} + +const printNode = (node, color) => { + const { + name, + version, + location, + extraneous, + dev, + optional, + peer + } = node + const { bold, dim } = color ? chalk : nocolor + const extra = [] + if (extraneous) { + extra.push(' ' + bold(colorType('extraneous', color))) + } + if (dev) { + extra.push(' ' + bold(colorType('dev', color))) + } + if (optional) { + extra.push(' ' + bold(colorType('optional', color))) + } + if (peer) { + extra.push(' ' + bold(colorType('peer', color))) + } + + return `${bold(name)}@${bold(version)}${extra.join('')}` + + (location ? dim(`\n${location}`) : '') +} + +const explainDependents = ({ name, dependents }, depth, color) => { + if (!dependents || !dependents.length || depth <= 0) { + return '' + } + + const max = Math.ceil(depth / 2) + const messages = dependents.slice(0, max) + .map(dep => explainDependency(name, dep, depth, color)) + + // show just the names of the first 5 deps that overflowed the list + if (dependents.length > max) { + let len = 0 + const maxLen = 30 + const showNames = [] + for (let i = max; i < dependents.length; i++) { + const { from: { name } } = dependents[i] + len += name.length + if (len >= maxLen && i < dependents.length - 1) { + showNames.push('...') + break + } + showNames.push(name) + } + const show = `(${showNames.join(', ')})` + messages.push(`${dependents.length - max} more ${show}`) + } + + const str = '\n' + messages.join('\n') + return str.split('\n').join('\n ') +} + +const explainDependency = (name, { type, from, spec }, depth, color) => { + const { bold } = color ? chalk : nocolor + return (type === 'prod' ? '' : `${colorType(type, color)} `) + + `${bold(name)}@"${bold(spec)}" from ` + + explainFrom(from, depth, color) +} + +const explainFrom = (from, depth, color) => { + if (!from.name && !from.version) { + return 'the root project' + } + + return printNode(from, color) + + explainDependents(from, depth - 1, color) +} + +module.exports = { explainNode, printNode } diff --git a/lib/utils/explain-eresolve.js b/lib/utils/explain-eresolve.js index 65a62a115..51a856f6c 100644 --- a/lib/utils/explain-eresolve.js +++ b/lib/utils/explain-eresolve.js @@ -8,12 +8,7 @@ const npm = require('../npm.js') const { writeFileSync } = require('fs') const { resolve } = require('path') - -const chalk = require('chalk') -const nocolor = { - bold: s => s, - dim: s => s -} +const { explainNode, printNode } = require('./explain-dep.js') // expl is an explanation object that comes from Arborist. It looks like: // { @@ -50,69 +45,20 @@ const explainEresolve = (expl, color, depth) => { out.push('While resolving: ' + printNode(dep.whileInstalling, color)) } - out.push(explainNode('Found:', current, depth, color)) + out.push('Found: ' + explainNode(current, depth, color)) - out.push(explainNode('\nCould not add conflicting dependency:', dep, depth, color)) + out.push('\nCould not add conflicting dependency: ' + + explainNode(dep, depth, color)) if (peerConflict) { const heading = '\nConflicting peer dependency:' - const pc = explainNode(heading, peerConflict, depth, color) - out.push(pc) + const pc = explainNode(peerConflict, depth, color) + out.push(heading + ' ' + pc) } return out.join('\n') } -const explainNode = (heading, node, depth, color) => - `${heading} ${printNode(node, color)}` + - explainDependents(node, depth, color) - -const printNode = ({ name, version, location }, color) => { - const { bold, dim } = color ? chalk : nocolor - return `${bold(name)}@${bold(version)}` + - (location ? dim(` at ${location}`) : '') -} - -const explainDependents = ({ name, dependents }, depth, color) => { - if (!dependents || !dependents.length || depth <= 0) { - return '' - } - - const max = Math.ceil(depth / 2) - const messages = dependents.slice(0, max) - .map(dep => explainDependency(name, dep, depth, color)) - - // show just the names of the first 5 deps that overflowed the list - if (dependents.length > max) { - const names = dependents.slice(max).map(d => d.from.name) - const showNames = names.slice(0, 5) - if (showNames.length < names.length) { - showNames.push('...') - } - const show = `(${showNames.join(', ')})` - messages.push(`${names.length} more ${show}`) - } - - const str = '\nfor: ' + messages.join('\nand: ') - return str.split('\n').join('\n ') -} - -const explainDependency = (name, { type, from, spec }, depth, color) => { - const { bold } = color ? chalk : nocolor - return `${type} dependency ` + - `${bold(name)}@"${bold(spec)}"\nfrom: ` + - explainFrom(from, depth, color) -} - -const explainFrom = (from, depth, color) => { - if (!from.name && !from.version) { - return 'the root project' - } - - return printNode(from, color) + - explainDependents(from, depth - 1, color) -} - // generate a full verbose report and tell the user how to fix it const report = (expl, depth = 4) => { const fullReport = resolve(npm.cache, 'eresolve-report.txt') |