Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2012-03-29 05:22:24 +0400
committerisaacs <i@izs.me>2012-03-29 05:22:24 +0400
commit37c8f97f58ba0283819ab8e4409ce3d12900974b (patch)
tree3b68c2f33b0e599667cc13abfe2de364b82efe46
parent5002c00d63ed9d1cd80eabc69e7972e4894a1848 (diff)
Update to use mkdirp and chownr modules
-rw-r--r--lib/cache.js42
-rw-r--r--lib/install.js4
-rw-r--r--lib/npm.js6
-rw-r--r--lib/utils/cmd-shim.js2
-rw-r--r--lib/utils/completion/file-completion.js2
-rw-r--r--lib/utils/fetch.js5
-rw-r--r--lib/utils/link.js2
-rw-r--r--lib/utils/mkdir-p.js191
-rw-r--r--lib/utils/npm-registry-client/get.js7
-rw-r--r--lib/utils/tar.js19
10 files changed, 64 insertions, 216 deletions
diff --git a/lib/cache.js b/lib/cache.js
index a57ff308f..b62e82dd1 100644
--- a/lib/cache.js
+++ b/lib/cache.js
@@ -31,7 +31,7 @@ exports.read = read
exports.clean = clean
exports.unpack = unpack
-var mkdir = require("./utils/mkdir-p.js")
+var mkdir = require("mkdirp")
, exec = require("./utils/exec.js")
, fetch = require("./utils/fetch.js")
, npm = require("./npm.js")
@@ -49,6 +49,7 @@ var mkdir = require("./utils/mkdir-p.js")
, tar = require("./utils/tar.js")
, fileCompletion = require("./utils/completion/file-completion.js")
, url = require("url")
+ , chownr = require("chownr")
cache.usage = "npm cache add <tarball file>"
+ "\nnpm cache add <folder>"
@@ -633,7 +634,7 @@ function getCacheStat (cb) {
}
function makeCacheDir (cb) {
- if (!process.getuid) return mkdir(npm.cache, npm.modes.exec, cb)
+ if (!process.getuid) return mkdir(npm.cache, cb)
var uid = +process.getuid()
, gid = +process.getgid()
@@ -644,18 +645,28 @@ function makeCacheDir (cb) {
}
if (uid !== 0 || !process.env.HOME) {
cacheStat = {uid: uid, gid: gid}
- return mkdir(npm.cache, npm.modes.exec, uid, gid, function (er) {
- return cb(er, cacheStat)
- })
+ return mkdir(npm.cache, afterMkdir)
}
+
fs.stat(process.env.HOME, function (er, st) {
if (er) return log.er(cb, "homeless?")(er)
cacheStat = st
log.silly([st.uid, st.gid], "uid, gid for cache dir")
- return mkdir(npm.cache, npm.modes.exec, st.uid, st.gid, function (er) {
+ return mkdir(npm.cache, afterMkdir)
+ })
+
+ function afterMkdir (er, made) {
+ if (er || !cacheStat || isNaN(cacheStat.uid) || isNaN(cacheStat.gid)) {
+ return cb(er, cacheStat)
+ }
+
+ if (!made) return cb(er, cacheStat)
+
+ // ensure that the ownership is correct.
+ chownr(made, cacheStat.uid, cacheStat.gid, function (er) {
return cb(er, cacheStat)
})
- })
+ }
}
@@ -733,9 +744,20 @@ function addLocalDirectory (p, name, cb) {
, tgz = placeDirect ? placed : tmptgz
, doFancyCrap = p.indexOf(npm.tmp) !== 0
&& p.indexOf(npm.cache) !== 0
- tar.pack(tgz, p, data, doFancyCrap, function (er) {
- if (er) return log.er(cb,"couldn't pack "+p+ " to "+tgz)(er)
- addLocalTarball(tgz, name, cb)
+ getCacheStat(function (er, cs) {
+ mkdir(path.dirname(tgz), function (er, made) {
+ if (er) return cb(er)
+ tar.pack(tgz, p, data, doFancyCrap, function (er) {
+ if (er) return log.er(cb,"couldn't pack "+p+ " to "+tgz)(er)
+
+ if (er || !cs || isNaN(cs.uid) || isNaN(cs.gid)) return cb()
+
+ chownr(made || tgz, cs.uid, cs.gid, function (er) {
+ if (er) return cb(er)
+ addLocalTarball(tgz, name, cb)
+ })
+ })
+ })
})
})
}
diff --git a/lib/install.js b/lib/install.js
index 0daf0bc50..4da66d338 100644
--- a/lib/install.js
+++ b/lib/install.js
@@ -67,7 +67,7 @@ var npm = require("./npm.js")
, relativize = require("./utils/relativize.js")
, output
, url = require("url")
- , mkdir = require("./utils/mkdir-p.js")
+ , mkdir = require("mkdirp")
, lifecycle = require("./utils/lifecycle.js")
, archy = require("archy")
@@ -107,7 +107,7 @@ function install (args, cb_) {
})
}
- mkdir(where, function (er) {
+ mkdir(where, function (er, made) {
if (er) return cb(er)
// install dependencies locally by default,
// or install current folder globally
diff --git a/lib/npm.js b/lib/npm.js
index c314b3ec2..456948a29 100644
--- a/lib/npm.js
+++ b/lib/npm.js
@@ -26,7 +26,7 @@ var EventEmitter = require("events").EventEmitter
, semver = require("semver")
, findPrefix = require("./utils/find-prefix.js")
, getUid = require("uid-number")
- , mkdir = require("./utils/mkdir-p.js")
+ , mkdir = require("mkdirp")
, slide = require("slide")
, chain = slide.chain
@@ -286,7 +286,7 @@ function loadPrefix (npm, conf, cb) {
})
// the prefix MUST exist, or else nothing works.
if (!npm.config.get("global")) {
- mkdir(p, npm.modes.exec, null, null, true, next)
+ mkdir(p, next)
} else {
next(er)
}
@@ -299,7 +299,7 @@ function loadPrefix (npm, conf, cb) {
, enumerable : true
})
// the prefix MUST exist, or else nothing works.
- mkdir(gp, npm.modes.exec, null, null, true, next)
+ mkdir(gp, next)
})
var i = 2
diff --git a/lib/utils/cmd-shim.js b/lib/utils/cmd-shim.js
index f53ab3cf8..e24da36f6 100644
--- a/lib/utils/cmd-shim.js
+++ b/lib/utils/cmd-shim.js
@@ -14,7 +14,7 @@ cmdShim.ifExists = cmdShimIfExists
var fs = require("graceful-fs")
, chain = require("slide").chain
- , mkdir = require("./mkdir-p.js")
+ , mkdir = require("mkdirp")
, rm = require("rimraf")
, log = require("./log.js")
, path = require("path")
diff --git a/lib/utils/completion/file-completion.js b/lib/utils/completion/file-completion.js
index 427efefb4..c1c241d68 100644
--- a/lib/utils/completion/file-completion.js
+++ b/lib/utils/completion/file-completion.js
@@ -1,7 +1,7 @@
module.exports = fileCompletion
var find = require("../find.js")
- , mkdir = require("../mkdir-p.js")
+ , mkdir = require("mkdirp")
, path = require("path")
function fileCompletion (root, req, depth, cb) {
diff --git a/lib/utils/fetch.js b/lib/utils/fetch.js
index 935e82039..0ece53cab 100644
--- a/lib/utils/fetch.js
+++ b/lib/utils/fetch.js
@@ -8,7 +8,8 @@ var request = require("request")
, url = require("url")
, log = require("./log.js")
, path = require("path")
- , mkdir = require("./mkdir-p.js")
+ , mkdir = require("mkdirp")
+ , chownr = require("chownr")
, regHost
module.exports = fetch
@@ -16,7 +17,7 @@ module.exports = fetch
function fetch (remote, local, headers, cb) {
if (typeof cb !== "function") cb = headers, headers = {}
log.verbose(local, "fetch to")
- mkdir(path.dirname(local), function (er) {
+ mkdir(path.dirname(local), function (er, made) {
if (er) return cb(er)
fetch_(remote, local, headers, cb)
})
diff --git a/lib/utils/link.js b/lib/utils/link.js
index 918481068..7fa80d5e1 100644
--- a/lib/utils/link.js
+++ b/lib/utils/link.js
@@ -4,7 +4,7 @@ link.ifExists = linkIfExists
var fs = require("graceful-fs")
, chain = require("slide").chain
- , mkdir = require("./mkdir-p.js")
+ , mkdir = require("mkdirp")
, rm = require("./gently-rm.js")
, log = require("./log.js")
, path = require("path")
diff --git a/lib/utils/mkdir-p.js b/lib/utils/mkdir-p.js
deleted file mode 100644
index 2d9b9ee9f..000000000
--- a/lib/utils/mkdir-p.js
+++ /dev/null
@@ -1,191 +0,0 @@
-
-var log = require("./log.js")
- , fs = require("graceful-fs")
- , path = require("path")
- , npm = require("../npm.js")
- , exec = require("./exec.js")
- , uidNumber = require("uid-number")
- , umask = process.umask()
- , umaskOrig = umask
- , addedUmaskExit = false
- , mkdirCache = {}
-
-module.exports = mkdir
-function mkdir (ensure, mode, uid, gid, noChmod, cb_) {
- if (typeof cb_ !== "function") cb_ = noChmod, noChmod = null
- if (typeof cb_ !== "function") cb_ = gid, gid = null
- if (typeof cb_ !== "function") cb_ = uid, uid = null
- if (typeof cb_ !== "function") cb_ = mode, mode = npm.modes.exec
-
- if (mode & umask) {
- log.verbose(mode.toString(8), "umasking from "+umask.toString(8))
- process.umask(umask = 0)
- if (!addedUmaskExit) {
- addedUmaskExit = true
- process.on("exit", function () { process.umask(umask = umaskOrig) })
- }
- }
-
- ensure = path.resolve(ensure).replace(/\/+$/, '')
-
- // mkdir("/") should not do anything, since that always exists.
- if (!ensure
- || ( process.platform === "win32"
- && ensure.match(/^[a-zA-Z]:(\\|\/)?$/))) {
- return cb_()
- }
-
- if (mkdirCache.hasOwnProperty(ensure)) {
- return mkdirCache[ensure].push(cb_)
- }
- mkdirCache[ensure] = [cb_]
-
- function cb (er) {
- var cbs = mkdirCache[ensure]
- delete mkdirCache[ensure]
- cbs.forEach(function (c) { c(er) })
- }
-
- if (uid === null && gid === null) {
- return mkdir_(ensure, mode, uid, gid, noChmod, cb)
- }
-
- uidNumber(uid, gid, function (er, uid, gid) {
- if (er) return cb(er)
- mkdir_(ensure, mode, uid, gid, noChmod, cb)
- })
-}
-
-function mkdir_ (ensure, mode, uid, gid, noChmod, cb) {
- // if it's already a dir, then just check the bits and owner.
- fs.stat(ensure, function (er, s) {
- if (s && s.isDirectory()) {
- // check mode, uid, and gid.
- if ((noChmod || (s.mode & mode) === mode)
- && (typeof uid !== "number" || s.uid === uid)
- && (typeof gid !== "number" || s.gid === gid)) return cb()
- return done(ensure, mode, uid, gid, noChmod, cb)
- }
- return walkDirs(ensure, mode, uid, gid, noChmod, cb)
- })
-}
-
-function done (ensure, mode, uid, gid, noChmod, cb) {
- // now the directory has been created.
- // chown it to the desired uid/gid
- // Don't chown the npm.root dir, though, in case we're
- // in unsafe-perm mode.
- log.verbose("done: "+ensure+" "+mode.toString(8), "mkdir")
-
- // only chmod if noChmod isn't set.
- var d = done_(ensure, mode, uid, gid, cb)
- if (noChmod) return d()
- fs.chmod(ensure, mode, d)
-}
-
-function done_ (ensure, mode, uid, gid, cb) {
- return function (er) {
- if (er
- || ensure === npm.dir
- || typeof uid !== "number"
- || typeof gid !== "number"
- || npm.config.get("unsafe-perm")) return cb(er)
- uid = Math.floor(uid)
- gid = Math.floor(gid)
- fs.chown(ensure, uid, gid, cb)
- }
-}
-
-var pathSplit = process.platform === "win32" ? /\/|\\/ : "/"
-function walkDirs (ensure, mode, uid, gid, noChmod, cb) {
- var dirs = ensure.split(pathSplit)
- , walker = []
- , foundUID = null
- , foundGID = null
-
- // gobble the "/" or C: first
- walker.push(dirs.shift())
-
- // The loop that goes through and stats each dir.
- ;(function S (d) {
- // no more directory steps left.
- if (d === undefined) {
- // do the chown stuff
- return done(ensure, mode, uid, gid, noChmod, cb)
- }
-
- // get the absolute dir for the next piece being stat'd
- walker.push(d)
- var dir = walker.join(path.SPLIT_CHAR)
-
- // stat callback lambda
- fs.stat(dir, function STATCB (er, s) {
- if (er) {
- // the stat failed - directory does not exist.
-
- log.verbose(er.message, "mkdir (expected) error")
-
- // use the same uid/gid as the nearest parent, if not set.
- if (foundUID !== null) uid = foundUID
- if (foundGID !== null) gid = foundGID
-
- // make the directory
- fs.mkdir(dir, mode, function MKDIRCB (er) {
- // since stat and mkdir are done as two separate syscalls,
- // operating on a path rather than a file descriptor, it's
- // possible that the directory didn't exist when we did
- // the stat, but then *did* exist when we go to to the mkdir.
- // If we didn't care about uid/gid, we could just mkdir
- // repeatedly, failing on any error other than "EEXIST".
- if (er && er.message.indexOf("EEXIST") === 0) {
- return fs.stat(dir, STATCB)
- }
-
- // any other kind of error is not saveable.
- if (er) return cb(er)
-
- // at this point, we've just created a new directory successfully.
-
- // if we care about permissions
- if (!npm.config.get("unsafe-perm") // care about permissions
- // specified a uid and gid
- && uid !== null
- && gid !== null ) {
- // set the proper ownership
- return fs.chown(dir, uid, gid, function (er) {
- if (er) return cb(er)
- // attack the next portion of the path.
- S(dirs.shift())
- })
- } else {
- // either we don't care about ownership, or it's already right.
- S(dirs.shift())
- }
- }) // mkdir
-
- } else {
- // the stat succeeded.
- if (s.isDirectory()) {
- // if it's a directory, that's good.
- // if the uid and gid aren't already set, then try to preserve
- // the ownership on up the tree. Things in ~ remain owned by
- // the user, things in / remain owned by root, etc.
- if (uid === null && typeof s.uid === "number") foundUID = s.uid
- if (gid === null && typeof s.gid === "number") foundGID = s.gid
-
- // move onto next portion of path
- S(dirs.shift())
-
- } else {
- // the stat succeeded, but it's not a directory
- log.verbose(dir, "mkdir exists")
- log.silly(s, "stat("+dir+")")
- log.verbose(s.isDirectory(), "isDirectory()")
- cb(new Error("Failed to mkdir "+dir+": File exists"))
- }// if (isDirectory) else
- } // if (stat failed) else
- }) // stat
-
- // start the S function with the first item in the list of directories.
- })(dirs.shift())
-}
diff --git a/lib/utils/npm-registry-client/get.js b/lib/utils/npm-registry-client/get.js
index 49a8b4cc0..e0902f027 100644
--- a/lib/utils/npm-registry-client/get.js
+++ b/lib/utils/npm-registry-client/get.js
@@ -6,8 +6,9 @@ var GET = require("./request.js").GET
, npm = require("../../npm.js")
, path = require("path")
, log = require("../log.js")
- , mkdir = require("../mkdir-p.js")
+ , mkdir = require("mkdirp")
, cacheStat = null
+ , chownr = require("chownr")
function get (project, version, timeout, nofollow, staleOk, cb) {
if (typeof cb !== "function") cb = staleOk, staleOk = false
@@ -173,13 +174,13 @@ function saveToCache (cache, data, saved) {
}
function saveToCache_ (cache, data, uid, gid, saved) {
- mkdir(path.dirname(cache), npm.modes.exec, uid, gid, function (er) {
+ mkdir(path.dirname(cache), function (er, made) {
if (er) return saved()
fs.writeFile(cache, JSON.stringify(data), function (er) {
if (er || uid === null || gid === null) {
return saved()
}
- fs.chown(cache, uid, gid, saved)
+ chownr(made || cache, uid, gid, saved)
})
})
}
diff --git a/lib/utils/tar.js b/lib/utils/tar.js
index 355b988ca..415eb7f9e 100644
--- a/lib/utils/tar.js
+++ b/lib/utils/tar.js
@@ -128,6 +128,13 @@ function gunzTarPerm (tarball, target, dMode, fMode, uid, gid, cb_) {
var extractOpts = { type: "Directory", path: target, strip: 1 }
+ if (process.platform !== "win32" &&
+ typeof uid === "number" &&
+ typeof gid === "number") {
+ extractOpts.uid = uid
+ extractOpts.gid = gid
+ }
+
extractOpts.filter = function () {
// symbolic links are not allowed in packages.
if (this.type.match(/^.*Link$/)) {
@@ -149,7 +156,6 @@ function gunzTarPerm (tarball, target, dMode, fMode, uid, gid, cb_) {
if (c[0] === 0x1F &&
c[1] === 0x8B &&
c[2] === 0x08) {
- var extracter = tar.Extract(extractOpts)
fst
.pipe(zlib.Unzip())
.on("error", log.er(cb, "unzip error "+tarball))
@@ -166,8 +172,17 @@ function gunzTarPerm (tarball, target, dMode, fMode, uid, gid, cb_) {
.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({ path: path.resolve(target, "index.js") }))
+ .pipe(fstream.Writer(jsOpts))
.on("error", log.er(cb, "copy error "+tarball))
.on("close", function () {
var j = path.resolve(target, "package.json")