summaryrefslogtreecommitdiff
path: root/deps/npm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib')
-rw-r--r--deps/npm/lib/cache.js91
-rw-r--r--deps/npm/lib/dedupe.js22
-rw-r--r--deps/npm/lib/install.js4
-rw-r--r--deps/npm/lib/link.js6
-rw-r--r--deps/npm/lib/ls.js3
-rw-r--r--deps/npm/lib/npm.js10
-rw-r--r--deps/npm/lib/outdated.js109
-rw-r--r--deps/npm/lib/prune.js3
-rw-r--r--deps/npm/lib/rebuild.js3
-rw-r--r--deps/npm/lib/shrinkwrap.js17
-rw-r--r--deps/npm/lib/unbuild.js2
-rw-r--r--deps/npm/lib/utils/completion/installed-deep.js8
-rw-r--r--deps/npm/lib/utils/gently-rm.js16
-rw-r--r--deps/npm/lib/utils/tar.js2
-rw-r--r--deps/npm/lib/view.js2
15 files changed, 221 insertions, 77 deletions
diff --git a/deps/npm/lib/cache.js b/deps/npm/lib/cache.js
index cc4546083..3b9a46f69 100644
--- a/deps/npm/lib/cache.js
+++ b/deps/npm/lib/cache.js
@@ -64,7 +64,7 @@ var mkdir = require("mkdirp")
, fetch = require("./utils/fetch.js")
, npm = require("./npm.js")
, fs = require("graceful-fs")
- , rm = require("rimraf")
+ , rm = require("./utils/gently-rm.js")
, readJson = require("read-package-json")
, registry = npm.registry
, log = require("npmlog")
@@ -249,16 +249,48 @@ function add (args, cb) {
var p = url.parse(spec) || {}
log.verbose("parsed url", p)
- // it could be that we got name@http://blah
+ // If there's a /, and it's a path, then install the path.
+ // If not, and there's a @, it could be that we got name@http://blah
// in that case, we will not have a protocol now, but if we
// split and check, we will.
- if (!name && !p.protocol && spec.indexOf("@") !== -1) {
- spec = spec.split("@")
- name = spec.shift()
- spec = spec.join("@")
- return add([name, spec], cb)
+ if (!name && !p.protocol) {
+ if (spec.indexOf("/") !== -1 ||
+ process.platform === "win32" && spec.indexOf("\\") !== -1) {
+ return maybeFile(spec, p, cb)
+ } else if (spec.indexOf("@") !== -1) {
+ return maybeAt(spec, cb)
+ }
}
+ add_(name, spec, p, cb)
+}
+
+function maybeFile (spec, p, cb) {
+ fs.stat(spec, function (er, stat) {
+ if (!er) {
+ // definitely a local thing
+ addLocal(spec, cb)
+ } else if (er && spec.indexOf("@") !== -1) {
+ // bar@baz/loofa
+ maybeAt(spec, cb)
+ } else {
+ // Already know it's not a url, so must be local
+ addLocal(spec, cb)
+ }
+ })
+}
+
+function maybeAt (spec, cb) {
+ var tmp = spec.split("@")
+
+ // split name@2.3.4 only if name is a valid package name,
+ // don't split in case of "./test@example.com/" (local path)
+ var name = tmp.shift()
+ spec = tmp.join("@")
+ return add([name, spec], cb)
+}
+
+function add_ (name, spec, p, cb) {
switch (p.protocol) {
case "http:":
case "https:":
@@ -378,41 +410,40 @@ function addRemoteGit (u, parsed, name, silent, cb_) {
iF.push(cb_)
if (iF.length > 1) return
+ // git is so tricky!
+ // if the path is like ssh://foo:22/some/path then it works, but
+ // it needs the ssh://
+ // If the path is like ssh://foo:some/path then it works, but
+ // only if you remove the ssh://
+ var origUrl = u
+ u = u.replace(/^git\+/, "")
+ .replace(/#.*$/, "")
+
+ // ssh paths that are scp-style urls don't need the ssh://
+ if (parsed.pathname.match(/^\/?:/)) {
+ u = u.replace(/^ssh:\/\//, "")
+ }
+
function cb (er, data) {
unlock(u, function () {
var c
while (c = iF.shift()) c(er, data)
- delete inFlightURLs[u]
+ delete inFlightURLs[origUrl]
})
}
- var p, co // cachePath, git-ref we want to check out
-
lock(u, function (er) {
if (er) return cb(er)
// figure out what we should check out.
var co = parsed.hash && parsed.hash.substr(1) || "master"
- // git is so tricky!
- // if the path is like ssh://foo:22/some/path then it works, but
- // it needs the ssh://
- // If the path is like ssh://foo:some/path then it works, but
- // only if you remove the ssh://
- var origUrl = u
- u = u.replace(/^git\+/, "")
- .replace(/#.*$/, "")
-
- // ssh paths that are scp-style urls don't need the ssh://
- if (parsed.pathname.match(/^\/?:/)) {
- u = u.replace(/^ssh:\/\//, "")
- }
var v = crypto.createHash("sha1").update(u).digest("hex").slice(0, 8)
v = u.replace(/[^a-zA-Z0-9]+/g, '-') + '-' + v
log.verbose("addRemoteGit", [u, co])
- p = path.join(npm.config.get("cache"), "_git-remotes", v)
+ var p = path.join(npm.config.get("cache"), "_git-remotes", v)
checkGitDir(p, u, co, origUrl, silent, function(er, data) {
chmodr(p, npm.modes.file, function(erChmod) {
@@ -1263,9 +1294,15 @@ function lock (u, cb) {
function unlock (u, cb) {
var lf = lockFileName(u)
- if (!myLocks[lf]) return process.nextTick(cb)
- myLocks[lf] = false
- lockFile.unlock(lockFileName(u), cb)
+ , locked = myLocks[lf]
+ if (locked === false) {
+ return process.nextTick(cb)
+ } else if (locked === true) {
+ myLocks[lf] = false
+ lockFile.unlock(lockFileName(u), cb)
+ } else {
+ throw new Error("Attempt to unlock " + u + ", which hasn't been locked")
+ }
}
function needName(er, data) {
diff --git a/deps/npm/lib/dedupe.js b/deps/npm/lib/dedupe.js
index ce161a46c..55823d967 100644
--- a/deps/npm/lib/dedupe.js
+++ b/deps/npm/lib/dedupe.js
@@ -16,7 +16,7 @@ var util = require("util")
var RegClient = require("npm-registry-client")
var npmconf = require("npmconf")
var semver = require("semver")
-var rimraf = require("rimraf")
+var rm = require("./utils/gently-rm.js")
var log = require("npmlog")
var npm = require("./npm.js")
@@ -208,7 +208,7 @@ function installAndRetest (set, filter, dir, unavoidable, silent, cb) {
}, function (er, installed) {
if (er) return cb(er)
- asyncMap(remove, rimraf, function (er) {
+ asyncMap(remove, rm, function (er) {
if (er) return cb(er)
remove.forEach(function (r) {
log.info("rm", r)
@@ -249,10 +249,10 @@ function findVersions (npm, summary, cb) {
var regVersions = er ? [] : Object.keys(data.versions)
var locMatch = bestMatch(versions, ranges)
var regMatch;
- var tag = npm.config.get("tag");
- var distTags = data["dist-tags"];
- if (distTags && distTags[tag] && data.versions[distTags[tag]]) {
- regMatch = distTags[tag]
+ var tag = npm.config.get("tag")
+ var distTag = data["dist-tags"] && data["dist-tags"][tag]
+ if (distTag && data.versions[distTag] && matches(distTag, ranges)) {
+ regMatch = distTag
} else {
regMatch = bestMatch(regVersions, ranges)
}
@@ -262,11 +262,15 @@ function findVersions (npm, summary, cb) {
}, cb)
}
+function matches (version, ranges) {
+ return !ranges.some(function (r) {
+ return !semver.satisfies(version, r, true)
+ })
+}
+
function bestMatch (versions, ranges) {
return versions.filter(function (v) {
- return !ranges.some(function (r) {
- return !semver.satisfies(v, r, true)
- })
+ return matches(v, ranges)
}).sort(semver.compareLoose).pop()
}
diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js
index f0604a9ce..92a490785 100644
--- a/deps/npm/lib/install.js
+++ b/deps/npm/lib/install.js
@@ -187,7 +187,7 @@ function install (args, cb_) {
}
function findPeerInvalid (where, cb) {
- readInstalled(where, log.warn, function (er, data) {
+ readInstalled(where, { log: log.warn }, function (er, data) {
if (er) return cb(er)
cb(null, findPeerInvalid_(data.dependencies, []))
@@ -351,7 +351,7 @@ function save (where, installed, tree, pretty, hasArguments, cb) {
}).reduce(function (set, k) {
var rangeDescriptor = semver.valid(k[1], true) &&
semver.gte(k[1], "0.1.0", true)
- ? "~" : ""
+ ? "^" : ""
set[k[0]] = rangeDescriptor + k[1]
return set
}, {})
diff --git a/deps/npm/lib/link.js b/deps/npm/lib/link.js
index 4ecd64ac3..562846550 100644
--- a/deps/npm/lib/link.js
+++ b/deps/npm/lib/link.js
@@ -8,7 +8,7 @@ var npm = require("./npm.js")
, asyncMap = require("slide").asyncMap
, chain = require("slide").chain
, path = require("path")
- , rm = require("rimraf")
+ , rm = require("./utils/gently-rm.js")
, build = require("./build.js")
module.exports = link
@@ -121,6 +121,10 @@ function linkPkg (folder, cb_) {
return cb_(er, [[d && d._id, target, null, null]])
}
if (er) return cb(er)
+ if (!d.name) {
+ er = new Error("Package must have a name field to be linked")
+ return cb(er)
+ }
var target = path.resolve(npm.globalDir, d.name)
rm(target, function (er) {
if (er) return cb(er)
diff --git a/deps/npm/lib/ls.js b/deps/npm/lib/ls.js
index 194aae635..dc56b0ef2 100644
--- a/deps/npm/lib/ls.js
+++ b/deps/npm/lib/ls.js
@@ -36,7 +36,8 @@ function ls (args, silent, cb) {
})
var depth = npm.config.get("depth")
- readInstalled(dir, depth, log.warn, function (er, data) {
+ var opt = { depth: depth, log: log.warn }
+ readInstalled(dir, opt, function (er, data) {
var bfs = bfsify(data, args)
, lite = getLite(bfs)
diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js
index 858a5e8c4..7b3826290 100644
--- a/deps/npm/lib/npm.js
+++ b/deps/npm/lib/npm.js
@@ -31,7 +31,15 @@ var EventEmitter = require("events").EventEmitter
, chain = slide.chain
, RegClient = require("npm-registry-client")
-npm.config = {loaded: false}
+npm.config = {
+ loaded: false,
+ get: function() {
+ throw new Error('npm.load() required')
+ },
+ set: function() {
+ throw new Error('npm.load() required')
+ }
+}
// /usr/local is often a read-only fs, which is not
// well handled by node or mkdirp. Just double-check
diff --git a/deps/npm/lib/outdated.js b/deps/npm/lib/outdated.js
index 5eb49737f..6ca348726 100644
--- a/deps/npm/lib/outdated.js
+++ b/deps/npm/lib/outdated.js
@@ -9,6 +9,9 @@ Does the following:
If no packages are specified, then run for all installed
packages.
+--parseable creates output like this:
+<fullpath>:<name@wanted>:<name@installed>:<name@latest>
+
*/
module.exports = outdated
@@ -29,6 +32,8 @@ var path = require("path")
, color = require("ansicolors")
, styles = require("ansistyles")
, table = require("text-table")
+ , semver = require("semver")
+ , os = require("os")
function outdated (args, silent, cb) {
if (typeof cb !== "function") cb = silent, silent = false
@@ -37,14 +42,23 @@ function outdated (args, silent, cb) {
if (er || silent) return cb(er, list)
if (npm.config.get("json")) {
console.log(makeJSON(list))
+ } else if (npm.config.get("parseable")) {
+ console.log(makeParseable(list));
} else {
var outList = list.map(makePretty)
- var outTable = [[ styles.underline("Package")
- , styles.underline("Current")
- , styles.underline("Wanted")
- , styles.underline("Latest")
- , styles.underline("Location")
+ var outTable = [[ "Package"
+ , "Current"
+ , "Wanted"
+ , "Latest"
+ , "Location"
]].concat(outList)
+
+ if (npm.color) {
+ outTable[0] = outTable[0].map(function(heading) {
+ return styles.underline(heading)
+ })
+ }
+
var tableOpts = { align: ["l", "r", "r", "r", "l"]
, stringLength: function(s) { return ansiTrim(s).length }
}
@@ -54,37 +68,34 @@ function outdated (args, silent, cb) {
})
}
-// [[ dir, dep, has, want ]]
+// [[ dir, dep, has, want, latest ]]
function makePretty (p) {
var parseable = npm.config.get("parseable")
- , long = npm.config.get("long")
, dep = p[1]
, dir = path.resolve(p[0], "node_modules", dep)
, has = p[2]
, want = p[3]
, latest = p[4]
- // XXX add --json support
- // Should match (more or less) the output of ls --json
-
- if (parseable) {
- var str = dir
- if (npm.config.get("long")) {
- str += ":" + dep + "@" + want
- + ":" + (has ? (dep + "@" + has) : "MISSING")
- }
- return str
- }
-
if (!npm.config.get("global")) {
dir = path.relative(process.cwd(), dir)
}
- return [ has === want ? color.yellow(dep) : color.red(dep)
- , (has || "MISSING")
- , color.green(want)
- , color.magenta(latest)
- , color.brightBlack(dirToPrettyLocation(dir))
- ]
+
+ var columns = [ dep
+ , has || "MISSING"
+ , want
+ , latest
+ , dirToPrettyLocation(dir)
+ ]
+
+ if (npm.color) {
+ columns[0] = color[has === want ? "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
+ }
+
+ return columns
}
function ansiTrim (str) {
@@ -98,6 +109,22 @@ function dirToPrettyLocation (dir) {
.replace(/[[/\\]node_modules[/\\]/g, " > ")
}
+function makeParseable (list) {
+ return list.map(function (p) {
+ var dep = p[1]
+ , dir = path.resolve(p[0], "node_modules", dep)
+ , has = p[2]
+ , want = p[3]
+ , latest = p[4];
+
+ return [ dir
+ , dep + "@" + want
+ , (has ? (dep + "@" + has) : "MISSING")
+ , dep + "@" + latest
+ ].join(":")
+ }).join(os.EOL)
+}
+
function makeJSON (list) {
var out = {}
list.forEach(function (p) {
@@ -222,10 +249,33 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) {
var registry = npm.registry
// search for the latest package
- registry.get(dep + "/latest", function (er, l) {
+ registry.get(dep, function (er, d) {
if (er) return cb()
- // so, we can conceivably update this. find out if we need to.
- cache.add(dep, req, function (er, d) {
+ if (!d || !d['dist-tags'] || !d.versions) return cb()
+ var l = d.versions[d['dist-tags'].latest]
+ if (!l) return cb()
+
+ // set to true if found in doc
+ var found = false
+
+ var r = req
+ if (d['dist-tags'][req])
+ r = d['dist-tags'][req]
+
+ if (semver.validRange(r, true)) {
+ // some kind of semver range.
+ // see if it's in the doc.
+ var vers = Object.keys(d.versions)
+ var v = semver.maxSatisfying(vers, r, true)
+ if (v) {
+ return onCacheAdd(null, d.versions[v])
+ }
+ }
+
+ // We didn't find the version in the doc. See if cache can find it.
+ cache.add(dep, req, onCacheAdd)
+
+ function onCacheAdd(er, d) {
// if this fails, then it means we can't update this thing.
// it's probably a thing that isn't published.
if (er) {
@@ -247,6 +297,7 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) {
doIt(d.version, l.version)
else
skip()
- })
+ }
+
})
}
diff --git a/deps/npm/lib/prune.js b/deps/npm/lib/prune.js
index 0e13da13b..8fa3e5d50 100644
--- a/deps/npm/lib/prune.js
+++ b/deps/npm/lib/prune.js
@@ -21,7 +21,8 @@ function prune (args, cb) {
})
function next() {
- readInstalled(npm.prefix, npm.config.get("depth"), function (er, data) {
+ var opt = { depth: npm.config.get("depth"), dev: npm.config.get("production") }
+ readInstalled(npm.prefix, opt, function (er, data) {
if (er) return cb(er)
prune_(args, data, cb)
})
diff --git a/deps/npm/lib/rebuild.js b/deps/npm/lib/rebuild.js
index 7cea3efff..a156acccf 100644
--- a/deps/npm/lib/rebuild.js
+++ b/deps/npm/lib/rebuild.js
@@ -14,7 +14,8 @@ rebuild.usage = "npm rebuild [<name>[@<version>] [name[@<version>] ...]]"
rebuild.completion = require("./utils/completion/installed-deep.js")
function rebuild (args, cb) {
- readInstalled(npm.prefix, npm.config.get("depth"), function (er, data) {
+ var opt = { depth: npm.config.get("depth") }
+ readInstalled(npm.prefix, opt, function (er, data) {
log.info("readInstalled", typeof data)
if (er) return cb(er)
var set = filter(data, args)
diff --git a/deps/npm/lib/shrinkwrap.js b/deps/npm/lib/shrinkwrap.js
index 14711df26..4aed5964e 100644
--- a/deps/npm/lib/shrinkwrap.js
+++ b/deps/npm/lib/shrinkwrap.js
@@ -38,6 +38,11 @@ function shrinkwrap_ (pkginfo, silent, dev, cb) {
return cb(er)
if (data.devDependencies) {
Object.keys(data.devDependencies).forEach(function (dep) {
+ if (data.dependencies && data.dependencies[dep]) {
+ // do not exclude the dev dependency if it's also listed as a dependency
+ return
+ }
+
log.warn("shrinkwrap", "Excluding devDependency: %s", dep)
delete pkginfo.dependencies[dep]
})
@@ -51,6 +56,9 @@ function shrinkwrap_ (pkginfo, silent, dev, cb) {
function save (pkginfo, silent, cb) {
+ // copy the keys over in a well defined order
+ // because javascript objects serialize arbitrarily
+ pkginfo.dependencies = copyOrder(pkginfo.dependencies)
try {
var swdata = JSON.stringify(pkginfo, null, 2) + "\n"
} catch (er) {
@@ -67,3 +75,12 @@ function save (pkginfo, silent, cb) {
cb(null, pkginfo)
})
}
+
+function copyOrder(obj) {
+ var result = {}
+ var keys = Object.keys(obj).sort()
+ keys.forEach(function (key) {
+ result[key] = obj[key]
+ })
+ return result
+}
diff --git a/deps/npm/lib/unbuild.js b/deps/npm/lib/unbuild.js
index 57688f069..0384a733e 100644
--- a/deps/npm/lib/unbuild.js
+++ b/deps/npm/lib/unbuild.js
@@ -2,7 +2,7 @@ module.exports = unbuild
unbuild.usage = "npm unbuild <folder>\n(this is plumbing)"
var readJson = require("read-package-json")
- , rm = require("rimraf")
+ , rm = require("./utils/gently-rm.js")
, gentlyRm = require("./utils/gently-rm.js")
, npm = require("./npm.js")
, path = require("path")
diff --git a/deps/npm/lib/utils/completion/installed-deep.js b/deps/npm/lib/utils/completion/installed-deep.js
index b49d7bb77..99e320788 100644
--- a/deps/npm/lib/utils/completion/installed-deep.js
+++ b/deps/npm/lib/utils/completion/installed-deep.js
@@ -6,12 +6,16 @@ var npm = require("../../npm.js")
function installedDeep (opts, cb) {
var local
, global
+ , depth = npm.config.get("depth")
+ , opt = { depth: depth }
+
if (npm.config.get("global")) local = [], next()
- else readInstalled(npm.prefix, npm.config.get("depth"), function (er, data) {
+ else readInstalled(npm.prefix, opt, function (er, data) {
local = getNames(data || {})
next()
})
- readInstalled(npm.config.get("prefix"), npm.config.get("depth"), function (er, data) {
+
+ readInstalled(npm.config.get("prefix"), opt, function (er, data) {
global = getNames(data || {})
next()
})
diff --git a/deps/npm/lib/utils/gently-rm.js b/deps/npm/lib/utils/gently-rm.js
index f24309a08..241740fed 100644
--- a/deps/npm/lib/utils/gently-rm.js
+++ b/deps/npm/lib/utils/gently-rm.js
@@ -9,6 +9,22 @@ var rimraf = require("rimraf")
, path = require("path")
function gentlyRm (p, gently, cb) {
+ if (!cb) cb = gently, gently = null
+
+ // never rm the root, prefix, or bin dirs.
+ // just a safety precaution.
+ p = path.resolve(p)
+ if (p === npm.dir ||
+ p === npm.root ||
+ p === npm.bin ||
+ p === npm.prefix ||
+ p === npm.globalDir ||
+ p === npm.globalRoot ||
+ p === npm.globalBin ||
+ p === npm.globalPrefix) {
+ return cb(new Error("May not delete: " + p))
+ }
+
if (npm.config.get("force") || !gently) {
return rimraf(p, cb)
}
diff --git a/deps/npm/lib/utils/tar.js b/deps/npm/lib/utils/tar.js
index 378415eb1..b73c134e4 100644
--- a/deps/npm/lib/utils/tar.js
+++ b/deps/npm/lib/utils/tar.js
@@ -6,7 +6,7 @@ var npm = require("../npm.js")
, path = require("path")
, log = require("npmlog")
, uidNumber = require("uid-number")
- , rm = require("rimraf")
+ , rm = require("./gently-rm.js")
, readJson = require("read-package-json")
, cache = require("../cache.js")
, myUid = process.getuid && process.getuid()
diff --git a/deps/npm/lib/view.js b/deps/npm/lib/view.js
index babd072f7..f7ba5a954 100644
--- a/deps/npm/lib/view.js
+++ b/deps/npm/lib/view.js
@@ -56,7 +56,7 @@ function view (args, silent, cb) {
if (name === ".") return cb(view.usage)
// get the data about this package
- registry.get(name, 600, function (er, data) {
+ registry.get(name, function (er, data) {
if (er) return cb(er)
if (data["dist-tags"].hasOwnProperty(version)) {
version = data["dist-tags"][version]