summaryrefslogtreecommitdiff
path: root/deps/npm/lib/cache.js
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2011-12-13 18:53:02 -0800
committerisaacs <i@izs.me>2011-12-14 14:17:16 -0800
commitbb9316da28feaad035eb2f61aeafc5f1a7a57ae2 (patch)
tree2ee858b80a3819c3c1d10c96932637261f5f0ca2 /deps/npm/lib/cache.js
parentf490934c33bdf134cfb24c6f26975a7e26d64953 (diff)
downloadnode-new-bb9316da28feaad035eb2f61aeafc5f1a7a57ae2.tar.gz
npm 1.1.0-beta-2
Diffstat (limited to 'deps/npm/lib/cache.js')
-rw-r--r--deps/npm/lib/cache.js107
1 files changed, 92 insertions, 15 deletions
diff --git a/deps/npm/lib/cache.js b/deps/npm/lib/cache.js
index 7260ab61a3..a73a874621 100644
--- a/deps/npm/lib/cache.js
+++ b/deps/npm/lib/cache.js
@@ -105,9 +105,7 @@ function read (name, ver, forceBypass, cb) {
return cb(er, data)
}
- if (forceBypass
- && (npm.config.get("force")
- || process.platform === "cygwin")) {
+ if (forceBypass && npm.config.get("force")) {
log.verbose(true, "force found, skipping cache")
return addNamed(name, ver, c)
}
@@ -335,7 +333,7 @@ function addRemoteGit (u, parsed, name, cb_) {
// name@blah thing.
var inFlightNames = {}
function addNamed (name, x, cb_) {
- log.info([name, x], "addNamed")
+ log.verbose([name, x], "addNamed")
var k = name + "@" + x
if (!inFlightNames[k]) inFlightNames[k] = []
var iF = inFlightNames[k]
@@ -368,10 +366,11 @@ function addNameTag (name, tag, cb) {
engineFilter(data)
if (data["dist-tags"] && data["dist-tags"][tag]
&& data.versions[data["dist-tags"][tag]]) {
- return addNameVersion(name, data["dist-tags"][tag], cb)
+ var ver = data["dist-tags"][tag]
+ return addNameVersion(name, ver, data.versions[ver], cb)
}
if (!explicit && Object.keys(data.versions).length) {
- return addNameRange(name, "*", cb)
+ return addNameRange(name, "*", data, cb)
}
return cb(installTargetsError(tag, data))
})
@@ -393,24 +392,84 @@ function engineFilter (data) {
})
}
-function addNameRange (name, range, cb) {
+function addNameRange (name, range, data, cb) {
+ if (typeof cb !== "function") cb = data, data = null
+
range = semver.validRange(range)
if (range === null) return cb(new Error(
"Invalid version range: "+range))
- registry.get(name, function (er, data, json, response) {
+
+ log.silly([name, range, !!data], "name, range, hasData")
+
+ if (data) return next()
+ registry.get(name, function (er, d, json, response) {
if (er) return cb(er)
+ data = d
+ next()
+ })
+
+ function next () {
+ log.silly([name, range, !!data], "name, range, hasData 2")
engineFilter(data)
+
+ if (npm.config.get("registry")) return next_()
+
+ cachedFilter(data, range, function (er) {
+ if (er) return cb(er)
+ if (Object.keys(data.versions).length === 0) {
+ return cb(new Error( "Can't fetch, and not cached: "
+ + data.name + "@" + range))
+ }
+ next_()
+ })
+ }
+
+ function next_ () {
+ log.silly([data.name, Object.keys(data.versions)], "versions")
// if the tagged version satisfies, then use that.
var tagged = data["dist-tags"][npm.config.get("tag")]
if (tagged && data.versions[tagged] && semver.satisfies(tagged, range)) {
- return addNameVersion(name, tagged, cb)
+ return addNameVersion(name, tagged, data.versions[tagged], cb)
}
+
// find the max satisfying version.
var ms = semver.maxSatisfying(Object.keys(data.versions || {}), range)
if (!ms) {
return cb(installTargetsError(range, data))
}
- addNameVersion(name, ms, cb)
+
+ // if we don't have a registry connection, try to see if
+ // there's a cached copy that will be ok.
+ addNameVersion(name, ms, data.versions[ms], cb)
+ }
+}
+
+// filter the versions down based on what's already in cache.
+function cachedFilter (data, range, cb) {
+ log.silly(data.name, "cachedFilter")
+ ls_(data.name, 1, function (er, files) {
+ if (er) return log.er(cb, "Not in cache, can't fetch: "+data.name)(er)
+ files = files.map(function (f) {
+ return path.basename(f.replace(/(\\|\/)$/, ""))
+ }).filter(function (f) {
+ return semver.valid(f) && semver.satisfies(f, range)
+ })
+
+ if (files.length === 0) {
+ return cb(new Error("Not in cache, can't fetch: "+data.name+"@"+range))
+ }
+
+ log.silly([data.name, files], "cached")
+ Object.keys(data.versions).forEach(function (v) {
+ if (files.indexOf(v) === -1) delete data.versions[v]
+ })
+
+ if (Object.keys(data.versions).length === 0) {
+ return log.er(cb, "Not in cache, can't fetch: "+data.name)(er)
+ }
+
+ log.silly([data.name, Object.keys(data.versions)], "filtered")
+ cb(null, data)
})
}
@@ -430,11 +489,26 @@ function installTargetsError (requested, data) {
+ requested + "\n" + targets)
}
-function addNameVersion (name, ver, cb) {
+function addNameVersion (name, ver, data, cb) {
+ if (typeof cb !== "function") cb = data, data = null
+
ver = semver.valid(ver)
if (ver === null) return cb(new Error("Invalid version: "+ver))
- registry.get(name, ver, function (er, data, json, response) {
+
+ var response
+
+ if (data) {
+ response = null
+ return next()
+ }
+ registry.get(name, ver, function (er, d, json, resp) {
if (er) return cb(er)
+ data = d
+ response = resp
+ next()
+ })
+
+ function next () {
deprCheck(data)
var dist = data.dist
@@ -452,8 +526,7 @@ function addNameVersion (name, ver, cb) {
if (!dist.tarball) return cb(new Error(
"No dist.tarball in " + data._id + " package"))
- if (response.statusCode !== 304 || npm.config.get("force")
- || process.platform === "cygwin") {
+ if ((response && response.statusCode !== 304) || npm.config.get("force")) {
return fetchit()
}
@@ -469,6 +542,10 @@ function addNameVersion (name, ver, cb) {
})
function fetchit () {
+ if (!npm.config.get("registry")) {
+ return cb(new Error("Cannot fetch: "+dist.tarball))
+ }
+
// use the same protocol as the registry.
// https registry --> https tarballs.
var tb = url.parse(dist.tarball)
@@ -480,7 +557,7 @@ function addNameVersion (name, ver, cb) {
, name+"-"+ver
, cb )
}
- })
+ }
}
function addLocal (p, name, cb_) {