Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

cache: don't repack unnecessarily from tmp

  • Loading branch information...
commit cb94310a6adb18cb7b881eacb8d67171eda8b744 1 parent a04696f
@isaacs isaacs authored
Showing with 79 additions and 18 deletions.
  1. +79 −18 lib/cache.js
View
97 lib/cache.js
@@ -331,7 +331,8 @@ function fetchAndShaCheck (u, tmp, shasum, cb) {
// Only have a single download action at once for a given url
// additional calls stack the callbacks.
var inFlightURLs = {}
-function addRemoteTarball (u, shasum, name, cb_) {
+function addRemoteTarball (u, shasum, name, version, cb_) {
+ if (typeof cb_ !== "function") cb_ = version, version = ""
if (typeof cb_ !== "function") cb_ = name, name = ""
if (typeof cb_ !== "function") cb_ = shasum, shasum = null
@@ -366,7 +367,7 @@ function addRemoteTarball (u, shasum, name, cb_) {
function done (er, resp, shasum) {
if (er) return cb(er)
- addLocalTarball(tmp, name, shasum, cb)
+ addLocalTarball(tmp, name, version, shasum, cb)
}
}
@@ -853,7 +854,8 @@ function addNameVersion (name, v, data, cb) {
}
return addRemoteTarball( tb
, dist.shasum
- , name+"-"+ver
+ , name
+ , ver
, cb )
}
}
@@ -924,13 +926,15 @@ function maybeGithub (p, name, er, cb) {
}
}
-function addLocalTarball (p, name, shasum, cb_) {
+function addLocalTarball (p, name, version, shasum, cb_) {
if (typeof cb_ !== "function") cb_ = shasum, shasum = null
+ if (typeof cb_ !== "function") cb_ = version, version = ""
if (typeof cb_ !== "function") cb_ = name, name = ""
+
// if it's a tar, and not in place,
// then unzip to .tmp, add the tmp folder, and clean up tmp
if (pathIsInside(p, npm.tmp))
- return addTmpTarball(p, name, shasum, cb_)
+ return addTmpTarball(p, name, version, shasum, cb_)
if (pathIsInside(p, npm.cache)) {
if (path.basename(p) !== "package.tgz") return cb_(new Error(
@@ -962,7 +966,7 @@ function addLocalTarball (p, name, shasum, cb_) {
log.verbose("chmod", tmp, npm.modes.file.toString(8))
fs.chmod(tmp, npm.modes.file, function (er) {
if (er) return cb(er)
- addTmpTarball(tmp, name, shasum, cb)
+ addTmpTarball(tmp, name, null, shasum, cb)
})
})
from.pipe(to)
@@ -1188,6 +1192,10 @@ function addLocalDirectory (p, name, shasum, cb) {
, data.version, "package.tgz" )
, placeDirect = path.basename(p) === "package"
, tgz = placeDirect ? placed : tmptgz
+ , version = data.version
+
+ name = data.name
+
getCacheStat(function (er, cs) {
mkdir(path.dirname(tgz), function (er, made) {
if (er) return cb(er)
@@ -1207,7 +1215,7 @@ function addLocalDirectory (p, name, shasum, cb) {
chownr(made || tgz, cs.uid, cs.gid, function (er) {
if (er) return cb(er)
- addLocalTarball(tgz, name, shasum, cb)
+ addLocalTarball(tgz, name, version, shasum, cb)
})
})
})
@@ -1215,21 +1223,74 @@ function addLocalDirectory (p, name, shasum, cb) {
})
}
-function addTmpTarball (tgz, name, shasum, cb) {
- if (!cb) cb = name, name = ""
+// XXX This is where it should be fixed
+// Right now it's unpacking to a "package" folder, and then
+// adding that local folder, for historical reasons.
+// Instead, unpack to the *cache* folder, and then copy the
+// tgz into place in the cache, so the shasum doesn't change.
+function addTmpTarball (tgz, name, version, shasum, cb) {
+ // Just have a placeholder here so we can move it into place after.
+ var tmp = false
+ if (!version) {
+ tmp = true
+ version = 'tmp_' + crypto.randomBytes(6).toString('hex')
+ }
+ if (!name) {
+ tmp = true
+ name = 'tmp_' + crypto.randomBytes(6).toString('hex')
+ }
+ if (!tmp) {
+ var pdir = path.resolve(npm.cache, name, version, "package")
+ } else {
+ var pdir = path.resolve(npm.cache, name + version + "package")
+ }
+
getCacheStat(function (er, cs) {
if (er) return cb(er)
- var contents = path.dirname(tgz)
- tar.unpack( tgz, path.resolve(contents, "package")
- , null, null
- , cs.uid, cs.gid
- , function (er) {
- if (er) {
- return cb(er)
+ tar.unpack(tgz, pdir, null, null, cs.uid, cs.gid, next)
+ })
+
+ function next (er) {
+ if (er) return cb(er)
+ // it MUST be able to get a version now!
+ var pj = path.resolve(pdir, "package.json")
+ readJson(pj, function (er, data) {
+ if (er) return cb(er)
+ if (version === data.version && name === data.name && !tmp) {
+ addTmpTarball_(tgz, data, name, version, shasum, cb)
+ } else {
+ var old = pdir
+ name = data.name
+ version = data.version
+ pdir = path.resolve(npm.cache, name, version, "package")
+ mkdir(path.dirname(pdir), function(er) {
+ if (er) return cb(er)
+ rm(pdir, function(er) {
+ if (er) return cb(er)
+ fs.rename(old, pdir, function(er) {
+ if (er) return cb(er)
+ rm(old, function(er) {
+ if (er) return cb(er)
+ addTmpTarball_(tgz, data, name, version, shasum, cb)
+ })
+ })
+ })
+ })
}
- addLocalDirectory(path.resolve(contents, "package"), name, shasum, cb)
})
- })
+ }
+}
+
+function addTmpTarball_ (tgz, data, name, version, shasum, cb) {
+ cb = once(cb)
+ var target = path.resolve(npm.cache, name, version, "package.tgz")
+ var read = fs.createReadStream(tgz)
+ var write = fs.createWriteStream(target)
+ read.on("error", cb).pipe(write).on("error", cb).on("close", done)
+
+ function done() {
+ cb(null, data)
+ }
}
function unpack (pkg, ver, unpackTarget, dMode, fMode, uid, gid, cb) {
Please sign in to comment.
Something went wrong with that request. Please try again.