summaryrefslogtreecommitdiff
path: root/deps/npm/lib/utils/tar.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/lib/utils/tar.js')
-rw-r--r--deps/npm/lib/utils/tar.js294
1 files changed, 111 insertions, 183 deletions
diff --git a/deps/npm/lib/utils/tar.js b/deps/npm/lib/utils/tar.js
index 192de7a26a..ede49a121e 100644
--- a/deps/npm/lib/utils/tar.js
+++ b/deps/npm/lib/utils/tar.js
@@ -3,6 +3,7 @@
var npm = require("../npm.js")
, fs = require("graceful-fs")
+ , writeFileAtomic = require("write-file-atomic")
, path = require("path")
, log = require("npmlog")
, uidNumber = require("uid-number")
@@ -15,15 +16,6 @@ var npm = require("../npm.js")
, fstream = require("fstream")
, Packer = require("fstream-npm")
, lifecycle = require("./lifecycle.js")
- , locker = require("./locker.js")
-
-function lock(path, cb) {
- return locker.lock('tar://' + path, cb)
-}
-
-function unlock(path, cb) {
- return locker.unlock('tar://' + path, cb)
-}
if (process.env.SUDO_UID && myUid === 0) {
if (!isNaN(process.env.SUDO_UID)) myUid = +process.env.SUDO_UID
@@ -51,73 +43,40 @@ function pack (tarball, folder, pkg, dfc, cb) {
}
}
-function pack_ (tarball, folder, pkg, cb_) {
- var tarballLock = false
- , folderLock = false
-
- function cb (er) {
- if (folderLock)
- unlock(folder, function() {
- folderLock = false
- cb(er)
- })
- else if (tarballLock)
- unlock(tarball, function() {
- tarballLock = false
- cb(er)
- })
- else
- cb_(er)
- }
-
- lock(folder, function(er) {
- if (er) return cb(er)
- folderLock = true
- next()
- })
-
- lock(tarball, function (er) {
- if (er) return cb(er)
- tarballLock = true
- next()
- })
-
- function next () {
- if (!tarballLock || !folderLock) return
-
- new Packer({ path: folder, type: "Directory", isDirectory: true })
- .on("error", function (er) {
- if (er) log.error("tar pack", "Error reading " + folder)
- return cb(er)
- })
+function pack_ (tarball, folder, pkg, cb) {
+ new Packer({ path: folder, type: "Directory", isDirectory: true })
+ .on("error", function (er) {
+ if (er) log.error("tar pack", "Error reading " + folder)
+ return cb(er)
+ })
- // By default, npm includes some proprietary attributes in the
- // package tarball. This is sane, and allowed by the spec.
- // However, npm *itself* excludes these from its own package,
- // so that it can be more easily bootstrapped using old and
- // non-compliant tar implementations.
- .pipe(tar.Pack({ noProprietary: !npm.config.get("proprietary-attribs") }))
- .on("error", function (er) {
- if (er) log.error("tar.pack", "tar creation error", tarball)
- cb(er)
- })
- .pipe(zlib.Gzip())
- .on("error", function (er) {
- if (er) log.error("tar.pack", "gzip error "+tarball)
- cb(er)
- })
- .pipe(fstream.Writer({ type: "File", path: tarball }))
- .on("error", function (er) {
- if (er) log.error("tar.pack", "Could not write "+tarball)
- cb(er)
- })
- .on("close", cb)
- }
+ // By default, npm includes some proprietary attributes in the
+ // package tarball. This is sane, and allowed by the spec.
+ // However, npm *itself* excludes these from its own package,
+ // so that it can be more easily bootstrapped using old and
+ // non-compliant tar implementations.
+ .pipe(tar.Pack({ noProprietary: !npm.config.get("proprietary-attribs") }))
+ .on("error", function (er) {
+ if (er) log.error("tar.pack", "tar creation error", tarball)
+ cb(er)
+ })
+ .pipe(zlib.Gzip())
+ .on("error", function (er) {
+ if (er) log.error("tar.pack", "gzip error "+tarball)
+ cb(er)
+ })
+ .pipe(fstream.Writer({ type: "File", path: tarball }))
+ .on("error", function (er) {
+ if (er) log.error("tar.pack", "Could not write "+tarball)
+ cb(er)
+ })
+ .on("close", cb)
}
function unpack (tarball, unpackTarget, dMode, fMode, uid, gid, cb) {
- log.verbose("tar unpack", tarball)
+ log.verbose("tar", "unpack", tarball)
+ log.verbose("tar", "unpacking to", unpackTarget)
if (typeof cb !== "function") cb = gid, gid = null
if (typeof cb !== "function") cb = uid, uid = null
if (typeof cb !== "function") cb = fMode, fMode = npm.modes.file
@@ -129,52 +88,9 @@ function unpack (tarball, unpackTarget, dMode, fMode, uid, gid, cb) {
})
}
-function unpack_ ( tarball, unpackTarget, dMode, fMode, uid, gid, cb_ ) {
- var parent = path.dirname(unpackTarget)
- , base = path.basename(unpackTarget)
- , folderLock
- , tarballLock
-
- function cb (er) {
- if (folderLock)
- unlock(unpackTarget, function() {
- folderLock = false
- cb(er)
- })
- else if (tarballLock)
- unlock(tarball, function() {
- tarballLock = false
- cb(er)
- })
- else
- cb_(er)
- }
-
- lock(unpackTarget, function (er) {
- if (er) return cb(er)
- folderLock = true
- next()
- })
-
- lock(tarball, function (er) {
+function unpack_ ( tarball, unpackTarget, dMode, fMode, uid, gid, cb ) {
+ rm(unpackTarget, function (er) {
if (er) return cb(er)
- tarballLock = true
- next()
- })
-
- function next() {
- if (!tarballLock || !folderLock) return
- rmGunz()
- }
-
- function rmGunz () {
- rm(unpackTarget, function (er) {
- if (er) return cb(er)
- gtp()
- })
- }
-
- function gtp () {
// gzip {tarball} --decompress --stdout \
// | tar -mvxpf - --strip-components=1 -C {unpackTarget}
gunzTarPerm( tarball, unpackTarget
@@ -184,7 +100,7 @@ function unpack_ ( tarball, unpackTarget, dMode, fMode, uid, gid, cb_ ) {
if (er) return cb(er)
readJson(path.resolve(folder, "package.json"), cb)
})
- }
+ })
}
@@ -202,6 +118,17 @@ function gunzTarPerm (tarball, target, dMode, fMode, uid, gid, cb_) {
var fst = fs.createReadStream(tarball)
+ fst.on("open", function (fd) {
+ fs.fstat(fd, function (er, st) {
+ if (er) return fst.emit("error", er)
+ if (st.size === 0) {
+ er = new Error("0-byte tarball\n" +
+ "Please run `npm cache clean`")
+ fst.emit("error", er)
+ }
+ })
+ })
+
// figure out who we're supposed to be, if we're not pretending
// to be a specific user.
if (npm.config.get("unsafe-perm") && process.platform !== "win32") {
@@ -275,73 +202,74 @@ function gunzTarPerm (tarball, target, dMode, fMode, uid, gid, cb_) {
}
- fst.on("error", function (er) {
- if (er) log.error("tar.unpack", "error reading "+tarball)
- cb(er)
- })
- fst.on("data", function OD (c) {
- // detect what it is.
- // Then, depending on that, we'll figure out whether it's
- // a single-file module, gzipped tarball, or naked tarball.
- // gzipped files all start with 1f8b08
- if (c[0] === 0x1F &&
- c[1] === 0x8B &&
- c[2] === 0x08) {
- fst
- .pipe(zlib.Unzip())
- .on("error", function (er) {
- if (er) log.error("tar.unpack", "unzip error "+tarball)
- cb(er)
- })
- .pipe(tar.Extract(extractOpts))
- .on("entry", extractEntry)
- .on("error", function (er) {
- if (er) log.error("tar.unpack", "untar error "+tarball)
- cb(er)
- })
- .on("close", cb)
- } else if (c.toString().match(/^package\//) ||
- c.toString().match(/^pax_global_header/)) {
- // naked tar
- fst
- .pipe(tar.Extract(extractOpts))
- .on("entry", extractEntry)
- .on("error", function (er) {
- if (er) log.error("tar.unpack", "untar error "+tarball)
- cb(er)
- })
- .on("close", cb)
- } else {
- // naked js file
- var jsOpts = { path: path.resolve(target, "index.js") }
-
- if (process.platform !== "win32" &&
- typeof uid === "number" &&
- typeof gid === "number") {
- jsOpts.uid = uid
- jsOpts.gid = gid
- }
+ fst
+ .on("error", function (er) {
+ if (er) log.error("tar.unpack", "error reading "+tarball)
+ cb(er)
+ })
+ .on("data", function OD (c) {
+ // detect what it is.
+ // Then, depending on that, we'll figure out whether it's
+ // a single-file module, gzipped tarball, or naked tarball.
+ // gzipped files all start with 1f8b08
+ if (c[0] === 0x1F &&
+ c[1] === 0x8B &&
+ c[2] === 0x08) {
+ fst
+ .pipe(zlib.Unzip())
+ .on("error", function (er) {
+ if (er) log.error("tar.unpack", "unzip error "+tarball)
+ cb(er)
+ })
+ .pipe(tar.Extract(extractOpts))
+ .on("entry", extractEntry)
+ .on("error", function (er) {
+ if (er) log.error("tar.unpack", "untar error "+tarball)
+ cb(er)
+ })
+ .on("close", cb)
+ } else if (c.toString().match(/^package\//) ||
+ c.toString().match(/^pax_global_header/)) {
+ // naked tar
+ fst
+ .pipe(tar.Extract(extractOpts))
+ .on("entry", extractEntry)
+ .on("error", function (er) {
+ if (er) log.error("tar.unpack", "untar error "+tarball)
+ cb(er)
+ })
+ .on("close", cb)
+ } else {
+ // naked js file
+ var jsOpts = { path: path.resolve(target, "index.js") }
+
+ if (process.platform !== "win32" &&
+ typeof uid === "number" &&
+ typeof gid === "number") {
+ jsOpts.uid = uid
+ jsOpts.gid = gid
+ }
- fst
- .pipe(fstream.Writer(jsOpts))
- .on("error", function (er) {
- if (er) log.error("tar.unpack", "copy error "+tarball)
- cb(er)
- })
- .on("close", function () {
- var j = path.resolve(target, "package.json")
- readJson(j, function (er, d) {
- if (er) {
- log.error("not a package", tarball)
- return cb(er)
- }
- fs.writeFile(j, JSON.stringify(d) + "\n", cb)
+ fst
+ .pipe(fstream.Writer(jsOpts))
+ .on("error", function (er) {
+ if (er) log.error("tar.unpack", "copy error "+tarball)
+ cb(er)
})
- })
- }
+ .on("close", function () {
+ var j = path.resolve(target, "package.json")
+ readJson(j, function (er, d) {
+ if (er) {
+ log.error("not a package", tarball)
+ return cb(er)
+ }
+ writeFileAtomic(j, JSON.stringify(d) + "\n", cb)
+ })
+ })
+ }
- // now un-hook, and re-emit the chunk
- fst.removeListener("data", OD)
- fst.emit("data", c)
- })
+ // now un-hook, and re-emit the chunk
+ fst.removeListener("data", OD)
+ fst.emit("data", c)
+ })
}