From a4b4c6140f64ab11f56507652f17ea586a0dd6c3 Mon Sep 17 00:00:00 2001 From: claudiahdz Date: Fri, 1 May 2020 17:09:37 -0500 Subject: feat: add --all flag on npm outdated --- lib/outdated.js | 103 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 48 deletions(-) (limited to 'lib/outdated.js') diff --git a/lib/outdated.js b/lib/outdated.js index 1f2916a01..bc96ed017 100644 --- a/lib/outdated.js +++ b/lib/outdated.js @@ -19,17 +19,13 @@ cmd.usage = 'npm outdated [[<@scope>/] ...]' cmd.completion = require('./utils/completion/installed-deep.js') module.exports = cmd -function cmd (args, silent, cb) { - if (typeof cb !== 'function') { - cb = silent - silent = false - } - outdated(args, silent, cb) +function cmd (args, cb) { + outdated(args, cb) .then(() => cb()) .catch(cb) } -async function outdated (args, silent) { +async function outdated (args) { const opts = npm.flatOptions const global = path.resolve(npm.globalDir, '..') const where = opts.global @@ -42,13 +38,13 @@ async function outdated (args, silent) { }) const tree = await arb.loadActual() - const list = await outdated_(tree, args) + const list = await outdated_(tree, args, opts) // sorts list alphabetically const outdated = list.sort((a, b) => a.name.localeCompare(b.name)) - // return if silent or no outdated packages - if (silent || (outdated.length === 0 && !opts.json)) { + // return if no outdated packages + if (outdated.length === 0 && !opts.json) { return } @@ -83,46 +79,34 @@ async function outdated (args, silent) { process.exitCode = outdated.length ? 1 : 0 } -async function outdated_ (tree, deps) { +async function outdated_ (tree, deps, opts) { const list = [] async function getOutdatedInfo (name, node) { const spec = npa(name) + const { + path, + location, + package: { + version: current + } + } = node || { package: {} } - // dep is on disk - let path, current, homepage - if (node) { - path = node.path - current = node.package.version - homepage = node.package.homepage - } - - const { package: pkg } = tree - const prod = pkg.dependencies - const dev = pkg.devDependencies - const peer = pkg.peerDependencies - const optional = pkg.optionalDependencies - - const type = ( - (prod && prod[name] && 'dependencies') || - (dev && dev[name] && 'devDependencies') || - (peer && peer[name] && 'peerDependencies') || - (optional && optional[name] && 'optionalDependencies') - ) - - // dep is not top-level - if (!type) return + const edge = tree.edgesOut.get(name) || {} + const type = edge.optional ? 'optionalDependencies' + : edge.peer ? 'peerDependencies' + : edge.dev ? 'devDependencies' + : 'dependencies' // deps different from prod not currently // on disk are not included in the output - if (!current && type !== 'dependencies') return - - const expected = pkg[type] && pkg[type][name] - + if (edge.error === 'MISSING' && type !== 'dependencies') return + try { - const packument = await pacote.packument(spec, { 'prefer-online': true }) - const wanted = pickManifest(packument, expected) - const latest = pickManifest(packument, 'latest') + const packument = await getPackument(spec) + const expected = edge.spec + const wanted = pickManifest(packument, expected, npm.flatOptions) + const latest = pickManifest(packument, '*', npm.flatOptions) if ( !current || @@ -134,10 +118,10 @@ async function outdated_ (tree, deps) { path, type, current, - homepage, + homepage: packument.homepage, wanted: wanted.version, latest: latest.version, - location: tree.package.name + location }) } } catch (err) { @@ -153,25 +137,48 @@ async function outdated_ (tree, deps) { } } - + + const p = [] if (deps.length !== 0) { // specific deps for (let i = 0; i < deps.length; i++) { const set = tree.inventory.query('name', deps[i]) - const node = set.values().next().value - await getOutdatedInfo(deps[i], node) + for (const node of set) { + p.push(getOutdatedInfo(deps[i], node)) + } } - } else { + } else if (opts.all) { + // all deps in tree + for (const [name, node] of tree.inventory) { + p.push(getOutdatedInfo(node.name, node)) + } + } + else { // top-level deps for (const [name, edge] of tree.edgesOut) { const { to } = edge - await getOutdatedInfo(name, to) + p.push(getOutdatedInfo(name, to)) } } + await Promise.all(p) return list } +// packument fetching memoizing +const packuments = new Map() +async function getPackument (spec) { + if (packuments.has(spec)) { + return packuments.get(spec) + } + const packument = await pacote.packument(spec, { + fullMetadata: npm.flatOptions.long, + preferOnline: true + }) + packuments.set(spec, packument) + return packument +} + // formatting functions function makePretty (dep, opts) { const { -- cgit v1.2.3