Skip to content
This repository has been archived by the owner on Aug 11, 2022. It is now read-only.

Commit

Permalink
prune: Rewrite to use npm@3 plumbing
Browse files Browse the repository at this point in the history
PR-URL: #15090
Credit: @iarna
Reviewed-By: @zkat
  • Loading branch information
iarna committed Dec 13, 2016
1 parent afb1dfd commit 981ce63
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 38 deletions.
86 changes: 49 additions & 37 deletions lib/prune.js
@@ -1,54 +1,66 @@
// prune extraneous packages.

module.exports = prune
module.exports.Pruner = Pruner

prune.usage = 'npm prune [[<@scope>/]<pkg>...] [--production]'

var readInstalled = require('read-installed')
var npm = require('./npm.js')
var path = require('path')
var readJson = require('read-package-json')
var log = require('npmlog')
var util = require('util')
var moduleName = require('./utils/module-name.js')
var Installer = require('./install.js').Installer
var isExtraneous = require('./install/is-extraneous.js')
var isDev = require('./install/is-dev-dep.js')
var removeDeps = require('./install/deps.js').removeDeps
var loadExtraneous = require('./install/deps.js').loadExtraneous
var chain = require('slide').chain

prune.completion = require('./utils/completion/installed-deep.js')

function prune (args, cb) {
// check if is a valid package.json file
var jsonFile = path.resolve(npm.dir, '..', 'package.json')
readJson(jsonFile, log.warn, function (er) {
if (er) return cb(er)
next()
})

function next () {
var opt = {
depth: npm.config.get('depth'),
dev: !npm.config.get('production') || npm.config.get('dev')
}
readInstalled(npm.prefix, opt, function (er, data) {
if (er) return cb(er)
prune_(args, data, cb)
})
}
var dryrun = !!npm.config.get('dry-run')
new Pruner('.', dryrun, args).run(cb)
}

function prune_ (args, data, cb) {
npm.commands.unbuild(prunables(args, data, []), cb)
function Pruner (where, dryrun, args) {
Installer.call(this, where, dryrun, args)
}
util.inherits(Pruner, Installer)

Pruner.prototype.loadAllDepsIntoIdealTree = function (cb) {
log.silly('uninstall', 'loadAllDepsIntoIdealtree')

var cg = this.progress.loadAllDepsIntoIdealTree
var steps = []

function prunables (args, data, seen) {
var deps = data.dependencies || {}
return Object.keys(deps).map(function (d) {
if (typeof deps[d] !== 'object' || seen.indexOf(deps[d]) !== -1) return null
seen.push(deps[d])
if (deps[d].extraneous && (args.length === 0 || args.indexOf(d) !== -1)) {
var extra = deps[d]
delete deps[d]
return extra.path
}
return prunables(args, deps[d], seen)
}).filter(function (d) { return d !== null })
.reduce(function FLAT (l, r) {
return l.concat(Array.isArray(r) ? r.reduce(FLAT, []) : r)
}, [])
var self = this
var excludeDev = npm.config.get('production') || /^prod(uction)?$/.test(npm.config.get('only'))
function shouldPrune (child) {
if (isExtraneous(child)) return true
if (!excludeDev) return false
var childName = moduleName(child)
var isChildDev = function (parent) { return isDev(parent, childName) }
if (child.requiredBy.every(isChildDev)) return true
}
function getModuleName (child) {
// wrapping because moduleName doesn't like extra args and we're called
// from map.
return moduleName(child)
}
function matchesArg (name) {
return self.args.length === 0 || self.args.indexOf(name) !== -1
}
function nameObj (name) {
return {name: name}
}
var toPrune = this.currentTree.children.filter(shouldPrune).map(getModuleName).filter(matchesArg).map(nameObj)

steps.push(
[removeDeps, toPrune, this.idealTree, null, cg.newGroup('removeDeps')],
[loadExtraneous, this.idealTree, cg.newGroup('loadExtraneous')])
chain(steps, cb)
}

Pruner.prototype.runPreinstallTopLevelLifecycles = function (cb) { cb() }
Pruner.prototype.runPostinstallTopLevelLifecycles = function (cb) { cb() }
2 changes: 1 addition & 1 deletion test/tap/prune.js
Expand Up @@ -107,7 +107,7 @@ test('npm prune', function (t) {
], EXEC_OPTS, function (err, code, stderr) {
t.ifErr(err, 'prune finished successfully')
t.notOk(code, 'exit ok')
t.equal(stderr, 'unbuild mkdirp@0.3.5\n')
t.equal(stderr, '- mkdirp@0.3.5 node_modules/mkdirp\n')
t.end()
})
})
Expand Down

0 comments on commit 981ce63

Please sign in to comment.