aboutsummaryrefslogtreecommitdiff
path: root/deps/npm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib')
-rw-r--r--deps/npm/lib/access.js5
-rw-r--r--deps/npm/lib/adduser.js19
-rw-r--r--deps/npm/lib/bin.js3
-rw-r--r--deps/npm/lib/build.js5
-rw-r--r--deps/npm/lib/cache.js3
-rw-r--r--deps/npm/lib/completion.js3
-rw-r--r--deps/npm/lib/config.js7
-rw-r--r--deps/npm/lib/dist-tag.js7
-rw-r--r--deps/npm/lib/explore.js3
-rw-r--r--deps/npm/lib/help-search.js5
-rw-r--r--deps/npm/lib/help.js5
-rw-r--r--deps/npm/lib/init.js4
-rw-r--r--deps/npm/lib/install.js37
-rw-r--r--deps/npm/lib/install/actions.js2
-rw-r--r--deps/npm/lib/install/deps.js134
-rw-r--r--deps/npm/lib/install/diff-trees.js36
-rw-r--r--deps/npm/lib/install/inflate-shrinkwrap.js1
-rw-r--r--deps/npm/lib/install/is-dev.js25
-rw-r--r--deps/npm/lib/install/is-extraneous.js47
-rw-r--r--deps/npm/lib/install/mutate-into-logical-tree.js71
-rw-r--r--deps/npm/lib/install/node.js27
-rw-r--r--deps/npm/lib/install/prune-tree.js36
-rw-r--r--deps/npm/lib/install/save.js4
-rw-r--r--deps/npm/lib/install/update-package-json.js50
-rw-r--r--deps/npm/lib/link.js9
-rw-r--r--deps/npm/lib/ls.js3
-rw-r--r--deps/npm/lib/npm.js19
-rw-r--r--deps/npm/lib/outdated.js13
-rw-r--r--deps/npm/lib/owner.js7
-rw-r--r--deps/npm/lib/pack.js3
-rw-r--r--deps/npm/lib/ping.js3
-rw-r--r--deps/npm/lib/prefix.js3
-rw-r--r--deps/npm/lib/publish.js4
-rw-r--r--deps/npm/lib/rebuild.js5
-rw-r--r--deps/npm/lib/root.js3
-rw-r--r--deps/npm/lib/run-script.js15
-rw-r--r--deps/npm/lib/search.js3
-rw-r--r--deps/npm/lib/shrinkwrap.js29
-rw-r--r--deps/npm/lib/star.js3
-rw-r--r--deps/npm/lib/stars.js3
-rw-r--r--deps/npm/lib/substack.js3
-rw-r--r--deps/npm/lib/team.js3
-rw-r--r--deps/npm/lib/unbuild.js5
-rw-r--r--deps/npm/lib/unpublish.js3
-rw-r--r--deps/npm/lib/utils/git.js3
-rw-r--r--deps/npm/lib/utils/lifecycle.js8
-rw-r--r--deps/npm/lib/utils/no-progress-while-running.js23
-rw-r--r--deps/npm/lib/utils/output.js8
-rw-r--r--deps/npm/lib/utils/pulse-till-done.js3
-rw-r--r--deps/npm/lib/utils/spawn.js16
-rw-r--r--deps/npm/lib/utils/tar.js114
-rw-r--r--deps/npm/lib/utils/usage.js2
-rw-r--r--deps/npm/lib/version.js5
-rw-r--r--deps/npm/lib/view.js4
-rw-r--r--deps/npm/lib/visnup.js3
-rw-r--r--deps/npm/lib/whoami.js5
56 files changed, 567 insertions, 305 deletions
diff --git a/deps/npm/lib/access.js b/deps/npm/lib/access.js
index 69527c2aa4..ad7a1f54bd 100644
--- a/deps/npm/lib/access.js
+++ b/deps/npm/lib/access.js
@@ -5,6 +5,7 @@ var resolve = require('path').resolve
var readPackageJson = require('read-package-json')
var mapToRegistry = require('./utils/map-to-registry.js')
var npm = require('./npm.js')
+var output = require('./utils/output.js')
var whoami = require('./whoami')
@@ -62,7 +63,9 @@ function access (args, cb) {
params.auth = auth
try {
return npm.registry.access(cmd, uri, params, function (err, data) {
- !err && data && console.log(JSON.stringify(data, undefined, 2))
+ if (!err && data) {
+ output(JSON.stringify(data, undefined, 2))
+ }
cb(err, data)
})
} catch (e) {
diff --git a/deps/npm/lib/adduser.js b/deps/npm/lib/adduser.js
index 3a7425d471..e04af0556b 100644
--- a/deps/npm/lib/adduser.js
+++ b/deps/npm/lib/adduser.js
@@ -4,7 +4,9 @@ var log = require('npmlog')
var npm = require('./npm.js')
var read = require('read')
var userValidate = require('npm-user-validate')
+var output = require('./utils/output')
var usage = require('./utils/usage')
+var chain = require('slide').chain
var crypto
try {
@@ -30,15 +32,14 @@ function adduser (args, cb) {
e: creds.email || ''
}
var u = {}
- var fns = [readUsername, readPassword, readEmail, save]
- loop()
- function loop (er) {
- if (er) return cb(er)
- var fn = fns.shift()
- if (fn) return fn(c, u, loop)
- cb()
- }
+ log.disableProgress()
+ chain([
+ [readUsername, c, u],
+ [readPassword, c, u],
+ [readEmail, c, u],
+ [save, c, u]
+ ], cb)
}
function readUsername (c, u, cb) {
@@ -173,7 +174,7 @@ function save (c, u, cb) {
log.info('adduser', 'Authorized user %s', u.u)
var scopeMessage = scope ? ' to scope ' + scope : ''
- console.log('Logged in as %s%s on %s.', u.u, scopeMessage, uri)
+ output('Logged in as %s%s on %s.', u.u, scopeMessage, uri)
npm.config.save('user', cb)
})
}
diff --git a/deps/npm/lib/bin.js b/deps/npm/lib/bin.js
index 2e02617d35..7258893b9c 100644
--- a/deps/npm/lib/bin.js
+++ b/deps/npm/lib/bin.js
@@ -2,6 +2,7 @@ module.exports = bin
var npm = require('./npm.js')
var osenv = require('osenv')
+var output = require('./utils/output.js')
bin.usage = 'npm bin [--global]'
@@ -13,7 +14,7 @@ function bin (args, silent, cb) {
var b = npm.bin
var PATH = osenv.path()
- if (!silent) console.log(b)
+ if (!silent) output(b)
process.nextTick(cb.bind(this, null, b))
if (npm.config.get('global') && PATH.indexOf(b) === -1) {
diff --git a/deps/npm/lib/build.js b/deps/npm/lib/build.js
index e9da59a23d..fbe78c746d 100644
--- a/deps/npm/lib/build.js
+++ b/deps/npm/lib/build.js
@@ -22,6 +22,7 @@ var asyncMap = require('slide').asyncMap
var ini = require('ini')
var writeFile = require('write-file-atomic')
var packageId = require('./utils/package-id.js')
+var output = require('./utils/output.js')
module.exports = build
build.usage = 'npm build [<folder>]'
@@ -211,9 +212,7 @@ function linkBins (pkg, folder, parent, gtop, cb) {
var out = npm.config.get('parseable')
? dest + '::' + src + ':BINFILE'
: dest + ' -> ' + src
- log.clearProgress()
- console.log(out)
- log.showProgress()
+ output(out)
cb()
})
}
diff --git a/deps/npm/lib/cache.js b/deps/npm/lib/cache.js
index 757ba6e79d..5ad07dfdcd 100644
--- a/deps/npm/lib/cache.js
+++ b/deps/npm/lib/cache.js
@@ -82,6 +82,7 @@ var npa = require('npm-package-arg')
var getStat = require('./cache/get-stat.js')
var cachedPackageRoot = require('./cache/cached-package-root.js')
var mapToRegistry = require('./utils/map-to-registry.js')
+var output = require('./utils/output.js')
cache.usage = 'npm cache add <tarball file>' +
'\nnpm cache add <folder>' +
@@ -182,7 +183,7 @@ function ls (args, cb) {
prefix = '~' + prefix.substr(process.env.HOME.length)
}
ls_(normalize(args), npm.config.get('depth'), function (er, files) {
- console.log(files.map(function (f) {
+ output(files.map(function (f) {
return path.join(prefix, f)
}).join('\n').trim())
cb(er, files)
diff --git a/deps/npm/lib/completion.js b/deps/npm/lib/completion.js
index 6f6cfd810b..3157255bfb 100644
--- a/deps/npm/lib/completion.js
+++ b/deps/npm/lib/completion.js
@@ -14,6 +14,7 @@ var shorthandNames = Object.keys(shorthands)
var allConfs = configNames.concat(shorthandNames)
var once = require('once')
var isWindowsShell = require('./utils/is-windows-shell.js')
+var output = require('./utils/output.js')
completion.completion = function (opts, cb) {
if (opts.w > 3) return cb()
@@ -203,7 +204,7 @@ function wrapCb (cb, opts) {
console.error([er && er.stack, compls, opts.partialWord])
if (er || compls.length === 0) return cb(er)
- console.log(compls.join('\n'))
+ output(compls.join('\n'))
cb()
}
}
diff --git a/deps/npm/lib/config.js b/deps/npm/lib/config.js
index 80958ec5fc..7112e88c5f 100644
--- a/deps/npm/lib/config.js
+++ b/deps/npm/lib/config.js
@@ -11,6 +11,7 @@ var editor = require('editor')
var os = require('os')
var umask = require('./utils/umask')
var usage = require('./utils/usage')
+var output = require('./utils/output')
config.usage = usage(
'config',
@@ -148,7 +149,7 @@ function get (key, cb) {
}
var val = npm.config.get(key)
if (key.match(/umask/)) val = umask.toString(val)
- console.log(val)
+ output(val)
cb()
}
@@ -278,7 +279,7 @@ function list (cb) {
'; HOME = ' + process.env.HOME + '\n' +
'; "npm config ls -l" to show all defaults.\n'
- console.log(msg)
+ output(msg)
return cb()
}
@@ -294,7 +295,7 @@ function list (cb) {
})
msg += '\n'
- console.log(msg)
+ output(msg)
return cb()
}
diff --git a/deps/npm/lib/dist-tag.js b/deps/npm/lib/dist-tag.js
index 0e9d914d39..7c20ea9901 100644
--- a/deps/npm/lib/dist-tag.js
+++ b/deps/npm/lib/dist-tag.js
@@ -8,6 +8,7 @@ var npm = require('./npm.js')
var mapToRegistry = require('./utils/map-to-registry.js')
var readLocalPkg = require('./utils/read-local-package.js')
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
distTag.usage = usage(
'dist-tag',
@@ -77,7 +78,7 @@ function add (spec, tag, cb) {
npm.registry.distTags.add(base, params, function (er) {
if (er) return cb(er)
- console.log('+' + t + ': ' + pkg + '@' + version)
+ output('+' + t + ': ' + pkg + '@' + version)
cb()
})
})
@@ -108,7 +109,7 @@ function remove (tag, pkg, cb) {
npm.registry.distTags.rm(base, params, function (er) {
if (er) return cb(er)
- console.log('-' + tag + ': ' + pkg + '@' + version)
+ output('-' + tag + ': ' + pkg + '@' + version)
cb()
})
})
@@ -132,7 +133,7 @@ function list (pkg, cb) {
var msg = Object.keys(tags).map(function (k) {
return k + ': ' + tags[k]
}).sort().join('\n')
- console.log(msg)
+ output(msg)
cb(er, tags)
})
}
diff --git a/deps/npm/lib/explore.js b/deps/npm/lib/explore.js
index 05b5220d5f..5640d5f157 100644
--- a/deps/npm/lib/explore.js
+++ b/deps/npm/lib/explore.js
@@ -12,6 +12,7 @@ var fs = require('graceful-fs')
var isWindowsShell = require('./utils/is-windows-shell.js')
var escapeExecPath = require('./utils/escape-exec-path.js')
var escapeArg = require('./utils/escape-arg.js')
+var output = require('./utils/output.js')
function explore (args, cb) {
if (args.length < 1 || !args[0]) return cb(explore.usage)
@@ -42,7 +43,7 @@ function explore (args, cb) {
}
if (!shellArgs.length) {
- console.log(
+ output(
'\nExploring ' + cwd + '\n' +
"Type 'exit' or ^D when finished\n"
)
diff --git a/deps/npm/lib/help-search.js b/deps/npm/lib/help-search.js
index 8a138feebe..ffbe554b7b 100644
--- a/deps/npm/lib/help-search.js
+++ b/deps/npm/lib/help-search.js
@@ -7,6 +7,7 @@ var asyncMap = require('slide').asyncMap
var npm = require('./npm.js')
var glob = require('glob')
var color = require('ansicolors')
+var output = require('./utils/output.js')
helpSearch.usage = 'npm help-search <text>'
@@ -135,7 +136,7 @@ function searchFiles (args, files, cb) {
}
if (results.length === 0) {
- console.log('No results for ' + args.map(JSON.stringify).join(' '))
+ output('No results for ' + args.map(JSON.stringify).join(' '))
return cb()
}
@@ -206,6 +207,6 @@ function formatResults (args, results, cb) {
'(run with -l or --long to see more context)'
}
- console.log(out.trim())
+ output(out.trim())
cb(null, results)
}
diff --git a/deps/npm/lib/help.js b/deps/npm/lib/help.js
index cecc6e02b0..cfac917999 100644
--- a/deps/npm/lib/help.js
+++ b/deps/npm/lib/help.js
@@ -15,6 +15,7 @@ var glob = require('glob')
var cmdList = require('./config/cmd-list').cmdList
var shorthands = require('./config/cmd-list').shorthands
var commands = cmdList.concat(Object.keys(shorthands))
+var output = require('./utils/output.js')
function help (args, cb) {
var argv = npm.config.get('argv').cooked
@@ -43,7 +44,7 @@ function help (args, cb) {
npm.commands[section].usage) {
npm.config.set('loglevel', 'silent')
log.level = 'silent'
- console.log(npm.commands[section].usage)
+ output(npm.commands[section].usage)
return cb()
}
@@ -161,7 +162,7 @@ function htmlMan (man) {
function npmUsage (valid, cb) {
npm.config.set('loglevel', 'silent')
log.level = 'silent'
- console.log([
+ output([
'\nUsage: npm <command>',
'',
'where <command> is one of:',
diff --git a/deps/npm/lib/init.js b/deps/npm/lib/init.js
index e3eb3d40dd..a5d102c1f3 100644
--- a/deps/npm/lib/init.js
+++ b/deps/npm/lib/init.js
@@ -5,15 +5,17 @@ module.exports = init
var log = require('npmlog')
var npm = require('./npm.js')
var initJson = require('init-package-json')
+var output = require('./utils/output.js')
init.usage = 'npm init [--force|-f|--yes|-y]'
function init (args, cb) {
var dir = process.cwd()
log.pause()
+ log.disableProgress()
var initFile = npm.config.get('init-module')
if (!initJson.yes(npm.config)) {
- console.log([
+ output([
'This utility will walk you through creating a package.json file.',
'It only covers the most common items, and tries to guess sensible defaults.',
'',
diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js
index 53153e1463..1fb5a4f4e6 100644
--- a/deps/npm/lib/install.js
+++ b/deps/npm/lib/install.js
@@ -113,6 +113,7 @@ var lock = locker.lock
var unlock = locker.unlock
var ls = require('./ls.js')
var parseJSON = require('./utils/parse-json.js')
+var output = require('./utils/output.js')
// install specific libraries
var copyTree = require('./install/copy-tree.js')
@@ -123,7 +124,6 @@ var loadDevDeps = require('./install/deps.js').loadDevDeps
var getAllMetadata = require('./install/deps.js').getAllMetadata
var loadRequestedDeps = require('./install/deps.js').loadRequestedDeps
var loadExtraneous = require('./install/deps.js').loadExtraneous
-var pruneTree = require('./install/prune-tree.js')
var diffTrees = require('./install/diff-trees.js')
var checkPermissions = require('./install/check-permissions.js')
var decomposeActions = require('./install/decompose-actions.js')
@@ -136,9 +136,11 @@ var doSerialActions = require('./install/actions.js').doSerial
var doReverseSerialActions = require('./install/actions.js').doReverseSerial
var doParallelActions = require('./install/actions.js').doParallel
var doOneAction = require('./install/actions.js').doOne
+var removeObsoleteDep = require('./install/deps.js').removeObsoleteDep
var packageId = require('./utils/package-id.js')
var moduleName = require('./utils/module-name.js')
var errorMessage = require('./utils/error-message.js')
+var andIgnoreErrors = require('./install/and-ignore-errors.js')
function unlockCB (lockPath, name, cb) {
validate('SSF', arguments)
@@ -363,9 +365,8 @@ Installer.prototype.loadIdealTree = function (cb) {
[this, this.loadAllDepsIntoIdealTree],
[this, this.finishTracker, 'loadAllDepsIntoIdealTree'],
- [this, function (next) { recalculateMetadata(this.idealTree, log, next) }],
- [this, this.debugTree, 'idealTree:prePrune', 'idealTree'],
- [this, function (next) { next(pruneTree(this.idealTree)) }]
+ // TODO: Remove this (should no longer be necessary, instead counter productive)
+ [this, function (next) { recalculateMetadata(this.idealTree, log, next) }]
], cb)
}
@@ -419,21 +420,18 @@ Installer.prototype.computeLinked = function (cb) {
var cmd = action[0]
var pkg = action[1]
if (cmd !== 'add' && cmd !== 'update') return next()
- var isReqByTop = pkg.package._requiredBy.filter(function (name) { return name === '/' }).length
- var isReqByUser = pkg.package._requiredBy.filter(function (name) { return name === '#USER' }).length
- var isExtraneous = pkg.package._requiredBy.length === 0
+ var isReqByTop = pkg.requiredBy.filter(function (mod) { return mod.isTop }).length
+ var isReqByUser = pkg.userRequired
+ var isExtraneous = pkg.requiredBy.length === 0
if (!isReqByTop && !isReqByUser && !isExtraneous) return next()
isLinkable(pkg, function (install, link) {
if (install) linkTodoList.push(['global-install', pkg])
if (link) linkTodoList.push(['global-link', pkg])
- if (install || link) {
- pkg.parent.children = pkg.parent.children.filter(function (child) { return child !== pkg })
- }
+ if (install || link) removeObsoleteDep(pkg)
next()
})
}, function () {
if (linkTodoList.length === 0) return cb()
- pruneTree(self.idealTree)
self.differences.length = 0
Array.prototype.push.apply(self.differences, linkTodoList)
diffTrees(self.currentTree, self.idealTree, self.differences, log.newGroup('d2'), cb)
@@ -633,8 +631,8 @@ Installer.prototype.normalizeTree = function (log, cb) {
log.silly('install', 'normalizeTree')
recalculateMetadata(this.currentTree, log, iferr(cb, function (tree) {
tree.children.forEach(function (child) {
- if (child.package._requiredBy.length === 0) {
- child.package._requiredBy.push('#EXISTING')
+ if (child.requiredBy.length === 0) {
+ child.existing = true
}
})
cb(null, tree)
@@ -655,17 +653,16 @@ Installer.prototype.printInstalled = function (cb) {
validate('F', arguments)
log.silly('install', 'printInstalled')
var self = this
- log.clearProgress()
this.differences.forEach(function (action) {
var mutation = action[0]
var child = action[1]
var name = packageId(child)
var where = path.relative(self.where, child.path)
if (mutation === 'remove') {
- console.log('- ' + name + ' ' + where)
+ output('- ' + name + ' ' + where)
} else if (mutation === 'move') {
var oldWhere = path.relative(self.where, child.fromPath)
- console.log(name + ' ' + oldWhere + ' -> ' + where)
+ output(name + ' ' + oldWhere + ' -> ' + where)
}
})
var addedOrMoved = this.differences.filter(function (action) {
@@ -676,10 +673,9 @@ Installer.prototype.printInstalled = function (cb) {
var child = action[1]
return child.path
})
- log.showProgress()
if (!addedOrMoved.length) return cb()
+ // TODO: remove the recalculateMetadata, should not be needed
recalculateMetadata(this.idealTree, log, iferr(cb, function (tree) {
- log.clearProgress()
// These options control both how installs happen AND how `ls` shows output.
// Something like `npm install --production` only installs production deps.
// By contrast `npm install --production foo` installs `foo` and the
@@ -691,10 +687,7 @@ Installer.prototype.printInstalled = function (cb) {
npm.config.set('dev', false)
npm.config.set('only', '')
npm.config.set('also', '')
- ls.fromTree(self.where, tree, addedOrMoved, false, function () {
- log.showProgress()
- cb()
- })
+ ls.fromTree(self.where, tree, addedOrMoved, false, andIgnoreErrors(cb))
}))
}
diff --git a/deps/npm/lib/install/actions.js b/deps/npm/lib/install/actions.js
index 5d162f86d0..1c7462030c 100644
--- a/deps/npm/lib/install/actions.js
+++ b/deps/npm/lib/install/actions.js
@@ -63,7 +63,7 @@ function andHandleOptionalDepErrors (pkg, next) {
return function (er) {
if (!er) return next.apply(null, arguments)
markAsFailed(pkg)
- var anyFatal = pkg.userRequired || !pkg.parent
+ var anyFatal = pkg.userRequired || pkg.isTop
for (var ii = 0; ii < pkg.requiredBy.length; ++ii) {
var parent = pkg.requiredBy[ii]
var isFatal = failedDependency(parent, pkg)
diff --git a/deps/npm/lib/install/deps.js b/deps/npm/lib/install/deps.js
index edc317f846..886e841913 100644
--- a/deps/npm/lib/install/deps.js
+++ b/deps/npm/lib/install/deps.js
@@ -10,6 +10,7 @@ var iferr = require('iferr')
var npa = require('npm-package-arg')
var validate = require('aproba')
var realizePackageSpecifier = require('realize-package-specifier')
+var asap = require('asap')
var dezalgo = require('dezalgo')
var fetchPackageMetadata = require('../fetch-package-metadata.js')
var andAddParentToErrors = require('./and-add-parent-to-errors.js')
@@ -78,15 +79,17 @@ function doesChildVersionMatch (child, requested, requestor) {
return semver.satisfies(child.package.version, requested.spec)
}
+// TODO: Rename to maybe computeMetadata or computeRelationships
exports.recalculateMetadata = function (tree, log, next) {
recalculateMetadata(tree, log, {}, next)
}
+exports._childDependencySpecifier = childDependencySpecifier
function childDependencySpecifier (tree, name, spec, cb) {
if (!tree.resolved) tree.resolved = {}
if (!tree.resolved[name]) tree.resolved[name] = {}
if (tree.resolved[name][spec]) {
- return process.nextTick(function () {
+ return asap(function () {
cb(null, tree.resolved[name][spec])
})
}
@@ -101,19 +104,24 @@ function recalculateMetadata (tree, log, seen, next) {
validate('OOOF', arguments)
if (seen[tree.path]) return next()
seen[tree.path] = true
- if (tree.parent == null) resetMetadata(tree)
- function markDeps (spec, done) {
- validate('SF', arguments)
- var matched = spec.match(/^(@?[^@]+)@(.*)$/)
- childDependencySpecifier(tree, matched[1], matched[2], function (er, req) {
+ if (tree.parent == null) {
+ resetMetadata(tree)
+ tree.isTop = true
+ }
+
+ function markDeps (toMark, done) {
+ var name = toMark.name
+ var spec = toMark.spec
+ var kind = toMark.kind
+ childDependencySpecifier(tree, name, spec, function (er, req) {
if (er || !req.name) return done()
var child = findRequirement(tree, req.name, req)
if (child) {
resolveWithExistingModule(child, tree, log, andIgnoreErrors(done))
- } else if (tree.package.dependencies[req.name] != null) {
+ } else if (kind === 'dep') {
tree.missingDeps[req.name] = req.rawSpec
done()
- } else if (tree.package.devDependencies[req.name] != null) {
+ } else if (kind === 'dev') {
tree.missingDevDeps[req.name] = req.rawSpec
done()
} else {
@@ -121,15 +129,16 @@ function recalculateMetadata (tree, log, seen, next) {
}
})
}
- function specs (deps) {
- return Object.keys(deps).map(function (depname) { return depname + '@' + deps[depname] })
+
+ function makeMarkable (deps, kind) {
+ if (!deps) return []
+ return Object.keys(deps).map(function (depname) { return { name: depname, spec: deps[depname], kind: kind } })
}
// Ensure dependencies and dev dependencies are marked as required
- var tomark = specs(tree.package.dependencies)
- if (!tree.parent && (npm.config.get('dev') || !npm.config.get('production'))) {
- tomark = union(tomark, specs(tree.package.devDependencies))
- }
+ var tomark = makeMarkable(tree.package.dependencies, 'dep')
+ if (tree.isTop) tomark = union(tomark, makeMarkable(tree.package.devDependencies, 'dev'))
+
// Ensure any children ONLY from a shrinkwrap are also included
var childrenOnlyInShrinkwrap = tree.children.filter(function (child) {
return child.fromShrinkwrap &&
@@ -137,7 +146,13 @@ function recalculateMetadata (tree, log, seen, next) {
!tree.package.devDependencies[child.package.name]
})
var tomarkOnlyInShrinkwrap = childrenOnlyInShrinkwrap.map(function (child) {
- return child.package._spec
+ var name = child.package.name
+ var matched = child.package._spec.match(/^@?[^@]+@(.*)$/)
+ var spec = matched ? matched[1] : child.package._spec
+ var kind = tree.package.dependencies[name] ? 'dep'
+ : tree.package.devDependencies[name] ? 'dev'
+ : 'dep'
+ return { name: name, spec: spec, kind: kind }
})
tomark = union(tomark, tomarkOnlyInShrinkwrap)
@@ -148,9 +163,7 @@ function recalculateMetadata (tree, log, seen, next) {
[asyncMap, tomark, markDeps],
[asyncMap, tree.children, function (child, done) { recalculateMetadata(child, log, seen, done) }]
], function () {
- tree.userRequired = tree.package._requiredBy.some(function (req) { return req === '#USER' })
- tree.existing = tree.package._requiredBy.some(function (req) { return req === '#EXISTING' })
- tree.package._location = flatNameFromTree(tree)
+ tree.location = flatNameFromTree(tree)
next(null, tree)
})
}
@@ -158,18 +171,23 @@ function recalculateMetadata (tree, log, seen, next) {
function addRequiredDep (tree, child, cb) {
isDep(tree, child, function (childIsDep, childIsProdDep, childIsDevDep) {
if (!childIsDep) return cb(false)
- var name = childIsProdDep ? flatNameFromTree(tree) : '#DEV:' + flatNameFromTree(tree)
- replaceModuleName(child.package, '_requiredBy', name)
- replaceModule(child, 'requiredBy', tree)
- replaceModule(tree, 'requires', child)
+ replaceModuleByPath(child, 'requiredBy', tree)
+ replaceModuleByName(tree, 'requires', child)
+ if (childIsProdDep && tree.missingDeps) delete tree.missingDeps[moduleName(child)]
+ if (childIsDevDep && tree.missingDevDeps) delete tree.missingDevDeps[moduleName(child)]
cb(true)
})
}
-exports._removeObsoleteDep = removeObsoleteDep
+exports.removeObsoleteDep = removeObsoleteDep
function removeObsoleteDep (child) {
if (child.removed) return
child.removed = true
+ // remove from physical tree
+ if (child.parent) {
+ child.parent.children = child.parent.children.filter(function (pchild) { return pchild !== child })
+ }
+ // remove from logical tree
var requires = child.requires || []
requires.forEach(function (requirement) {
requirement.requiredBy = requirement.requiredBy.filter(function (reqBy) { return reqBy !== child })
@@ -243,9 +261,7 @@ exports.loadRequestedDeps = function (args, tree, saveToDependencies, log, next)
// won't be when we're done), flag it as "depending" on the user
// themselves, so we don't remove it as a dep that no longer exists
addRequiredDep(tree, child, function (childIsDep) {
- if (!childIsDep) {
- replaceModuleName(child.package, '_requiredBy', '#USER')
- }
+ if (!childIsDep) child.userRequired = true
depLoaded(null, child, tracker)
})
}))
@@ -266,13 +282,13 @@ exports.removeDeps = function (args, tree, saveToDependencies, log, next) {
validate('AOOF', [args, tree, log, next])
args.forEach(function (pkg) {
var pkgName = moduleName(pkg)
+ var toRemove = tree.children.filter(moduleNameMatches(pkgName))
+ var pkgToRemove = toRemove[0] || createChild({package: {name: pkgName}})
if (saveToDependencies) {
- var toRemove = tree.children.filter(moduleNameMatches(pkgName))
- var pkgToRemove = toRemove[0] || createChild({package: {name: pkgName}})
- replaceModule(tree, 'removed', pkgToRemove)
+ replaceModuleByPath(tree, 'removed', pkgToRemove)
pkgToRemove.save = saveToDependencies
}
- tree.children = tree.children.filter(noModuleNameMatches(pkgName))
+ removeObsoleteDep(pkgToRemove)
})
log.finish()
next()
@@ -313,7 +329,6 @@ var failedDependency = exports.failedDependency = function (tree, name_pkg) {
pkg = name_pkg
name = moduleName(pkg)
}
-
tree.children = tree.children.filter(noModuleNameMatches(name))
if (isDepOptional(tree, name)) {
@@ -322,10 +337,14 @@ var failedDependency = exports.failedDependency = function (tree, name_pkg) {
tree.failed = true
- if (!tree.parent) return true
+ if (tree.isTop) return true
if (tree.userRequired) return true
+ removeObsoleteDep(tree)
+
+ if (!tree.requiredBy) return false
+
for (var ii = 0; ii < tree.requiredBy.length; ++ii) {
var requireParent = tree.requiredBy[ii]
if (failedDependency(requireParent, tree.package)) {
@@ -367,7 +386,7 @@ function andHandleOptionalErrors (log, tree, name, done) {
exports.loadDeps = loadDeps
function loadDeps (tree, log, next) {
validate('OOF', arguments)
- if (tree.loaded || (tree.parent && tree.parent.failed)) return andFinishTracker.now(log, next)
+ if (tree.loaded || (tree.parent && tree.parent.failed) || tree.removed) return andFinishTracker.now(log, next)
if (tree.parent) tree.loaded = true
if (!tree.package.dependencies) tree.package.dependencies = {}
asyncMap(Object.keys(tree.package.dependencies), function (dep, done) {
@@ -446,38 +465,44 @@ function resolveWithExistingModule (child, tree, log, next) {
var updatePhantomChildren = exports.updatePhantomChildren = function (current, child) {
validate('OO', arguments)
while (current && current !== child.parent) {
- // FIXME: phantomChildren doesn't actually belong in the package.json
- if (!current.package._phantomChildren) current.package._phantomChildren = {}
- current.package._phantomChildren[moduleName(child)] = child.package.version
+ if (!current.phantomChildren) current.phantomChildren = {}
+ current.phantomChildren[moduleName(child)] = child
current = current.parent
}
}
function flatNameFromTree (tree) {
validate('O', arguments)
- if (!tree.parent) return '/'
+ if (tree.isTop) return '/'
var path = flatNameFromTree(tree.parent)
if (path !== '/') path += '/'
return flatName(path, tree)
}
-exports._replaceModuleName = replaceModuleName
-function replaceModuleName (obj, key, name) {
- validate('OSS', arguments)
- obj[key] = union(obj[key] || [], [name])
+exports._replaceModuleByPath = replaceModuleByPath
+function replaceModuleByPath (obj, key, child) {
+ return replaceModule(obj, key, child, function (replacing, child) {
+ return replacing.path === child.path
+ })
+}
+
+exports._replaceModuleByName = replaceModuleByName
+function replaceModuleByName (obj, key, child) {
+ var childName = moduleName(child)
+ return replaceModule(obj, key, child, function (replacing, child) {
+ return moduleName(replacing) === childName
+ })
}
-exports._replaceModule = replaceModule
-function replaceModule (obj, key, child) {
- validate('OSO', arguments)
+function replaceModule (obj, key, child, matchBy) {
+ validate('OSOF', arguments)
if (!obj[key]) obj[key] = []
// we replace children with a new array object instead of mutating it
// because mutating it results in weird failure states.
// I would very much like to know _why_ this is. =/
var children = [].concat(obj[key])
- var childName = moduleName(child)
for (var replaceAt = 0; replaceAt < children.length; ++replaceAt) {
- if (moduleName(children[replaceAt]) === childName) break
+ if (matchBy(children[replaceAt], child)) break
}
var replacing = children.splice(replaceAt, 1, child)
obj[key] = children
@@ -514,15 +539,17 @@ function resolveWithNewModule (pkg, tree, log, next) {
children: pkg._bundled || [],
isLink: tree.isLink
})
+ delete pkg._bundled
+ var hasBundled = child.children.length
- var replaced = replaceModule(parent, 'children', child)
+ var replaced = replaceModuleByName(parent, 'children', child)
if (replaced) removeObsoleteDep(replaced)
addRequiredDep(tree, child, function () {
- pkg._location = flatNameFromTree(child)
+ child.location = flatNameFromTree(child)
if (tree.parent && parent !== tree) updatePhantomChildren(tree.parent, child)
- if (pkg._bundled) {
+ if (hasBundled) {
inflateBundled(child, child.children)
}
@@ -584,7 +611,7 @@ var findRequirement = exports.findRequirement = function (tree, name, requested,
if (matches.length) return matches[0]
return null
}
- if (!tree.parent) return null
+ if (tree.isTop) return null
return findRequirement(tree.parent, name, requested, requestor)
}
@@ -618,13 +645,12 @@ var earliestInstallable = exports.earliestInstallable = function (requiredBy, tr
return null
}
- // FIXME: phantomChildren doesn't actually belong in the package.json
- if (tree.package._phantomChildren && tree.package._phantomChildren[pkg.name]) return null
+ if (tree.phantomChildren && tree.phantomChildren[pkg.name]) return null
- if (!tree.parent) return tree
+ if (tree.isTop) return tree
if (tree.isGlobal) return tree
- if (npm.config.get('global-style') && !tree.parent.parent) return tree
+ if (npm.config.get('global-style') && tree.parent.isTop) return tree
if (npm.config.get('legacy-bundling')) return tree
return (earliestInstallable(requiredBy, tree.parent, pkg) || tree)
diff --git a/deps/npm/lib/install/diff-trees.js b/deps/npm/lib/install/diff-trees.js
index 8000124604..578cda90ce 100644
--- a/deps/npm/lib/install/diff-trees.js
+++ b/deps/npm/lib/install/diff-trees.js
@@ -59,17 +59,15 @@ function requiredByAllLinked (node) {
return node.requiredBy.filter(isLink).length === node.requiredBy.length
}
-function isNotReqByTop (req) {
- return req !== '/' && // '/' is the top level itself
- req !== '#USER' && // #USER
- req !== '#EXTRANEOUS'
+function isNotTopOrExtraneous (node) {
+ return !node.isTop && !node.userRequired && !node.existing
}
var sortActions = module.exports.sortActions = function (differences) {
var actions = {}
differences.forEach(function (action) {
var child = action[1]
- actions[child.package._location] = action
+ actions[child.location] = action
})
var sorted = []
@@ -77,14 +75,18 @@ var sortActions = module.exports.sortActions = function (differences) {
var sortedlocs = Object.keys(actions).sort(sortByLocation)
- // Do top level deps first, this stops the sorting by required order from
- // unsorting these deps.
+ // We're going to sort the actions taken on top level dependencies first, before
+ // considering the order of transitive deps. Because we're building our list
+ // from the bottom up, this means we will return a list with top level deps LAST.
+ // This is important in terms of keeping installations as consistent as possible
+ // as folks add new dependencies.
var toplocs = sortedlocs.filter(function (location) {
var mod = actions[location][1]
- if (!mod.package._requiredBy) return true
- // If the module is required by ANY non-top level package
- // then we don't want to include this.
- return !mod.package._requiredBy.some(isNotReqByTop)
+ if (!mod.requiredBy) return true
+ // If this module is required by any non-top level module
+ // or by any extraneous module, eg user requested or existing
+ // then we don't want to give this priority sorting.
+ return !mod.requiredBy.some(isNotTopOrExtraneous)
})
toplocs.concat(sortedlocs).forEach(function (location) {
@@ -94,12 +96,16 @@ var sortActions = module.exports.sortActions = function (differences) {
function sortByLocation (aa, bb) {
return bb.localeCompare(aa)
}
+ function sortModuleByLocation (aa, bb) {
+ return sortByLocation(aa && aa.location, bb && bb.location)
+ }
function sortByDeps (action) {
var mod = action[1]
- if (added[mod.package._location]) return
- added[mod.package._location] = action
- mod.package._requiredBy.sort().forEach(function (location) {
- if (actions[location]) sortByDeps(actions[location])
+ if (added[mod.location]) return
+ added[mod.location] = action
+ if (!mod.requiredBy) mod.requiredBy = []
+ mod.requiredBy.sort(sortModuleByLocation).forEach(function (mod) {
+ if (actions[mod.location]) sortByDeps(actions[mod.location])
})
sorted.unshift(action)
}
diff --git a/deps/npm/lib/install/inflate-shrinkwrap.js b/deps/npm/lib/install/inflate-shrinkwrap.js
index b38181b9f1..1853f2c068 100644
--- a/deps/npm/lib/install/inflate-shrinkwrap.js
+++ b/deps/npm/lib/install/inflate-shrinkwrap.js
@@ -55,6 +55,7 @@ var inflateShrinkwrap = module.exports = function (tree, swdeps, finishInflating
})
tree.children.push(child)
if (pkg._bundled) {
+ delete pkg._bundled
inflateBundled(child, child.children)
}
inflateShrinkwrap(child, sw.dependencies || {}, next)
diff --git a/deps/npm/lib/install/is-dev.js b/deps/npm/lib/install/is-dev.js
index b1f2c4b661..e0fae4eb82 100644
--- a/deps/npm/lib/install/is-dev.js
+++ b/deps/npm/lib/install/is-dev.js
@@ -1,7 +1,26 @@
'use strict'
-var isDev = exports.isDev = function (node) {
- return node.package._requiredBy.some(function (req) { return req === '#DEV:/' })
+var moduleName = require('../utils/module-name.js')
+
+function andIsDev (name) {
+ return function (req) {
+ return req.package &&
+ req.package.devDependencies &&
+ req.package.devDependencies[name]
+ }
}
+
+exports.isDev = function (node) {
+ return node.requiredBy.some(andIsDev(moduleName(node)))
+}
+
+function andIsOnlyDev (name) {
+ var isThisDev = andIsDev(name)
+ return function (req) {
+ return isThisDev(req) &&
+ (!req.package.dependencies || !req.package.dependencies[name])
+ }
+}
+
exports.isOnlyDev = function (node) {
- return node.package._requiredBy.length === 1 && isDev(node)
+ return node.requiredBy.every(andIsOnlyDev(moduleName(node)))
}
diff --git a/deps/npm/lib/install/is-extraneous.js b/deps/npm/lib/install/is-extraneous.js
index cd4d954668..f0d599965f 100644
--- a/deps/npm/lib/install/is-extraneous.js
+++ b/deps/npm/lib/install/is-extraneous.js
@@ -1,14 +1,37 @@
'use strict'
-var path = require('path')
-var isDev = require('./is-dev.js').isDev
-var npm = require('../npm.js')
-
-module.exports = function (tree) {
- var pkg = tree.package
- var requiredBy = pkg._requiredBy.filter(function (req) { return req[0] !== '#' })
- var isTopLevel = tree.parent == null
- var isChildOfTop = !isTopLevel && tree.parent.parent == null
- var isTopGlobal = isChildOfTop && tree.parent.path === path.resolve(npm.globalDir, '..')
- var topHasNoPackageJson = isChildOfTop && tree.parent.error
- return !isTopLevel && (!isChildOfTop || !topHasNoPackageJson) && !isTopGlobal && requiredBy.length === 0 && !isDev(tree)
+module.exports = isExtraneous
+
+function isExtraneous (tree) {
+ var result = !isNotExtraneous(tree)
+ return result
+}
+
+function isNotRequired (tree) {
+ return tree.requiredBy && tree.requiredBy.length === 0
+}
+
+function parentHasNoPjson (tree) {
+ return tree.parent && tree.parent.isTop && tree.parent.error
+}
+
+function topHasNoPjson (tree) {
+ var top = tree
+ while (!top.isTop) top = top.parent
+ return top.error
+}
+
+function isNotExtraneous (tree, isCycle) {
+ if (!isCycle) isCycle = {}
+ if (tree.isTop || tree.userRequired) {
+ return true
+ } else if (isNotRequired(tree) && parentHasNoPjson(tree)) {
+ return true
+ } else if (isCycle[tree.path]) {
+ return topHasNoPjson(tree)
+ } else {
+ isCycle[tree.path] = true
+ return tree.requiredBy && tree.requiredBy.some(function (node) {
+ return isNotExtraneous(node, Object.create(isCycle))
+ })
+ }
}
diff --git a/deps/npm/lib/install/mutate-into-logical-tree.js b/deps/npm/lib/install/mutate-into-logical-tree.js
index 833aa94c94..b2059da906 100644
--- a/deps/npm/lib/install/mutate-into-logical-tree.js
+++ b/deps/npm/lib/install/mutate-into-logical-tree.js
@@ -8,6 +8,24 @@ var validateAllPeerDeps = require('./deps.js').validateAllPeerDeps
var packageId = require('../utils/package-id.js')
var moduleName = require('../utils/module-name.js')
+// Return true if tree is a part of a cycle that:
+// A) Never connects to the top of the tree
+// B) Has not not had a point in the cycle arbitraryly declared its top
+// yet.
+function isDisconnectedCycle (tree, seen) {
+ if (!seen) seen = {}
+ if (tree.isTop || tree.cycleTop || tree.requiredBy.length === 0) {
+ return false
+ } else if (seen[tree.path]) {
+ return true
+ } else {
+ seen[tree.path] = true
+ return tree.requiredBy.every(function (node) {
+ return isDisconnectedCycle(node, Object.create(seen))
+ })
+ }
+}
+
var mutateIntoLogicalTree = module.exports = function (tree) {
validate('O', arguments)
@@ -18,35 +36,29 @@ var mutateIntoLogicalTree = module.exports = function (tree) {
var flat = flattenTree(tree)
- function getNode (flatname) {
- return flatname.substr(0, 5) === '#DEV:'
- ? flat[flatname.substr(5)]
- : flat[flatname]
- }
-
Object.keys(flat).sort().forEach(function (flatname) {
var node = flat[flatname]
- var requiredBy = node.package._requiredBy || []
- var requiredByNames = requiredBy.filter(function (parentFlatname) {
- var parentNode = getNode(parentFlatname)
- if (!parentNode) return false
- return parentNode.package.dependencies[moduleName(node)] ||
- (parentNode.package.devDependencies && parentNode.package.devDependencies[moduleName(node)])
- })
- requiredBy = requiredByNames.map(getNode)
-
- node.requiredBy = requiredBy
-
- if (!requiredBy.length) return
+ if (!node.requiredBy.length) return
- if (node.parent) node.parent.children = without(node.parent.children, node)
+ if (node.parent) {
+ // If a node is a cycle that never reaches the root of the logical
+ // tree then we'll leave it attached to the root, or else it
+ // would go missing. Further we'll note that this is the node in the
+ // cycle that we picked arbitrarily to be the one attached to the root.
+ // others will fall
+ if (isDisconnectedCycle(node)) {
+ node.cycleTop = true
+ // Nor do we want to disconnect non-cyclical extraneous modules from the tree.
+ } else if (node.requiredBy.length) {
+ // regular deps though, we do, as we're moving them into the capable
+ // hands of the modules that require them.
+ node.parent.children = without(node.parent.children, node)
+ }
+ }
- requiredBy.forEach(function (parentNode) {
+ node.requiredBy.forEach(function (parentNode) {
parentNode.children = union(parentNode.children, [node])
})
- if (node.package._requiredBy.some(function (nodename) { return nodename[0] === '#' })) {
- tree.children = union(tree.children, [node])
- }
})
return tree
}
@@ -70,18 +82,27 @@ function translateTree_ (tree, seen) {
tree.children.forEach(function (child) {
pkg.dependencies[moduleName(child)] = translateTree_(child, seen)
})
- Object.keys(tree.missingDeps).forEach(function (name) {
+
+ function markMissing (name, requiredBy) {
if (pkg.dependencies[name]) {
+ if (pkg.dependencies[name].missing) return
pkg.dependencies[name].invalid = true
pkg.dependencies[name].realName = name
pkg.dependencies[name].extraneous = false
} else {
pkg.dependencies[name] = {
- requiredBy: tree.missingDeps[name],
+ requiredBy: requiredBy,
missing: true,
optional: !!pkg.optionalDependencies[name]
}
}
+ }
+
+ Object.keys(tree.missingDeps).forEach(function (name) {
+ markMissing(name, tree.missingDeps[name])
+ })
+ Object.keys(tree.missingDevDeps).forEach(function (name) {
+ markMissing(name, tree.missingDevDeps[name])
})
var checkForMissingPeers = (tree.parent ? [] : [tree]).concat(tree.children)
checkForMissingPeers.filter(function (child) {
diff --git a/deps/npm/lib/install/node.js b/deps/npm/lib/install/node.js
index c76dc765ba..a5b766b054 100644
--- a/deps/npm/lib/install/node.js
+++ b/deps/npm/lib/install/node.js
@@ -2,11 +2,10 @@
var defaultTemplate = {
package: {
+ version: '',
dependencies: {},
devDependencies: {},
- optionalDependencies: {},
- _requiredBy: [],
- _phantomChildren: {}
+ optionalDependencies: {}
},
loaded: false,
children: [],
@@ -14,10 +13,13 @@ var defaultTemplate = {
requires: [],
missingDeps: {},
missingDevDeps: {},
+ phantomChildren: {},
path: null,
realpath: null,
+ location: null,
userRequired: false,
- existing: false
+ existing: false,
+ isTop: false
}
function isLink (node) {
@@ -34,7 +36,7 @@ var create = exports.create = function (node, template) {
if (node[key] != null) return
node[key] = template[key]
})
- if (isLink(node) || isLink(node.parent)) {
+ if (isLink(node.parent)) {
node.isLink = true
}
return node
@@ -48,14 +50,17 @@ function reset (node, seen) {
if (seen[node.path]) return
seen[node.path] = true
var child = create(node)
- child.package._requiredBy = child.package._requiredBy.filter(function (req) {
- return req[0] === '#'
- })
- child.requiredBy = []
- child.package._phantomChildren = {}
+
// FIXME: cleaning up after read-package-json's mess =(
if (child.package._id === '@') delete child.package._id
+
+ child.isTop = false
+ child.requiredBy = []
+ child.requires = []
child.missingDeps = {}
+ child.missingDevDeps = {}
+ child.phantomChildren = {}
+ child.location = null
+
child.children.forEach(function (child) { reset(child, seen) })
- if (!child.package.version) child.package.version = ''
}
diff --git a/deps/npm/lib/install/prune-tree.js b/deps/npm/lib/install/prune-tree.js
deleted file mode 100644
index eb3edf4f75..0000000000
--- a/deps/npm/lib/install/prune-tree.js
+++ /dev/null
@@ -1,36 +0,0 @@
-'use strict'
-var validate = require('aproba')
-var flattenTree = require('./flatten-tree.js')
-
-function isNotPackage (mod) {
- return function (parentMod) { return mod !== parentMod }
-}
-
-module.exports = function pruneTree (tree) {
- validate('O', arguments)
- var flat = flattenTree(tree)
- // we just do this repeatedly until there are no more orphaned packages
- // which isn't as effecient as it could be on a REALLY big tree
- // but we'll face that if it proves to be an issue
- var removedPackage
- do {
- removedPackage = false
- Object.keys(flat).forEach(function (flatname) {
- var child = flat[flatname]
- if (!child.parent) return
- child.package._requiredBy = (child.package._requiredBy || []).filter(function (req) {
- var isDev = req.substr(0, 4) === '#DEV'
- if (req[0] === '#' && !isDev) return true
- if (flat[req]) return true
- if (!isDev) return false
- var reqChildAsDevDep = flat[req.substr(5)]
- return reqChildAsDevDep && !reqChildAsDevDep.parent
- })
- if (!child.package._requiredBy.length) {
- removedPackage = true
- delete flat[flatname]
- child.parent.children = child.parent.children.filter(isNotPackage(child))
- }
- })
- } while (removedPackage)
-}
diff --git a/deps/npm/lib/install/save.js b/deps/npm/lib/install/save.js
index acbe8c5bb3..708da61c8a 100644
--- a/deps/npm/lib/install/save.js
+++ b/deps/npm/lib/install/save.js
@@ -12,6 +12,7 @@ var npm = require('../npm.js')
var deepSortObject = require('../utils/deep-sort-object.js')
var parseJSON = require('../utils/parse-json.js')
var moduleName = require('../utils/module-name.js')
+var isOnlyDev = require('./is-dev.js').isOnlyDev
// if the -S|--save option is specified, then write installed packages
// as dependencies to a package.json file.
@@ -49,8 +50,7 @@ function saveShrinkwrap (tree, next) {
var shrinkwrap = tree.package._shrinkwrap || {dependencies: {}}
var hasDevOnlyDeps = tree.requires.filter(function (dep) {
- var devReqs = dep.package._requiredBy.filter(function (name) { return name.substr(0, 4) === '#DEV' })
- return devReqs.length === dep.package._requiredBy.length
+ return isOnlyDev(dep)
}).some(function (dep) {
return shrinkwrap.dependencies[dep.package.name] != null
})
diff --git a/deps/npm/lib/install/update-package-json.js b/deps/npm/lib/install/update-package-json.js
index 97b2f05bb0..eee530c3cd 100644
--- a/deps/npm/lib/install/update-package-json.js
+++ b/deps/npm/lib/install/update-package-json.js
@@ -1,18 +1,46 @@
'use strict'
var path = require('path')
var writeFileAtomic = require('write-file-atomic')
+var moduleName = require('../utils/module-name.js')
var deepSortObject = require('../utils/deep-sort-object.js')
+var sortedObject = require('sorted-object')
+
+var sortKeys = [
+ 'dependencies', 'devDependencies', 'bundleDependencies',
+ 'optionalDependencies', 'keywords', 'engines', 'scripts',
+ 'files'
+]
+
+module.exports = function (mod, buildpath, next) {
+ var pkg = sortedObject(mod.package)
+ var name = moduleName(mod)
+ // Add our diagnostic keys to the package.json.
+ // Note that there are folks relying on these, for ex, the Visual Studio
+ // Node.js addon.
+ pkg._requiredBy =
+ mod.requiredBy
+ .map(function (req) {
+ if (req.package.devDependencies[name] && !req.package.dependencies[name]) {
+ return '#DEV:' + req.location
+ } else {
+ return req.location
+ }
+ })
+ .concat(mod.userRequired ? ['#USER'] : [])
+ .concat(mod.existing ? ['#EXISTING'] : [])
+ .sort()
+ pkg._location = mod.location
+ pkg._phantomChildren = {}
+ Object.keys(mod.phantomChildren).sort().forEach(function (name) {
+ pkg._phantomChildren[name] = mod.phantomChildren[name].package.version
+ })
+
+ // sort keys that are known safe to sort to produce more consistent output
+ sortKeys.forEach(function (key) {
+ if (pkg[key] != null) pkg[key] = deepSortObject(pkg[key])
+ })
+
+ var data = JSON.stringify(sortedObject(pkg), null, 2) + '\n'
-module.exports = function (pkg, buildpath, next) {
- // FIXME: This bundled dance is because we're sticking a big tree of bundled
- // deps into the parsed package.json– it probably doesn't belong there =/
- // But the real reason we don't just dump it out is that it's the result
- // of npm-read-tree, which produces circular data structures, due to the
- // parent and children keys.
- var bundled = pkg.package._bundled
- delete pkg.package._bundled // FIXME
- var packagejson = deepSortObject(pkg.package)
- var data = JSON.stringify(packagejson, null, 2) + '\n'
- pkg.package._bundled = bundled
writeFileAtomic(path.resolve(buildpath, 'package.json'), data, next)
}
diff --git a/deps/npm/lib/link.js b/deps/npm/lib/link.js
index 3624a16c98..54b8dcac7a 100644
--- a/deps/npm/lib/link.js
+++ b/deps/npm/lib/link.js
@@ -11,6 +11,7 @@ var path = require('path')
var build = require('./build.js')
var npa = require('npm-package-arg')
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
module.exports = link
@@ -179,9 +180,7 @@ function resultPrinter (pkg, src, dest, rp, cb) {
return parseableOutput(dest, rp || src, cb)
}
if (rp === src) rp = null
- log.clearProgress()
- console.log(where + ' -> ' + src + (rp ? ' -> ' + rp : ''))
- log.showProgress()
+ output(where + ' -> ' + src + (rp ? ' -> ' + rp : ''))
cb()
}
@@ -193,8 +192,6 @@ function parseableOutput (dest, rp, cb) {
// *just* print the target folder.
// However, we don't actually ever read the version number, so
// the second field is always blank.
- log.clearProgress()
- console.log(dest + '::' + rp)
- log.showProgress()
+ output(dest + '::' + rp)
cb()
}
diff --git a/deps/npm/lib/ls.js b/deps/npm/lib/ls.js
index d2fe14fb2f..ba5ab16e51 100644
--- a/deps/npm/lib/ls.js
+++ b/deps/npm/lib/ls.js
@@ -20,6 +20,7 @@ var mutateIntoLogicalTree = require('./install/mutate-into-logical-tree.js')
var recalculateMetadata = require('./install/deps.js').recalculateMetadata
var packageId = require('./utils/package-id.js')
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
ls.usage = usage(
'ls',
@@ -99,7 +100,7 @@ var lsFromTree = ls.fromTree = function (dir, physicalTree, args, silent, cb) {
} else if (data) {
out = makeArchy(bfs, long, dir)
}
- console.log(out)
+ output(out)
if (args.length && !data._found) process.exitCode = 1
diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js
index 9d6cda386a..4f81015251 100644
--- a/deps/npm/lib/npm.js
+++ b/deps/npm/lib/npm.js
@@ -22,6 +22,7 @@
var npmconf = require('./config/core.js')
var log = require('npmlog')
+ var tty = require('tty')
var path = require('path')
var abbrev = require('abbrev')
var which = require('which')
@@ -30,6 +31,7 @@
var aliases = require('./config/cmd-list').aliases
var cmdList = require('./config/cmd-list').cmdList
var plumbing = require('./config/cmd-list').plumbing
+ var output = require('./utils/output.js')
npm.config = {
loaded: false,
@@ -140,7 +142,7 @@
function defaultCb (er, data) {
log.disableProgress()
if (er) console.error(er.stack || er.message)
- else console.log(data)
+ else output(data)
}
npm.deref = function (c) {
@@ -261,7 +263,6 @@
npm.color = false
break
default:
- var tty = require('tty')
if (process.stdout.isTTY) npm.color = true
else if (!tty.isatty) npm.color = true
else if (tty.isatty(1)) npm.color = true
@@ -269,19 +270,19 @@
break
}
- log.resume()
+ if (config.get('unicode')) {
+ log.enableUnicode()
+ } else {
+ log.disableUnicode()
+ }
- if (config.get('progress')) {
+ if (config.get('progress') && (process.stderr.isTTY || (tty.isatty && tty.isatty(2)))) {
log.enableProgress()
} else {
log.disableProgress()
}
- if (config.get('unicode')) {
- log.enableUnicode()
- } else {
- log.disableUnicode()
- }
+ log.resume()
// at this point the configs are all set.
// go ahead and spin up the registry client.
diff --git a/deps/npm/lib/outdated.js b/deps/npm/lib/outdated.js
index 50bdb363d1..dd59798365 100644
--- a/deps/npm/lib/outdated.js
+++ b/deps/npm/lib/outdated.js
@@ -40,6 +40,7 @@ var mapToRegistry = require('./utils/map-to-registry.js')
var isExtraneous = require('./install/is-extraneous.js')
var recalculateMetadata = require('./install/deps.js').recalculateMetadata
var moduleName = require('./utils/module-name.js')
+var output = require('./utils/output.js')
function uniqName (item) {
return item[0].path + '|' + item[1] + '|' + item[7]
@@ -75,6 +76,7 @@ function outdated (args, silent, cb) {
if (npm.config.get('depth') === Infinity) npm.config.set('depth', 0)
readPackageTree(dir, andRecalculateMetadata(function (er, tree) {
+ if (!tree) return cb(er)
mutateIntoLogicalTree(tree)
outdated_(args, '', tree, {}, 0, function (er, list) {
list = uniq(list || []).sort(function (aa, bb) {
@@ -82,11 +84,10 @@ function outdated (args, silent, cb) {
aa[1].localeCompare(bb[1])
})
if (er || silent || list.length === 0) return cb(er, list)
- log.disableProgress()
if (npm.config.get('json')) {
- console.log(makeJSON(list))
+ output(makeJSON(list))
} else if (npm.config.get('parseable')) {
- console.log(makeParseable(list))
+ output(makeParseable(list))
} else {
var outList = list.map(makePretty)
var outHead = [ 'Package',
@@ -108,7 +109,7 @@ function outdated (args, silent, cb) {
align: ['l', 'r', 'r', 'r', 'l'],
stringLength: function (s) { return ansiTrim(s).length }
}
- console.log(table(outTable, tableOpts))
+ output(table(outTable, tableOpts))
}
cb(null, list.map(function (item) { return [item[0].parent.path].concat(item.slice(1, 7)) }))
})
@@ -142,8 +143,6 @@ function makePretty (p) {
columns[0] = color[has === want || want === 'linked' ? 'yellow' : 'red'](columns[0]) // dep
columns[2] = color.green(columns[2]) // want
columns[3] = color.magenta(columns[3]) // latest
- columns[4] = color.brightBlack(columns[4]) // dir
- if (long) columns[5] = color.brightBlack(columns[5]) // type
}
return columns
@@ -333,7 +332,7 @@ function shouldUpdate (args, tree, dep, has, req, depth, pkgpath, cb, type) {
if (args.length && args.indexOf(dep) === -1) return skip()
var parsed = npa(dep + '@' + req)
- if (tree.isLink && (tree.parent !== null && tree.parent.parent === null)) {
+ if (tree.isLink && tree.parent && tree.parent.isTop) {
return doIt('linked', 'linked')
}
if (parsed.type === 'git' || parsed.type === 'hosted') {
diff --git a/deps/npm/lib/owner.js b/deps/npm/lib/owner.js
index 2cc3eef3b9..64d086af78 100644
--- a/deps/npm/lib/owner.js
+++ b/deps/npm/lib/owner.js
@@ -5,6 +5,7 @@ var log = require('npmlog')
var mapToRegistry = require('./utils/map-to-registry.js')
var readLocalPkg = require('./utils/read-local-package.js')
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
owner.usage = usage(
'owner',
@@ -127,7 +128,7 @@ function ls (pkg, cb) {
return o.name + ' <' + o.email + '>'
}).join('\n')
}
- console.log(msg)
+ output(msg)
cb(er, owners)
})
})
@@ -258,9 +259,9 @@ function mutate (pkg, user, mutation, cb) {
if (er) {
log.error('owner mutate', 'Failed to update package metadata')
} else if (m.length > beforeMutation) {
- console.log('+ %s (%s)', user, pkg)
+ output('+ %s (%s)', user, pkg)
} else if (m.length < beforeMutation) {
- console.log('- %s (%s)', user, pkg)
+ output('- %s (%s)', user, pkg)
}
cb(er, data)
diff --git a/deps/npm/lib/pack.js b/deps/npm/lib/pack.js
index c98f5f2020..ede59dd12c 100644
--- a/deps/npm/lib/pack.js
+++ b/deps/npm/lib/pack.js
@@ -12,6 +12,7 @@ var path = require('path')
var cwd = process.cwd()
var writeStreamAtomic = require('fs-write-stream-atomic')
var cachedPackageRoot = require('./cache/cached-package-root.js')
+var output = require('./utils/output.js')
pack.usage = 'npm pack [[<@scope>/]<pkg>...]'
@@ -39,7 +40,7 @@ function printFiles (files, cb) {
files = files.map(function (file) {
return path.relative(cwd, file)
})
- console.log(files.join('\n'))
+ output(files.join('\n'))
cb()
}
diff --git a/deps/npm/lib/ping.js b/deps/npm/lib/ping.js
index 23b18bfba0..a86150508d 100644
--- a/deps/npm/lib/ping.js
+++ b/deps/npm/lib/ping.js
@@ -1,4 +1,5 @@
var npm = require('./npm.js')
+var output = require('./utils/output.js')
module.exports = ping
@@ -14,7 +15,7 @@ function ping (args, silent, cb) {
var auth = npm.config.getCredentialsByURI(registry)
npm.registry.ping(registry, {auth: auth}, function (er, pong) {
- if (!silent) console.log(JSON.stringify(pong))
+ if (!silent) output(JSON.stringify(pong))
cb(er, er ? null : pong)
})
}
diff --git a/deps/npm/lib/prefix.js b/deps/npm/lib/prefix.js
index 42f61103f6..fb20389c45 100644
--- a/deps/npm/lib/prefix.js
+++ b/deps/npm/lib/prefix.js
@@ -1,6 +1,7 @@
module.exports = prefix
var npm = require('./npm.js')
+var output = require('./utils/output.js')
prefix.usage = 'npm prefix [-g]'
@@ -9,6 +10,6 @@ function prefix (args, silent, cb) {
cb = silent
silent = false
}
- if (!silent) console.log(npm.prefix)
+ if (!silent) output(npm.prefix)
process.nextTick(cb.bind(this, null, npm.prefix))
}
diff --git a/deps/npm/lib/publish.js b/deps/npm/lib/publish.js
index 45de4f24b4..e1826df9d4 100644
--- a/deps/npm/lib/publish.js
+++ b/deps/npm/lib/publish.js
@@ -13,6 +13,7 @@ var createReadStream = require('graceful-fs').createReadStream
var npa = require('npm-package-arg')
var semver = require('semver')
var getPublishConfig = require('./utils/get-publish-config.js')
+var output = require('./utils/output.js')
publish.usage = 'npm publish [<tarball>|<folder>] [--tag <tag>] [--access <public|restricted>]' +
"\n\nPublishes '.' if no argument supplied" +
@@ -147,8 +148,7 @@ function publish_ (arg, data, isRetry, cachedir, cb) {
// report the unpublish error if this was a retry and unpublish failed
if (er && isRetry && isRetry !== true) return cb(isRetry)
if (er) return cb(er)
- log.clearProgress()
- console.log('+ ' + data._id)
+ output('+ ' + data._id)
cb()
})
})
diff --git a/deps/npm/lib/rebuild.js b/deps/npm/lib/rebuild.js
index 29492c27f2..2673b1cfea 100644
--- a/deps/npm/lib/rebuild.js
+++ b/deps/npm/lib/rebuild.js
@@ -7,6 +7,7 @@ var log = require('npmlog')
var npm = require('./npm.js')
var npa = require('npm-package-arg')
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
rebuild.usage = usage(
'rebuild',
@@ -33,11 +34,9 @@ function rebuild (args, cb) {
function cleanBuild (folders, set, cb) {
npm.commands.build(folders, function (er) {
if (er) return cb(er)
- log.clearProgress()
- console.log(folders.map(function (f) {
+ output(folders.map(function (f) {
return set[f] + ' ' + f
}).join('\n'))
- log.showProgress()
cb()
})
}
diff --git a/deps/npm/lib/root.js b/deps/npm/lib/root.js
index 958361d351..82a804aff5 100644
--- a/deps/npm/lib/root.js
+++ b/deps/npm/lib/root.js
@@ -1,6 +1,7 @@
module.exports = root
var npm = require('./npm.js')
+var output = require('./utils/output.js')
root.usage = 'npm root [-g]'
@@ -9,6 +10,6 @@ function root (args, silent, cb) {
cb = silent
silent = false
}
- if (!silent) console.log(npm.dir)
+ if (!silent) output(npm.dir)
process.nextTick(cb.bind(this, null, npm.dir))
}
diff --git a/deps/npm/lib/run-script.js b/deps/npm/lib/run-script.js
index f9c6872aa9..05bc1fe98b 100644
--- a/deps/npm/lib/run-script.js
+++ b/deps/npm/lib/run-script.js
@@ -7,6 +7,7 @@ var readJson = require('read-package-json')
var log = require('npmlog')
var chain = require('slide').chain
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
runScript.usage = usage(
'run-script',
@@ -91,13 +92,13 @@ function list (cb) {
}
if (npm.config.get('json')) {
- console.log(JSON.stringify(d.scripts || {}, null, 2))
+ output(JSON.stringify(d.scripts || {}, null, 2))
return cb(null, allScripts)
}
if (npm.config.get('parseable')) {
allScripts.forEach(function (script) {
- console.log(script + ':' + d.scripts[script])
+ output(script + ':' + d.scripts[script])
})
return cb(null, allScripts)
}
@@ -105,18 +106,18 @@ function list (cb) {
var s = '\n '
var prefix = ' '
if (scripts.length) {
- console.log('Lifecycle scripts included in %s:', d.name)
+ output('Lifecycle scripts included in %s:', d.name)
}
scripts.forEach(function (script) {
- console.log(prefix + script + s + d.scripts[script])
+ output(prefix + script + s + d.scripts[script])
})
if (!scripts.length && runScripts.length) {
- console.log('Scripts available in %s via `npm run-script`:', d.name)
+ output('Scripts available in %s via `npm run-script`:', d.name)
} else if (runScripts.length) {
- console.log('\navailable via `npm run-script`:')
+ output('\navailable via `npm run-script`:')
}
runScripts.forEach(function (script) {
- console.log(prefix + script + s + d.scripts[script])
+ output(prefix + script + s + d.scripts[script])
})
return cb(null, allScripts)
})
diff --git a/deps/npm/lib/search.js b/deps/npm/lib/search.js
index d71102ac3e..cd6d5ed8ea 100644
--- a/deps/npm/lib/search.js
+++ b/deps/npm/lib/search.js
@@ -5,6 +5,7 @@ var npm = require('./npm.js')
var columnify = require('columnify')
var updateIndex = require('./cache/update-index.js')
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
search.usage = usage(
'search',
@@ -70,7 +71,7 @@ function search (args, silent, staleness, cb) {
// prettify and print it, and then provide the raw
// data to the cb.
if (er || silent) return cb(er, data)
- console.log(prettify(data, args))
+ output(prettify(data, args))
cb(null, data)
})
}
diff --git a/deps/npm/lib/shrinkwrap.js b/deps/npm/lib/shrinkwrap.js
index 9a6d8e76bd..c6a41842fc 100644
--- a/deps/npm/lib/shrinkwrap.js
+++ b/deps/npm/lib/shrinkwrap.js
@@ -7,8 +7,10 @@ var path = require('path')
var log = require('npmlog')
var writeFileAtomic = require('write-file-atomic')
var iferr = require('iferr')
+var readPackageJson = require('read-package-json')
var readPackageTree = require('read-package-tree')
var validate = require('aproba')
+var chain = require('slide').chain
var npm = require('./npm.js')
var recalculateMetadata = require('./install/deps.js').recalculateMetadata
var validatePeerDeps = require('./install/deps.js').validatePeerDeps
@@ -16,6 +18,8 @@ var isExtraneous = require('./install/is-extraneous.js')
var isOnlyDev = require('./install/is-dev.js').isOnlyDev
var packageId = require('./utils/package-id.js')
var moduleName = require('./utils/module-name.js')
+var output = require('./utils/output.js')
+var lifecycle = require('./utils/lifecycle.js')
shrinkwrap.usage = 'npm shrinkwrap'
@@ -30,11 +34,24 @@ function shrinkwrap (args, silent, cb) {
}
var dir = path.resolve(npm.dir, '..')
+ var packagePath = path.join(npm.localPrefix, 'package.json')
npm.config.set('production', true)
- readPackageTree(dir, andRecalculateMetadata(iferr(cb, function (tree) {
- var pkginfo = treeToShrinkwrap(tree, !!npm.config.get('dev') || /^dev(elopment)?$/.test(npm.config.get('also')))
- shrinkwrap_(pkginfo, silent, cb)
- })))
+
+ readPackageJson(packagePath, iferr(cb, function (data) {
+ lifecycle(data, 'preshrinkwrap', function () {
+ readPackageTree(dir, andRecalculateMetadata(iferr(cb, function (tree) {
+ var pkginfo = treeToShrinkwrap(tree, !!npm.config.get('dev') || /^dev(elopment)?$/.test(npm.config.get('also')))
+
+ chain([
+ [lifecycle, tree.package, 'shrinkwrap'],
+ [shrinkwrap_, pkginfo, silent],
+ [lifecycle, tree.package, 'postshrinkwrap']
+ ], iferr(cb, function (data) {
+ cb(null, data[0])
+ }))
+ })))
+ })
+ }))
}
function andRecalculateMetadata (next) {
@@ -122,9 +139,7 @@ function save (pkginfo, silent, cb) {
writeFileAtomic(file, swdata, function (er) {
if (er) return cb(er)
if (silent) return cb(null, pkginfo)
- log.clearProgress()
- console.log('wrote npm-shrinkwrap.json')
- log.showProgress()
+ output('wrote npm-shrinkwrap.json')
cb(null, pkginfo)
})
}
diff --git a/deps/npm/lib/star.js b/deps/npm/lib/star.js
index ce141688b9..f19cb4b07b 100644
--- a/deps/npm/lib/star.js
+++ b/deps/npm/lib/star.js
@@ -5,6 +5,7 @@ var log = require('npmlog')
var asyncMap = require('slide').asyncMap
var mapToRegistry = require('./utils/map-to-registry.js')
var usage = require('./utils/usage')
+var output = require('./utils/output.js')
star.usage = usage(
'star',
@@ -34,7 +35,7 @@ function star (args, cb) {
}
npm.registry.star(uri, params, function (er, data, raw, req) {
if (!er) {
- console.log(s + ' ' + pkg)
+ output(s + ' ' + pkg)
log.verbose('star', data)
}
cb(er, data, raw, req)
diff --git a/deps/npm/lib/stars.js b/deps/npm/lib/stars.js
index 4ad8f02e59..4771079356 100644
--- a/deps/npm/lib/stars.js
+++ b/deps/npm/lib/stars.js
@@ -5,6 +5,7 @@ stars.usage = 'npm stars [<user>]'
var npm = require('./npm.js')
var log = require('npmlog')
var mapToRegistry = require('./utils/map-to-registry.js')
+var output = require('./utils/output.js')
function stars (args, cb) {
npm.commands.whoami([], true, function (er, username) {
@@ -38,7 +39,7 @@ function stars (args, cb) {
log.warn('stars', 'user has not starred any packages.')
} else {
data.rows.forEach(function (a) {
- console.log(a.value)
+ output(a.value)
})
}
cb()
diff --git a/deps/npm/lib/substack.js b/deps/npm/lib/substack.js
index c39a5dcc48..428e0a5898 100644
--- a/deps/npm/lib/substack.js
+++ b/deps/npm/lib/substack.js
@@ -1,5 +1,6 @@
module.exports = substack
var npm = require('./npm.js')
+var output = require('./utils/output.js')
var isms = [
'\u001b[32mbeep \u001b[35mboop\u001b[m',
@@ -14,7 +15,7 @@ var isms = [
function substack (args, cb) {
var i = Math.floor(Math.random() * isms.length)
- console.log(isms[i])
+ output(isms[i])
var c = args.shift()
if (c) npm.commands[c](args, cb)
else cb()
diff --git a/deps/npm/lib/team.js b/deps/npm/lib/team.js
index 324d8df5e2..f99063b278 100644
--- a/deps/npm/lib/team.js
+++ b/deps/npm/lib/team.js
@@ -1,5 +1,6 @@
var mapToRegistry = require('./utils/map-to-registry.js')
var npm = require('./npm')
+var output = require('./utils/output.js')
module.exports = team
@@ -44,7 +45,7 @@ function team (args, cb) {
team: entity[1],
user: args.shift()
}, function (err, data) {
- !err && data && console.log(JSON.stringify(data, undefined, 2))
+ !err && data && output(JSON.stringify(data, undefined, 2))
cb(err, data)
})
} catch (e) {
diff --git a/deps/npm/lib/unbuild.js b/deps/npm/lib/unbuild.js
index f5efb1ee6d..9ba5972d8a 100644
--- a/deps/npm/lib/unbuild.js
+++ b/deps/npm/lib/unbuild.js
@@ -12,6 +12,7 @@ var asyncMap = require('slide').asyncMap
var chain = require('slide').chain
var log = require('npmlog')
var build = require('./build.js')
+var output = require('./utils/output.js')
// args is a list of folders.
// remove any bins/etc, and then delete the folder.
@@ -40,9 +41,7 @@ function unbuild_ (silent) {
[lifecycle, pkg, 'preuninstall', folder, false, true],
[lifecycle, pkg, 'uninstall', folder, false, true],
!silent && function (cb) {
- log.clearProgress()
- console.log('unbuild ' + pkg._id)
- log.showProgress()
+ output('unbuild ' + pkg._id)
cb()
},
[rmStuff, pkg, folder],
diff --git a/deps/npm/lib/unpublish.js b/deps/npm/lib/unpublish.js
index 63f87b8207..ee050c2846 100644
--- a/deps/npm/lib/unpublish.js
+++ b/deps/npm/lib/unpublish.js
@@ -8,6 +8,7 @@ var path = require('path')
var mapToRegistry = require('./utils/map-to-registry.js')
var npa = require('npm-package-arg')
var getPublishConfig = require('./utils/get-publish-config.js')
+var output = require('./utils/output.js')
unpublish.usage = 'npm unpublish [<@scope>/]<pkg>[@<version>]'
@@ -89,7 +90,7 @@ function gotProject (project, version, publishConfig, cb_) {
function cb (er) {
if (er) return cb_(er)
- console.log('- ' + project + (version ? '@' + version : ''))
+ output('- ' + project + (version ? '@' + version : ''))
cb_()
}
diff --git a/deps/npm/lib/utils/git.js b/deps/npm/lib/utils/git.js
index dc021300ea..4d05c75b86 100644
--- a/deps/npm/lib/utils/git.js
+++ b/deps/npm/lib/utils/git.js
@@ -11,6 +11,7 @@ var which = require('which')
var git = npm.config.get('git')
var assert = require('assert')
var log = require('npmlog')
+var noProgressTillDone = require('./no-progress-while-running.js').tillDone
function prefixGitArgs () {
return process.platform === 'win32' ? ['-c', 'core.longpaths=true'] : []
@@ -19,7 +20,7 @@ function prefixGitArgs () {
function execGit (args, options, cb) {
log.info('git', args)
var fullArgs = prefixGitArgs().concat(args || [])
- return exec(git, fullArgs, options, cb)
+ return exec(git, fullArgs, options, noProgressTillDone(cb))
}
function spawnGit (args, options) {
diff --git a/deps/npm/lib/utils/lifecycle.js b/deps/npm/lib/utils/lifecycle.js
index fd1a59b74c..6a862366f2 100644
--- a/deps/npm/lib/utils/lifecycle.js
+++ b/deps/npm/lib/utils/lifecycle.js
@@ -14,6 +14,7 @@ var PATH = 'PATH'
var uidNumber = require('uid-number')
var umask = require('./umask')
var usage = require('./usage')
+var output = require('./output.js')
// windows calls it's path 'Path' usually, but this is not guaranteed.
if (process.platform === 'win32') {
@@ -182,9 +183,7 @@ function runCmd (note, cmd, pkg, env, stage, wd, unsafe, cb) {
var group = unsafe ? null : npm.config.get('group')
if (log.level !== 'silent') {
- log.clearProgress()
- console.log(note)
- log.showProgress()
+ output(note)
}
log.verbose('lifecycle', logid(pkg, stage), 'unsafe-perm in lifecycle', unsafe)
@@ -232,8 +231,6 @@ function runCmd_ (cmd, pkg, env, wd, stage, unsafe, uid, gid, cb_) {
log.verbose('lifecycle', logid(pkg, stage), 'CWD:', wd)
log.silly('lifecycle', logid(pkg, stage), 'Args:', [shFlag, cmd])
- var progressEnabled = log.progressEnabled
- if (progressEnabled) log.disableProgress()
var proc = spawn(sh, [shFlag, cmd], conf)
proc.on('error', procError)
@@ -249,7 +246,6 @@ function runCmd_ (cmd, pkg, env, wd, stage, unsafe, uid, gid, cb_) {
process.once('SIGTERM', procKill)
function procError (er) {
- if (progressEnabled) log.enableProgress()
if (er) {
log.info('lifecycle', logid(pkg, stage), 'Failed to exec ' + stage + ' script')
er.message = pkg._id + ' ' + stage + ': `' + cmd + '`\n' +
diff --git a/deps/npm/lib/utils/no-progress-while-running.js b/deps/npm/lib/utils/no-progress-while-running.js
new file mode 100644
index 0000000000..961fa8b555
--- /dev/null
+++ b/deps/npm/lib/utils/no-progress-while-running.js
@@ -0,0 +1,23 @@
+'use strict'
+var log = require('npmlog')
+var progressEnabled
+var running = 0
+
+var startRunning = exports.startRunning = function () {
+ if (progressEnabled == null) progressEnabled = log.progressEnabled
+ if (progressEnabled) log.disableProgress()
+ ++running
+}
+
+var stopRunning = exports.stopRunning = function () {
+ --running
+ if (progressEnabled && running === 0) log.enableProgress()
+}
+
+exports.tillDone = function noProgressTillDone (cb) {
+ startRunning()
+ return function () {
+ stopRunning()
+ cb.apply(this, arguments)
+ }
+}
diff --git a/deps/npm/lib/utils/output.js b/deps/npm/lib/utils/output.js
new file mode 100644
index 0000000000..3dd66cbdd2
--- /dev/null
+++ b/deps/npm/lib/utils/output.js
@@ -0,0 +1,8 @@
+'use strict'
+var log = require('npmlog')
+// output to stdout in a progress bar compatible way
+module.exports = function () {
+ log.clearProgress()
+ console.log.apply(console, arguments)
+ log.showProgress()
+}
diff --git a/deps/npm/lib/utils/pulse-till-done.js b/deps/npm/lib/utils/pulse-till-done.js
index fc6450e003..2669241306 100644
--- a/deps/npm/lib/utils/pulse-till-done.js
+++ b/deps/npm/lib/utils/pulse-till-done.js
@@ -7,9 +7,10 @@ var pulse
module.exports = function (prefix, cb) {
validate('SF', [prefix, cb])
+ if (!prefix) prefix = 'network'
if (!pulsers++) {
pulse = setInterval(function () {
- log.gauge.pulse('network')
+ log.gauge.pulse(prefix)
}, 250)
}
return function () {
diff --git a/deps/npm/lib/utils/spawn.js b/deps/npm/lib/utils/spawn.js
index e389d83e02..b164a6acba 100644
--- a/deps/npm/lib/utils/spawn.js
+++ b/deps/npm/lib/utils/spawn.js
@@ -2,15 +2,31 @@ module.exports = spawn
var _spawn = require('child_process').spawn
var EventEmitter = require('events').EventEmitter
+var npwr = require('./no-progress-while-running.js')
+
+function willCmdOutput (stdio) {
+ if (stdio === 'inherit') return true
+ if (!Array.isArray(stdio)) return false
+ for (var fh = 1; fh <= 2; ++fh) {
+ if (stdio[fh] === 'inherit') return true
+ if (stdio[fh] === 1 || stdio[fh] === 2) return true
+ }
+ return false
+}
function spawn (cmd, args, options) {
+ var cmdWillOutput = willCmdOutput(options && options.stdio)
+
+ if (cmdWillOutput) npwr.startRunning()
var raw = _spawn(cmd, args, options)
var cooked = new EventEmitter()
raw.on('error', function (er) {
+ if (cmdWillOutput) npwr.stopRunning()
er.file = cmd
cooked.emit('error', er)
}).on('close', function (code, signal) {
+ if (cmdWillOutput) npwr.stopRunning()
// Create ENOENT error because Node.js v0.8 will not emit
// an `error` event if the command could not be found.
if (code === 127) {
diff --git a/deps/npm/lib/utils/tar.js b/deps/npm/lib/utils/tar.js
index 98f6e4ff64..1e00040dbb 100644
--- a/deps/npm/lib/utils/tar.js
+++ b/deps/npm/lib/utils/tar.js
@@ -20,9 +20,9 @@ var myUid = process.getuid && process.getuid()
var myGid = process.getgid && process.getgid()
var readPackageTree = require('read-package-tree')
var union = require('lodash.union')
-var flattenTree = require('../install/flatten-tree.js')
var moduleName = require('./module-name.js')
var packageId = require('./package-id.js')
+var pulseTillDone = require('../utils/pulse-till-done.js')
if (process.env.SUDO_UID && myUid === 0) {
if (!isNaN(process.env.SUDO_UID)) myUid = +process.env.SUDO_UID
@@ -40,18 +40,20 @@ function pack (tarball, folder, pkg, cb) {
readJson(path.join(folder, 'package.json'), function (er, pkg) {
if (er || !pkg.bundleDependencies) {
- pack_(tarball, folder, null, null, pkg, cb)
+ pack_(tarball, folder, null, pkg, cb)
} else {
// we require this at runtime due to load-order issues, because recursive
// requires fail if you replace the exports object, and we do, not in deps, but
// in a dep of it.
var recalculateMetadata = require('../install/deps.js').recalculateMetadata
- readPackageTree(folder, iferr(cb, function (tree) {
- recalculateMetadata(tree, log.newGroup('pack:' + packageId(pkg)), iferr(cb, function () {
- pack_(tarball, folder, tree, flattenTree(tree), pkg, cb)
+ readPackageTree(folder, pulseTillDone('pack:readTree:' + packageId(pkg), iferr(cb, function (tree) {
+ var recalcGroup = log.newGroup('pack:recalc:' + packageId(pkg))
+ recalculateMetadata(tree, recalcGroup, iferr(cb, function () {
+ recalcGroup.finish()
+ pack_(tarball, folder, tree, pkg, pulseTillDone('pack:' + packageId(pkg), cb))
}))
- }))
+ })))
}
})
}
@@ -61,9 +63,96 @@ function BundledPacker (props) {
}
inherits(BundledPacker, Packer)
+BundledPacker.prototype.applyIgnores = function (entry, partial, entryObj) {
+ if (!entryObj || entryObj.type !== 'Directory') {
+ // package.json files can never be ignored.
+ if (entry === 'package.json') return true
+
+ // readme files should never be ignored.
+ if (entry.match(/^readme(\.[^\.]*)$/i)) return true
+
+ // license files should never be ignored.
+ if (entry.match(/^(license|licence)(\.[^\.]*)?$/i)) return true
+
+ // copyright notice files should never be ignored.
+ if (entry.match(/^(notice)(\.[^\.]*)?$/i)) return true
+
+ // changelogs should never be ignored.
+ if (entry.match(/^(changes|changelog|history)(\.[^\.]*)?$/i)) return true
+ }
+
+ // special rules. see below.
+ if (entry === 'node_modules' && this.packageRoot) return true
+
+ // package.json main file should never be ignored.
+ var mainFile = this.package && this.package.main
+ if (mainFile && path.resolve(this.path, entry) === path.resolve(this.path, mainFile)) return true
+
+ // some files are *never* allowed under any circumstances
+ // (VCS folders, native build cruft, npm cruft, regular cruft)
+ if (entry === '.git' ||
+ entry === 'CVS' ||
+ entry === '.svn' ||
+ entry === '.hg' ||
+ entry === '.lock-wscript' ||
+ entry.match(/^\.wafpickle-[0-9]+$/) ||
+ (this.parent && this.parent.packageRoot && this.basename === 'build' &&
+ entry === 'config.gypi') ||
+ entry === 'npm-debug.log' ||
+ entry === '.npmrc' ||
+ entry.match(/^\..*\.swp$/) ||
+ entry === '.DS_Store' ||
+ entry.match(/^\._/)
+ ) {
+ return false
+ }
+
+ // in a node_modules folder, we only include bundled dependencies
+ // also, prevent packages in node_modules from being affected
+ // by rules set in the containing package, so that
+ // bundles don't get busted.
+ // Also, once in a bundle, everything is installed as-is
+ // To prevent infinite cycles in the case of cyclic deps that are
+ // linked with npm link, even in a bundle, deps are only bundled
+ // if they're not already present at a higher level.
+ if (this.bundleMagic) {
+ // bubbling up. stop here and allow anything the bundled pkg allows
+ if (entry.indexOf('/') !== -1) return true
+
+ // never include the .bin. It's typically full of platform-specific
+ // stuff like symlinks and .cmd files anyway.
+ if (entry === '.bin') return false
+
+ // the package root.
+ var p = this.parent
+ // the package before this one.
+ var pp = p && p.parent
+
+ // if this entry has already been bundled, and is a symlink,
+ // and it is the *same* symlink as this one, then exclude it.
+ if (pp && pp.bundleLinks && this.bundleLinks &&
+ pp.bundleLinks[entry] &&
+ pp.bundleLinks[entry] === this.bundleLinks[entry]) {
+ return false
+ }
+
+ // since it's *not* a symbolic link, if we're *already* in a bundle,
+ // then we should include everything.
+ if (pp && pp.package && pp.basename === 'node_modules') {
+ return true
+ }
+
+ // only include it at this point if it's a bundleDependency
+ return this.isBundled(entry)
+ }
+ // if (this.bundled) return true
+
+ return Packer.prototype.applyIgnores.call(this, entry, partial, entryObj)
+}
+
function nameMatch (name) { return function (other) { return name === moduleName(other) } }
-function pack_ (tarball, folder, tree, flatTree, pkg, cb) {
+function pack_ (tarball, folder, tree, pkg, cb) {
function InstancePacker (props) {
BundledPacker.call(this, props)
}
@@ -81,18 +170,17 @@ function pack_ (tarball, folder, tree, flatTree, pkg, cb) {
if (bd.indexOf(name) !== -1) return true
var pkg = tree.children.filter(nameMatch(name))[0]
if (!pkg) return false
- var requiredBy = union([], pkg.package._requiredBy)
+ var requiredBy = [].concat(pkg.requiredBy)
var seen = {}
while (requiredBy.length) {
- var req = requiredBy.shift()
- if (seen[req]) continue
- seen[req] = true
- var reqPkg = flatTree[req]
+ var reqPkg = requiredBy.shift()
+ if (seen[reqPkg.path]) continue
+ seen[reqPkg.path] = true
if (!reqPkg) continue
if (reqPkg.parent === tree && bd.indexOf(moduleName(reqPkg)) !== -1) {
return true
}
- requiredBy = union(requiredBy, reqPkg.package._requiredBy)
+ requiredBy = union(requiredBy, reqPkg.requiredBy)
}
return false
}
diff --git a/deps/npm/lib/utils/usage.js b/deps/npm/lib/utils/usage.js
index 261d84ee8e..ba069e645e 100644
--- a/deps/npm/lib/utils/usage.js
+++ b/deps/npm/lib/utils/usage.js
@@ -11,7 +11,7 @@ module.exports = function usage (cmd, txt, opt) {
if (opt || post.length > 0) txt += '\n\n'
if (post.length === 1) {
- txt += 'aliase: '
+ txt += 'alias: '
txt += post.join(', ')
} else if (post.length > 1) {
txt += 'aliases: '
diff --git a/deps/npm/lib/version.js b/deps/npm/lib/version.js
index 448c7713ce..e69560fa9a 100644
--- a/deps/npm/lib/version.js
+++ b/deps/npm/lib/version.js
@@ -13,6 +13,7 @@ var git = require('./utils/git.js')
var assert = require('assert')
var lifecycle = require('./utils/lifecycle.js')
var parseJSON = require('./utils/parse-json.js')
+var output = require('./utils/output.js')
version.usage = 'npm version [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]' +
'\n(run in package dir)\n' +
@@ -121,7 +122,7 @@ function readPackage (cb) {
function updatePackage (newVersion, silent, cb_) {
function cb (er) {
- if (!er && !silent) console.log('v' + newVersion)
+ if (!er && !silent) output('v' + newVersion)
cb_(er)
}
@@ -174,7 +175,7 @@ function dump (data, cb) {
if (npm.config.get('json')) v = JSON.stringify(v, null, 2)
- console.log(v)
+ output(v)
cb()
}
diff --git a/deps/npm/lib/view.js b/deps/npm/lib/view.js
index 79c440426b..5bf1cbf248 100644
--- a/deps/npm/lib/view.js
+++ b/deps/npm/lib/view.js
@@ -288,6 +288,10 @@ function printData (data, name, cb) {
// there's one at the beginning
if (/^\s*\n/.test(msg)) msg += '\n'
+ // disable the progress bar entirely, as we can't meaningfully update it if
+ // we may have partial lines printed.
+ log.disableProgress()
+
// print directly to stdout to not unnecessarily add blank lines
process.stdout.write(msg)
diff --git a/deps/npm/lib/visnup.js b/deps/npm/lib/visnup.js
index b0352fd6d0..a61bacb73b 100644
--- a/deps/npm/lib/visnup.js
+++ b/deps/npm/lib/visnup.js
@@ -1,5 +1,6 @@
module.exports = visnup
var npm = require('./npm.js')
+var output = require('./utils/output.js')
var handsomeFace = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 237, 236, 236, 232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
@@ -31,7 +32,7 @@ var handsomeFace = [
function visnup (args, cb) {
handsomeFace.forEach(function (line) {
- console.log(line.map(function (ch) {
+ output(line.map(function (ch) {
return '\u001b[' + (ch ? '48;5;' + ch : ch) + 'm'
}).join(' '))
})
diff --git a/deps/npm/lib/whoami.js b/deps/npm/lib/whoami.js
index feb6fab95a..e8af6595d1 100644
--- a/deps/npm/lib/whoami.js
+++ b/deps/npm/lib/whoami.js
@@ -1,4 +1,5 @@
var npm = require('./npm.js')
+var output = require('./utils/output.js')
module.exports = whoami
@@ -17,7 +18,7 @@ function whoami (args, silent, cb) {
var auth = npm.config.getCredentialsByURI(registry)
if (auth) {
if (auth.username) {
- if (!silent) console.log(auth.username)
+ if (!silent) output(auth.username)
return process.nextTick(cb.bind(this, null, auth.username))
} else if (auth.token) {
return npm.registry.whoami(registry, { auth: auth }, function (er, username) {
@@ -30,7 +31,7 @@ function whoami (args, silent, cb) {
return cb(needNewSession)
}
- if (!silent) console.log(username)
+ if (!silent) output(username)
cb(null, username)
})
}