Large diffs are not rendered by default.

@@ -0,0 +1,223 @@
var mkdir = require("mkdirp")
, assert = require("assert")
, fs = require("graceful-fs")
, readJson = require("read-package-json")
, log = require("npmlog")
, path = require("path")
, sha = require("sha")
, npm = require("../npm.js")
, tar = require("../utils/tar.js")
, pathIsInside = require("path-is-inside")
, locker = require("../utils/locker.js")
, lock = locker.lock
, unlock = locker.unlock
, getCacheStat = require("./get-stat.js")
, chownr = require("chownr")
, inflight = require("inflight")
, once = require("once")

module.exports = addLocalTarball

function addLocalTarball (p, pkgData, shasum, cb_) {
assert(typeof p === "string", "must have path")
assert(typeof cb_ === "function", "must have callback")

if (!pkgData) pkgData = {}
var name = pkgData.name || ""

// If we don't have a shasum yet, then get the shasum now.
if (!shasum) {
return sha.get(p, function (er, shasum) {
if (er) return cb_(er)
addLocalTarball(p, pkgData, shasum, cb_)
})
}

// 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, pkgData, shasum, cb_)

if (pathIsInside(p, npm.cache)) {
if (path.basename(p) !== "package.tgz") return cb_(new Error(
"Not a valid cache tarball name: "+p))
return addPlacedTarball(p, pkgData, shasum, cb_)
}

function cb (er, data) {
if (data) {
data._resolved = p
data._shasum = data._shasum || shasum
}
return cb_(er, data)
}

// just copy it over and then add the temp tarball file.
var tmp = path.join(npm.tmp, name + Date.now()
+ "-" + Math.random(), "tmp.tgz")
mkdir(path.dirname(tmp), function (er) {
if (er) return cb(er)
var from = fs.createReadStream(p)
, to = fs.createWriteStream(tmp)
, errState = null
function errHandler (er) {
if (errState) return
return cb(errState = er)
}
from.on("error", errHandler)
to.on("error", errHandler)
to.on("close", function () {
if (errState) return
log.verbose("chmod", tmp, npm.modes.file.toString(8))
fs.chmod(tmp, npm.modes.file, function (er) {
if (er) return cb(er)
addTmpTarball(tmp, pkgData, shasum, cb)
})
})
from.pipe(to)
})
}

function addPlacedTarball (p, pkgData, shasum, cb) {
assert(pkgData, "should have package data by now")
assert(typeof cb === "function", "cb function required")

getCacheStat(function (er, cs) {
if (er) return cb(er)
return addPlacedTarball_(p, pkgData, cs.uid, cs.gid, shasum, cb)
})
}

function addPlacedTarball_ (p, pkgData, uid, gid, resolvedSum, cb) {
// now we know it's in place already as .cache/name/ver/package.tgz
var name = pkgData.name
, version = pkgData.version
, folder = path.join(npm.cache, name, version, "package")

// First, make sure we have the shasum, if we don't already.
if (!resolvedSum) {
sha.get(p, function (er, shasum) {
if (er) return cb(er)
addPlacedTarball_(p, pkgData, uid, gid, shasum, cb)
})
return
}

lock(folder, function (er) {
if (er) return cb(er)

// async try/finally
var originalCb = cb
cb = function (er, data) {
unlock(folder, function (er2) {
return originalCb(er || er2, data)
})
}

mkdir(folder, function (er) {
if (er) return cb(er)
var pj = path.join(folder, "package.json")
var json = JSON.stringify(pkgData, null, 2)
fs.writeFile(pj, json, "utf8", function (er) {
cb(er, pkgData)
})
})
})
}

function addTmpTarball (tgz, pkgData, shasum, cb) {
assert(typeof cb === "function", "must have callback function")
assert(shasum, "should have shasum by now")

cb = inflight("addTmpTarball:" + tgz, cb)
if (!cb) return

// we already have the package info, so just move into place
if (pkgData && pkgData.name && pkgData.version) {
return addTmpTarball_(tgz, pkgData, shasum, cb)
}

// This is a tarball we probably downloaded from the internet.
// The shasum's already been checked, but we haven't ever had
// a peek inside, so we unpack it here just to make sure it is
// what it says it is.
// Note: we might not have any clue what we think it is, for
// example if the user just did `npm install ./foo.tgz`

var target = tgz + "-unpack"
getCacheStat(function (er, cs) {
tar.unpack(tgz, target, null, null, cs.uid, cs.gid, next)
})

function next (er) {
if (er) return cb(er)
var pj = path.join(target, "package.json")
readJson(pj, function (er, data) {
// XXX dry with similar stanza in add-local.js
er = needName(er, data)
er = needVersion(er, data)
// check that this is what we expected.
if (!er && pkgData.name && pkgData.name !== data.name) {
er = new Error( "Invalid Package: expected "
+ pkgData.name + " but found "
+ data.name )
}

if (!er && pkgData.version && pkgData.version !== data.version) {
er = new Error( "Invalid Package: expected "
+ pkgData.name + "@" + pkgData.version
+ " but found "
+ data.name + "@" + data.version )
}

if (er) return cb(er)

addTmpTarball_(tgz, data, shasum, cb)
})
}
}

function addTmpTarball_ (tgz, data, shasum, cb) {
assert(typeof cb === "function", "must have callback function")
cb = once(cb)

var name = data.name
var version = data.version
assert(name, "should have package name by now")
assert(version, "should have package version by now")

var root = path.resolve(npm.cache, name, version)
var pkg = path.resolve(root, "package")
var target = path.resolve(root, "package.tgz")
getCacheStat(function (er, cs) {
if (er) return cb(er)
mkdir(pkg, function (er) {
if (er) return cb(er)
var read = fs.createReadStream(tgz)
var write = fs.createWriteStream(target)
var fin = cs.uid && cs.gid ? chown : done
read.on("error", cb).pipe(write).on("error", cb).on("close", fin)
})

function chown () {
chownr(root, cs.uid, cs.gid, done)
}
})

function done() {
data._shasum = data._shasum || shasum
cb(null, data)
}
}

function needName(er, data) {
return er ? er
: (data && !data.name) ? new Error("No name provided")
: null
}

function needVersion(er, data) {
return er ? er
: (data && !data.version) ? new Error("No version provided")
: null
}
@@ -0,0 +1,146 @@
var fs = require("graceful-fs")
, assert = require("assert")
, path = require("path")
, mkdir = require("mkdirp")
, chownr = require("chownr")
, pathIsInside = require("path-is-inside")
, readJson = require("read-package-json")
, log = require("npmlog")
, npm = require("../npm.js")
, tar = require("../utils/tar.js")
, deprCheck = require("../utils/depr-check.js")
, locker = require("../utils/locker.js")
, lock = locker.lock
, unlock = locker.unlock
, getCacheStat = require("./get-stat.js")
, addNamed = require("./add-named.js")
, addLocalTarball = require("./add-local-tarball.js")
, maybeGithub = require("./maybe-github.js")
, sha = require("sha")

module.exports = addLocal

function addLocal (p, pkgData, cb_) {
assert(typeof p === "string", "must have path")
assert(typeof cb === "function", "must have callback")

pkgData = pkgData || {}

function cb (er, data) {
unlock(p, function () {
if (er) {
// if it doesn't have a / in it, it might be a
// remote thing.
if (p.indexOf("/") === -1 && p.charAt(0) !== "."
&& (process.platform !== "win32" || p.indexOf("\\") === -1)) {
return addNamed(p, "", null, cb_)
}
log.error("addLocal", "Could not install %s", p)
return cb_(er)
}
if (data && !data._fromGithub) data._from = p
return cb_(er, data)
})
}

lock(p, function (er) {
if (er) return cb(er)
// figure out if this is a folder or file.
fs.stat(p, function (er, s) {
if (er) {
// might be username/project
// in that case, try it as a github url.
if (p.split("/").length === 2) {
return maybeGithub(p, er, cb)
}
return cb(er)
}
if (s.isDirectory()) addLocalDirectory(p, pkgData, null, cb)
else addLocalTarball(p, pkgData, null, cb)
})
})
}

// At this point, if shasum is set, it's something that we've already
// read and checked. Just stashing it in the data at this point.
function addLocalDirectory (p, pkgData, shasum, cb) {
assert(pkgData, "must pass package data")
assert(typeof cb === "function", "must have callback")

// if it's a folder, then read the package.json,
// tar it to the proper place, and add the cache tar
if (pathIsInside(p, npm.cache)) return cb(new Error(
"Adding a cache directory to the cache will make the world implode."))

readJson(path.join(p, "package.json"), false, function (er, data) {
er = needName(er, data)
er = needVersion(er, data)

// check that this is what we expected.
if (!er && pkgData.name && pkgData.name !== data.name) {
er = new Error( "Invalid Package: expected "
+ pkgData.name + " but found "
+ data.name )
}

if (!er && pkgData.version && pkgData.version !== data.version) {
er = new Error( "Invalid Package: expected "
+ pkgData.name + "@" + pkgData.version
+ " but found "
+ data.name + "@" + data.version )
}

if (er) return cb(er)
deprCheck(data)

// pack to {cache}/name/ver/package.tgz
var croot = path.resolve(npm.cache, data.name, data.version)
var tgz = path.resolve(croot, "package.tgz")
var pj = path.resolve(croot, "package/package.json")
getCacheStat(function (er, cs) {
mkdir(path.dirname(pj), function (er, made) {
if (er) return cb(er)
var fancy = !pathIsInside(p, npm.tmp)
tar.pack(tgz, p, data, fancy, function (er) {
if (er) {
log.error( "addLocalDirectory", "Could not pack %j to %j"
, p, tgz )
return cb(er)
}

if (!cs || isNaN(cs.uid) || isNaN(cs.gid)) next()

chownr(made || tgz, cs.uid, cs.gid, next)
})
})
})

function next (er) {
if (er) return cb(er)
// if we have the shasum already, just add it
if (shasum) {
return addLocalTarball(tgz, data, shasum, cb)
} else {
sha.get(tgz, function (er, shasum) {
if (er) {
return cb(er)
}
data._shasum = shasum
return addLocalTarball(tgz, data, shasum, cb)
})
}
}
})
}

function needName(er, data) {
return er ? er
: (data && !data.name) ? new Error("No name provided")
: null
}

function needVersion(er, data) {
return er ? er
: (data && !data.version) ? new Error("No version provided")
: null
}
@@ -0,0 +1,275 @@
var path = require("path")
, assert = require("assert")
, fs = require("graceful-fs")
, http = require("http")
, log = require("npmlog")
, semver = require("semver")
, readJson = require("read-package-json")
, url = require("url")
, npm = require("../npm.js")
, registry = npm.registry
, deprCheck = require("../utils/depr-check.js")
, inflight = require("inflight")
, locker = require("../utils/locker.js")
, lock = locker.lock
, unlock = locker.unlock
, maybeGithub = require("./maybe-github.js")
, addRemoteTarball = require("./add-remote-tarball.js")


module.exports = addNamed

var NAME_PREFIX = "addName:"
function addNamed (name, version, data, cb_) {
assert(typeof name === "string", "must have module name")
assert(typeof cb_ === "function", "must have callback")

log.verbose("addNamed", [name, version])

var key = name + "@" + version
function cb (er, data) {
if (data && !data._fromGithub) data._from = key
unlock(key, function () { cb_(er, data) })
}

cb_ = inflight(NAME_PREFIX + key, cb_)

if (!cb_) return

log.verbose("addNamed", [semver.valid(version), semver.validRange(version)])
lock(key, function (er) {
if (er) return cb(er)

var fn = ( semver.valid(version, true) ? addNameVersion
: semver.validRange(version, true) ? addNameRange
: addNameTag
)
fn(name, version, data, cb)
})
}

function addNameTag (name, tag, data, cb_) {
log.info("addNameTag", [name, tag])
var explicit = true
if (!tag) {
explicit = false
tag = npm.config.get("tag")
}

function cb(er, data) {
// might be username/project
// in that case, try it as a github url.
if (er && tag.split("/").length === 2) {
return maybeGithub(tag, er, cb_)
}
return cb_(er, data)
}

registry.get(name, function (er, data, json, resp) {
if (!er) {
er = errorResponse(name, resp)
}
if (er) return cb(er)
engineFilter(data)
if (data["dist-tags"] && data["dist-tags"][tag]
&& data.versions[data["dist-tags"][tag]]) {
var ver = data["dist-tags"][tag]
return addNamed(name, ver, data.versions[ver], cb)
}
if (!explicit && Object.keys(data.versions).length) {
return addNamed(name, "*", data, cb)
}

er = installTargetsError(tag, data)
return cb(er)
})
}

function engineFilter (data) {
var npmv = npm.version
, nodev = npm.config.get("node-version")
, strict = npm.config.get("engine-strict")

if (!nodev || npm.config.get("force")) return data

Object.keys(data.versions || {}).forEach(function (v) {
var eng = data.versions[v].engines
if (!eng) return
if (!strict && !data.versions[v].engineStrict) return
if (eng.node && !semver.satisfies(nodev, eng.node, true)
|| eng.npm && !semver.satisfies(npmv, eng.npm, true)) {
delete data.versions[v]
}
})
}

function addNameVersion (name, v, data, cb) {
var ver = semver.valid(v, true)
if (!ver) return cb(new Error("Invalid version: "+v))

var response

if (data) {
response = null
return next()
}
registry.get(name, function (er, d, json, resp) {
if (!er) {
er = errorResponse(name, resp)
}
if (er) return cb(er)
data = d && d.versions[ver]
if (!data) {
er = new Error('version not found: ' + name + '@' + ver)
er.package = name
er.statusCode = 404
return cb(er)
}
response = resp
next()
})

function next () {
deprCheck(data)
var dist = data.dist

if (!dist) return cb(new Error("No dist in "+data._id+" package"))

if (!dist.tarball) return cb(new Error(
"No dist.tarball in " + data._id + " package"))

if ((response && response.statusCode !== 304) || npm.config.get("force")) {
return fetchit()
}

// we got cached data, so let's see if we have a tarball.
var pkgroot = path.join(npm.cache, name, ver)
var pkgtgz = path.join(pkgroot, "package.tgz")
var pkgjson = path.join(pkgroot, "package", "package.json")
fs.stat(pkgtgz, function (er) {
if (!er) {
readJson(pkgjson, function (er, data) {
er = needName(er, data)
er = needVersion(er, data)
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR")
return cb(er)
if (er) return fetchit()
return cb(null, data)
})
} else return fetchit()
})

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, but
// only if they're the same hostname, or else
// detached tarballs may not work.
var tb = url.parse(dist.tarball)
var rp = url.parse(npm.config.get("registry"))
if (tb.hostname === rp.hostname
&& tb.protocol !== rp.protocol) {
tb.protocol = url.parse(npm.config.get("registry")).protocol
delete tb.href
}
tb = url.format(tb)

// only add non-shasum'ed packages if --forced.
// only ancient things would lack this for good reasons nowadays.
if (!dist.shasum && !npm.config.get("force")) {
return cb(new Error("package lacks shasum: " + data._id))
}
return addRemoteTarball(tb, data, dist.shasum, cb)
}
}
}

function addNameRange (name, range, data, cb) {
range = semver.validRange(range, true)
if (range === null) return cb(new Error(
"Invalid version range: "+range))

log.silly("addNameRange", {name:name, range:range, hasData:!!data})

if (data) return next()
registry.get(name, function (er, d, json, resp) {
if (!er) {
er = errorResponse(name, resp)
}
if (er) return cb(er)
data = d
next()
})

function next () {
log.silly( "addNameRange", "number 2"
, {name:name, range:range, hasData:!!data})
engineFilter(data)

log.silly("addNameRange", "versions"
, [data.name, Object.keys(data.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, true)) {
return addNamed(name, tagged, data.versions[tagged], cb)
}

// find the max satisfying version.
var versions = Object.keys(data.versions || {})
var ms = semver.maxSatisfying(versions, range, true)
if (!ms) {
return cb(installTargetsError(range, data))
}

// if we don't have a registry connection, try to see if
// there's a cached copy that will be ok.
addNamed(name, ms, data.versions[ms], cb)
}
}

function installTargetsError (requested, data) {
var targets = Object.keys(data["dist-tags"]).filter(function (f) {
return (data.versions || {}).hasOwnProperty(f)
}).concat(Object.keys(data.versions || {}))

requested = data.name + (requested ? "@'" + requested + "'" : "")

targets = targets.length
? "Valid install targets:\n" + JSON.stringify(targets) + "\n"
: "No valid targets found.\n"
+ "Perhaps not compatible with your version of node?"

var er = new Error( "No compatible version found: "
+ requested + "\n" + targets)
er.code = "ETARGET"
return er
}

function errorResponse (name, response) {
var er
if (response.statusCode >= 400) {
er = new Error(http.STATUS_CODES[response.statusCode])
er.statusCode = response.statusCode
er.code = "E" + er.statusCode
er.pkgid = name
}
return er
}

function needName(er, data) {
return er ? er
: (data && !data.name) ? new Error("No name provided")
: null
}

function needVersion(er, data) {
return er ? er
: (data && !data.version) ? new Error("No version provided")
: null
}
@@ -0,0 +1,285 @@
var mkdir = require("mkdirp")
, assert = require("assert")
, spawn = require("child_process").spawn
, exec = require("child_process").execFile
, once = require("once")
, fs = require("graceful-fs")
, log = require("npmlog")
, path = require("path")
, url = require("url")
, chownr = require("chownr")
, zlib = require("zlib")
, which = require("which")
, crypto = require("crypto")
, chmodr = require("chmodr")
, npm = require("../npm.js")
, rm = require("../utils/gently-rm.js")
, inflight = require("inflight")
, locker = require("../utils/locker.js")
, lock = locker.lock
, unlock = locker.unlock
, getCacheStat = require("./get-stat.js")
, addLocalTarball = require("./add-local-tarball.js")


// 1. cacheDir = path.join(cache,'_git-remotes',sha1(u))
// 2. checkGitDir(cacheDir) ? 4. : 3. (rm cacheDir if necessary)
// 3. git clone --mirror u cacheDir
// 4. cd cacheDir && git fetch -a origin
// 5. git archive /tmp/random.tgz
// 6. addLocalTarball(/tmp/random.tgz) <gitref> --format=tar --prefix=package/
// silent flag is used if this should error quietly
module.exports = function addRemoteGit (u, parsed, silent, cb_) {
assert(typeof u === "string", "must have git URL")
assert(typeof parsed === "object", "must have parsed query")
assert(typeof cb_ === "function", "must have callback")

function cb (er, data) {
unlock(u, function () { cb_(er, data) })
}

cb_ = inflight(u, cb_)

if (!cb_) 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:\/\//, "")
}

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"

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])

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) {
if (er) return cb(er, data)
return cb(erChmod, data)
})
})
})
}

function checkGitDir (p, u, co, origUrl, silent, cb) {
fs.stat(p, function (er, s) {
if (er) return cloneGitRemote(p, u, co, origUrl, silent, cb)
if (!s.isDirectory()) return rm(p, function (er){
if (er) return cb(er)
cloneGitRemote(p, u, co, origUrl, silent, cb)
})

var git = npm.config.get("git")
var args = [ "config", "--get", "remote.origin.url" ]
var env = gitEnv()

// check for git
which(git, function (err) {
if (err) {
err.code = "ENOGIT"
return cb(err)
}
exec(git, args, {cwd: p, env: env}, function (er, stdout, stderr) {
var stdoutTrimmed = (stdout + "\n" + stderr).trim()
if (er || u !== stdout.trim()) {
log.warn( "`git config --get remote.origin.url` returned "
+ "wrong result ("+u+")", stdoutTrimmed )
return rm(p, function (er){
if (er) return cb(er)
cloneGitRemote(p, u, co, origUrl, silent, cb)
})
}
log.verbose("git remote.origin.url", stdoutTrimmed)
archiveGitRemote(p, u, co, origUrl, cb)
})
})
})
}

function checkGitDir (p, u, co, origUrl, silent, cb) {
fs.stat(p, function (er, s) {
if (er) return cloneGitRemote(p, u, co, origUrl, silent, cb)
if (!s.isDirectory()) return rm(p, function (er){
if (er) return cb(er)
cloneGitRemote(p, u, co, origUrl, silent, cb)
})

var git = npm.config.get("git")
var args = [ "config", "--get", "remote.origin.url" ]
var env = gitEnv()

// check for git
which(git, function (err) {
if (err) {
err.code = "ENOGIT"
return cb(err)
}
exec(git, args, {cwd: p, env: env}, function (er, stdout, stderr) {
var stdoutTrimmed = (stdout + "\n" + stderr).trim()
if (er || u !== stdout.trim()) {
log.warn( "`git config --get remote.origin.url` returned "
+ "wrong result ("+u+")", stdoutTrimmed )
return rm(p, function (er){
if (er) return cb(er)
cloneGitRemote(p, u, co, origUrl, silent, cb)
})
}
log.verbose("git remote.origin.url", stdoutTrimmed)
archiveGitRemote(p, u, co, origUrl, cb)
})
})
})
}

function cloneGitRemote (p, u, co, origUrl, silent, cb) {
mkdir(p, function (er) {
if (er) return cb(er)

var git = npm.config.get("git")
var args = [ "clone", "--mirror", u, p ]
var env = gitEnv()

// check for git
which(git, function (err) {
if (err) {
err.code = "ENOGIT"
return cb(err)
}
exec(git, args, {cwd: p, env: env}, function (er, stdout, stderr) {
stdout = (stdout + "\n" + stderr).trim()
if (er) {
if (silent) {
log.verbose("git clone " + u, stdout)
} else {
log.error("git clone " + u, stdout)
}
return cb(er)
}
log.verbose("git clone " + u, stdout)
archiveGitRemote(p, u, co, origUrl, cb)
})
})
})
}

function archiveGitRemote (p, u, co, origUrl, cb) {
var git = npm.config.get("git")
var archive = [ "fetch", "-a", "origin" ]
var resolve = [ "rev-list", "-n1", co ]
var env = gitEnv()

var resolved = null
var tmp

exec(git, archive, {cwd: p, env: env}, function (er, stdout, stderr) {
stdout = (stdout + "\n" + stderr).trim()
if (er) {
log.error("git fetch -a origin ("+u+")", stdout)
return cb(er)
}
log.verbose("git fetch -a origin ("+u+")", stdout)
tmp = path.join(npm.tmp, Date.now()+"-"+Math.random(), "tmp.tgz")
verifyOwnership()
})

function verifyOwnership() {
if (process.platform === "win32") {
log.silly("verifyOwnership", "skipping for windows")
resolveHead()
} else {
getCacheStat(function(er, cs) {
if (er) {
log.error("Could not get cache stat")
return cb(er)
}
chownr(p, cs.uid, cs.gid, function(er) {
if (er) {
log.error("Failed to change folder ownership under npm cache for %s", p)
return cb(er)
}
resolveHead()
})
})
}
}

function resolveHead () {
exec(git, resolve, {cwd: p, env: env}, function (er, stdout, stderr) {
stdout = (stdout + "\n" + stderr).trim()
if (er) {
log.error("Failed resolving git HEAD (" + u + ")", stderr)
return cb(er)
}
log.verbose("git rev-list -n1 " + co, stdout)
var parsed = url.parse(origUrl)
parsed.hash = stdout
resolved = url.format(parsed)

// https://github.com/npm/npm/issues/3224
// node incorrectly sticks a / at the start of the path
// We know that the host won't change, so split and detect this
var spo = origUrl.split(parsed.host)
var spr = resolved.split(parsed.host)
if (spo[1].charAt(0) === ':' && spr[1].charAt(0) === '/')
spr[1] = spr[1].slice(1)
resolved = spr.join(parsed.host)

log.verbose('resolved git url', resolved)
next()
})
}

function next () {
mkdir(path.dirname(tmp), function (er) {
if (er) return cb(er)
var gzip = zlib.createGzip({ level: 9 })
var git = npm.config.get("git")
var args = ["archive", co, "--format=tar", "--prefix=package/"]
var out = fs.createWriteStream(tmp)
var env = gitEnv()
cb = once(cb)
var cp = spawn(git, args, { env: env, cwd: p })
cp.on("error", cb)
cp.stderr.on("data", function(chunk) {
log.silly(chunk.toString(), "git archive")
})

cp.stdout.pipe(gzip).pipe(out).on("close", function() {
addLocalTarball(tmp, null, null, function(er, data) {
if (data) data._resolved = resolved
cb(er, data)
})
})
})
}
}

var gitEnv_
function gitEnv () {
// git responds to env vars in some weird ways in post-receive hooks
// so don't carry those along.
if (gitEnv_) return gitEnv_
gitEnv_ = {}
for (var k in process.env) {
if (!~['GIT_PROXY_COMMAND','GIT_SSH','GIT_SSL_NO_VERIFY'].indexOf(k) && k.match(/^GIT/)) continue
gitEnv_[k] = process.env[k]
}
return gitEnv_
}
@@ -0,0 +1,106 @@
var mkdir = require("mkdirp")
, assert = require("assert")
, log = require("npmlog")
, path = require("path")
, sha = require("sha")
, retry = require("retry")
, npm = require("../npm.js")
, fetch = require("../utils/fetch.js")
, inflight = require("inflight")
, locker = require("../utils/locker.js")
, lock = locker.lock
, unlock = locker.unlock
, addLocalTarball = require("./add-local-tarball.js")
, cacheFile = require("npm-cache-filename")

module.exports = addRemoteTarball

function addRemoteTarball (u, pkgData, shasum, cb_) {
assert(typeof u === "string", "must have module URL")
assert(typeof cb_ === "function", "must have callback")

function cb (er, data) {
if (data) {
data._from = u
data._shasum = data._shasum || shasum
data._resolved = u
}
unlock(u, function () {
cb_(er, data)
})
}

cb_ = inflight(u, cb_)

if (!cb_) return

// XXX Fetch direct to cache location, store tarballs under
// ${cache}/registry.npmjs.org/pkg/-/pkg-1.2.3.tgz
var tmp = cacheFile(npm.tmp, u)

function next (er, resp, shasum) {
if (er) return cb(er)
addLocalTarball(tmp, pkgData, shasum, cb)
}

lock(u, function (er) {
if (er) return cb(er)

log.verbose("addRemoteTarball", [u, shasum])
mkdir(path.dirname(tmp), function (er) {
if (er) return cb(er)
addRemoteTarball_(u, tmp, shasum, next)
})
})
}

function addRemoteTarball_(u, tmp, shasum, cb) {
// Tuned to spread 3 attempts over about a minute.
// See formula at <https://github.com/tim-kos/node-retry>.
var operation = retry.operation
( { retries: npm.config.get("fetch-retries")
, factor: npm.config.get("fetch-retry-factor")
, minTimeout: npm.config.get("fetch-retry-mintimeout")
, maxTimeout: npm.config.get("fetch-retry-maxtimeout") })

operation.attempt(function (currentAttempt) {
log.info("retry", "fetch attempt " + currentAttempt
+ " at " + (new Date()).toLocaleTimeString())
fetchAndShaCheck(u, tmp, shasum, function (er, response, shasum) {
// Only retry on 408, 5xx or no `response`.
var sc = response && response.statusCode
var statusRetry = !sc || (sc === 408 || sc >= 500)
if (er && statusRetry && operation.retry(er)) {
log.info("retry", "will retry, error on last attempt: " + er)
return
}
cb(er, response, shasum)
})
})
}

function fetchAndShaCheck (u, tmp, shasum, cb) {
fetch(u, tmp, function (er, response) {
if (er) {
log.error("fetch failed", u)
return cb(er, response)
}

if (!shasum) {
// Well, we weren't given a shasum, so at least sha what we have
// in case we want to compare it to something else later
return sha.get(tmp, function (er, shasum) {
cb(er, response, shasum)
})
}

// validate that the url we just downloaded matches the expected shasum.
sha.check(tmp, shasum, function (er) {
if (er && er.message) {
// add original filename for better debuggability
er.message = er.message + '\n' + 'From: ' + u
}
return cb(er, response, shasum)
})
})
}
@@ -0,0 +1,63 @@
var mkdir = require("mkdirp")
, fs = require("graceful-fs")
, log = require("npmlog")
, chownr = require("chownr")
, npm = require("../npm.js")
, inflight = require("inflight")

// to maintain the cache dir's permissions consistently.
var cacheStat = null
module.exports = function getCacheStat (cb) {
if (cacheStat) return cb(null, cacheStat)

cb = inflight("getCacheStat", cb)
if (!cb) return

fs.stat(npm.cache, function (er, st) {
if (er) return makeCacheDir(cb)
if (!st.isDirectory()) {
log.error("getCacheStat", "invalid cache dir %j", npm.cache)
return cb(er)
}
return cb(null, cacheStat = st)
})
}

function makeCacheDir (cb) {
if (!process.getuid) return mkdir(npm.cache, cb)

var uid = +process.getuid()
, gid = +process.getgid()

if (uid === 0) {
if (process.env.SUDO_UID) uid = +process.env.SUDO_UID
if (process.env.SUDO_GID) gid = +process.env.SUDO_GID
}
if (uid !== 0 || !process.env.HOME) {
cacheStat = {uid: uid, gid: gid}
return mkdir(npm.cache, afterMkdir)
}

fs.stat(process.env.HOME, function (er, st) {
if (er) {
log.error("makeCacheDir", "homeless?")
return cb(er)
}
cacheStat = st
log.silly("makeCacheDir", "cache dir uid, gid", [st.uid, st.gid])
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)
})
}
}
@@ -0,0 +1,35 @@
var url = require("url")
, assert = require("assert")
, log = require("npmlog")
, addRemoteGit = require("./add-remote-git.js")

module.exports = function maybeGithub (p, er, cb) {
assert(typeof p === "string", "must pass package name")
assert(er instanceof Error, "must include error")
assert(typeof cb === "function", "must pass callback")

var u = "git://github.com/" + p
, up = url.parse(u)
log.info("maybeGithub", "Attempting %s from %s", p, u)

return addRemoteGit(u, up, true, function (er2, data) {
if (er2) {
var upriv = "git+ssh://git@github.com:" + p
, uppriv = url.parse(upriv)

log.info("maybeGithub", "Attempting %s from %s", p, upriv)

return addRemoteGit(upriv, uppriv, false, function (er3, data) {
if (er3) return cb(er)
success(upriv, data)
})
}
success(u, data)
})

function success (u, data) {
data._from = u
data._fromGithub = true
return cb(null, data)
}
}
@@ -26,6 +26,7 @@ function explore (args, cb) {
"\nExploring "+cwd+"\n"+
"Type 'exit' or ^D when finished\n")

npm.spinner.stop()
var shell = spawn(sh, args, { cwd: cwd, customFds: [0, 1, 2] })
shell.on("close", function (er) {
// only fail if non-interactive.
@@ -15,6 +15,7 @@ var fs = require("graceful-fs")
, glob = require("glob")

function help (args, cb) {
npm.spinner.stop()
var argv = npm.config.get("argv").cooked

var argnum = 0
@@ -12,6 +12,7 @@ init.usage = "npm init"
function init (args, cb) {
var dir = process.cwd()
log.pause()
npm.spinner.stop()
var initFile = npm.config.get('init-module')

console.log(
@@ -31,6 +32,10 @@ function init (args, cb) {
log.resume()
log.silly('package data', data)
log.info('init', 'written successfully')
if (er && er.message === 'canceled') {
log.warn('init', 'canceled')
return cb(null, data)
}
cb(er, data)
})
}
@@ -391,6 +391,7 @@ function save (where, installed, tree, pretty, hasArguments, cb) {
if (saveBundle) {
var i = bundle.indexOf(t)
if (i === -1) bundle.push(t)
data.bundleDependencies = bundle.sort()
}
})

@@ -709,7 +710,7 @@ function targetResolver (where, context, deps) {
// already has a matching copy.
// If it's not a git repo, and the parent already has that pkg, then
// we can skip installing it again.
cache.add(what, function (er, data) {
cache.add(what, null, false, function (er, data) {
if (er && parent && parent.optionalDependencies &&
parent.optionalDependencies.hasOwnProperty(what.split("@")[0])) {
log.warn("optional dep failed, continuing", what)
@@ -128,8 +128,7 @@ function getLite (data, noname) {
var dep = data.dependencies[d]
if (typeof dep === "string") {
lite.problems = lite.problems || []
var p
if (data.depth >= maxDepth) {
if (data.depth > maxDepth) {
p = "max depth reached: "
} else {
p = "missing: "
@@ -223,14 +222,14 @@ function makeArchy (data, long, dir) {
function makeArchy_ (data, long, dir, depth, parent, d) {
var color = npm.color
if (typeof data === "string") {
if (depth < npm.config.get("depth")) {
if (depth -1 <= npm.config.get("depth")) {
// just missing
var p = parent.link || parent.path
var unmet = "UNMET DEPENDENCY"
if (color) {
unmet = "\033[31;40m" + unmet + "\033[0m"
}
data = unmet + " " + d + " " + data
data = unmet + " " + d + "@" + data
} else {
data = d+"@"+ data
}
@@ -24,12 +24,8 @@ var EventEmitter = require("events").EventEmitter
, abbrev = require("abbrev")
, which = require("which")
, semver = require("semver")
, findPrefix = require("./utils/find-prefix.js")
, getUid = require("uid-number")
, mkdirp = require("mkdirp")
, slide = require("slide")
, chain = slide.chain
, RegClient = require("npm-registry-client")
, charSpin = require("char-spinner")

npm.config = {
loaded: false,
@@ -41,23 +37,6 @@ npm.config = {
}
}

// /usr/local is often a read-only fs, which is not
// well handled by node or mkdirp. Just double-check
// in the case of errors when making the prefix dirs.
function mkdir (p, cb) {
mkdirp(p, function (er, made) {
// it could be that we couldn't create it, because it
// already exists, and is on a read-only fs.
if (er) {
return fs.stat(p, function (er2, st) {
if (er2 || !st.isDirectory()) return cb(er)
return cb(null, made)
})
}
return cb(er, made)
})
}

npm.commands = {}

try {
@@ -182,6 +161,22 @@ var commandCache = {}
})
, abbrevs = abbrev(fullList)

npm.spinner =
{ int: null
, start: function () {
if (npm.spinner.int) return
var c = npm.config.get("spin")
if (!c) return
var stream = npm.config.get("logstream")
var opt = { tty: c !== "always", stream: stream }
npm.spinner.int = charSpin(opt)
}
, stop: function () {
clearInterval(npm.spinner.int)
npm.spinner.int = null
}
}

Object.keys(abbrevs).concat(plumbing).forEach(function addCommand (c) {
Object.defineProperty(npm.commands, c, { get : function () {
if (!loaded) throw new Error(
@@ -204,6 +199,9 @@ Object.keys(abbrevs).concat(plumbing).forEach(function addCommand (c) {
}
if (args.length === 1) args.unshift([])

npm.spinner.start()

npm.registry.version = npm.version
if (!npm.registry.refer) {
npm.registry.refer = [a].concat(args[0]).map(function (arg) {
// exclude anything that might be a URL, path, or private module
@@ -350,118 +348,24 @@ function load (npm, cli, cb) {

// at this point the configs are all set.
// go ahead and spin up the registry client.
var token = config.get("_token")
if (typeof token === "string") {
try {
token = JSON.parse(token)
config.set("_token", token, "user")
config.save("user")
} catch (e) { token = null }
}

npm.registry = new RegClient(npm.config)

// save the token cookie in the config file
if (npm.registry.couchLogin) {
npm.registry.couchLogin.tokenSet = function (tok) {
npm.config.set("_token", tok, "user")
// ignore save error. best effort.
npm.config.save("user")
}
}

var umask = npm.config.get("umask")
npm.modes = { exec: 0777 & (~umask)
, file: 0666 & (~umask)
, umask: umask }

chain([ [ loadPrefix, npm, cli ]
, [ setUser, config, config.root ]
, [ loadUid, npm ]
], cb)
})
})
}
var gp = Object.getOwnPropertyDescriptor(config, "globalPrefix")
Object.defineProperty(npm, "globalPrefix", gp)

function loadPrefix (npm, config, cb) {
// try to guess at a good node_modules location.
var p
, gp
if (!Object.prototype.hasOwnProperty.call(config, "prefix")) {
p = process.cwd()
} else {
p = npm.config.get("prefix")
}
gp = npm.config.get("prefix")

findPrefix(p, function (er, p) {
Object.defineProperty(npm, "localPrefix",
{ get : function () { return p }
, set : function (r) { return p = r }
, enumerable : true
})
// the prefix MUST exist, or else nothing works.
if (!npm.config.get("global")) {
mkdir(p, next)
} else {
next(er)
}
})

gp = path.resolve(gp)
Object.defineProperty(npm, "globalPrefix",
{ get : function () { return gp }
, set : function (r) { return gp = r }
, enumerable : true
})
// the prefix MUST exist, or else nothing works.
mkdir(gp, next)


var i = 2
, errState = null
function next (er) {
if (errState) return
if (er) return cb(errState = er)
if (--i === 0) return cb()
}
}
var lp = Object.getOwnPropertyDescriptor(config, "localPrefix")
Object.defineProperty(npm, "localPrefix", lp)


function loadUid (npm, cb) {
// if we're not in unsafe-perm mode, then figure out who
// to run stuff as. Do this first, to support `npm update npm -g`
if (!npm.config.get("unsafe-perm")) {
getUid(npm.config.get("user"), npm.config.get("group"), cb)
} else {
process.nextTick(cb)
}
}

function setUser (cl, dc, cb) {
// If global, leave it as-is.
// If not global, then set the user to the owner of the prefix folder.
// Just set the default, so it can be overridden.
if (cl.get("global")) return cb()
if (process.env.SUDO_UID) {
dc.user = +(process.env.SUDO_UID)
return cb()
}

var prefix = path.resolve(cl.get("prefix"))
mkdir(prefix, function (er) {
if (er) {
log.error("could not create prefix dir", prefix)
return cb(er)
}
fs.stat(prefix, function (er, st) {
dc.user = st && st.uid
return cb(er)
return cb()
})
})
}


Object.defineProperty(npm, "prefix",
{ get : function () {
return npm.config.get("global") ? npm.globalPrefix : npm.localPrefix
@@ -155,12 +155,33 @@ function outdated_ (args, dir, parentHas, depth, cb) {
}
var deps = null
readJson(path.resolve(dir, "package.json"), function (er, d) {
d = d || {}
if (er && er.code !== "ENOENT" && er.code !== "ENOTDIR") return cb(er)
deps = (er) ? true : (d.dependencies || {})

if (npm.config.get("save-dev")) {
deps = d.devDependencies || {}
return next()
}

if (npm.config.get("save")) {
// remove optional dependencies from dependencies during --save.
Object.keys(d.optionalDependencies || {}).forEach(function (k) {
delete deps[k]
})
return next()
}

if (npm.config.get("save-optional")) {
deps = d.optionalDependencies || {}
return next()
}

var doUpdate = npm.config.get("dev") ||
(!npm.config.get("production") &&
!Object.keys(parentHas).length &&
!npm.config.get("global"))

if (!er && d && doUpdate) {
Object.keys(d.devDependencies || {}).forEach(function (k) {
if (!(k in parentHas)) {
@@ -273,7 +294,7 @@ function shouldUpdate (args, dir, dep, has, req, depth, cb) {
}

// We didn't find the version in the doc. See if cache can find it.
cache.add(dep, req, onCacheAdd)
cache.add(dep, req, false, onCacheAdd)

function onCacheAdd(er, d) {
// if this fails, then it means we can't update this thing.
@@ -40,7 +40,7 @@ function printFiles (files, cb) {

// add to cache, then cp to the cwd
function pack_ (pkg, cb) {
cache.add(pkg, function (er, data) {
cache.add(pkg, null, false, function (er, data) {
if (er) return cb(er)
var fname = path.resolve(data._id.replace(/@/g, "-") + ".tgz")
, cached = path.resolve( npm.cache
@@ -49,7 +49,7 @@ function publish (args, isRetry, cb) {
// That means that we can run publish/postpublish in the dir, rather than
// in the cache dir.
function cacheAddPublish (dir, didPre, isRetry, cb) {
npm.commands.cache.add(dir, function (er, data) {
npm.commands.cache.add(dir, null, false, function (er, data) {
if (er) return cb(er)
log.silly("publish", data)
var cachedir = path.resolve( npm.cache
@@ -19,6 +19,7 @@ var npm = require("./npm.js")
, path = require("path")
, readJson = require("read-package-json")
, fs = require("fs")
, url_ = require('url')

function repo (args, cb) {
var n = args.length && args[0].split("@").shift() || '.'
@@ -40,7 +41,11 @@ function getUrlAndOpen (d, cb) {
// from https://github.com/npm/npm-www/issues/418
if (githubUserRepo(r.url))
r.url = githubUserRepo(r.url)
var url = github(r.url)

var url = (r.url && ~r.url.indexOf('github'))
? github(r.url)
: nonGithubUrl(r.url)

if (!url)
return cb(new Error('no repository: could not get url'))
opener(url, { command: npm.config.get("browser") }, cb)
@@ -52,3 +57,19 @@ function callRegistry (n, cb) {
getUrlAndOpen(d, cb)
})
}

function nonGithubUrl (url) {
try {
var idx = url.indexOf('@')
if (idx !== -1) {
url = url.slice(idx+1).replace(/:([^\d]+)/, '/$1')
}
url = url_.parse(url)
var protocol = url.protocol === 'https:'
? 'https:'
: 'http:'
return protocol + '//' + (url.host || '') +
url.path.replace(/\.git$/, '')
}
catch(e) {}
}
@@ -23,7 +23,7 @@ function submodule (args, cb) {
if (args.length === 0) return cb(submodule.usage)

asyncMap(args, function (arg, cb) {
cache.add(arg, cb)
cache.add(arg, null, false, cb)
}, function (er, pkgs) {
if (er) return cb(er)
chain(pkgs.map(function (pkg) { return function (cb) {
@@ -99,9 +99,9 @@ var getSubmodules = function getSubmodules (cb) {
err.code = "ENOGIT"
return cb(err)
}
exec(git, args, function (er, stdout, stderr) {
exec(git, args, function (er, stdout) {
if (er) return cb(er)
res = stdout.trim().split(/\n/).map(function (line) {
var res = stdout.trim().split(/\n/).map(function (line) {
return line.trim().split(/\s+/)[1]
}).filter(function (line) {
// only care about submodules in the node_modules folder.
@@ -0,0 +1,13 @@
var log = require("npmlog")

var deprecated = {}
, deprWarned = {}
module.exports = function deprCheck (data) {
if (deprecated[data._id]) data.deprecated = deprecated[data._id]
if (data.deprecated) deprecated[data._id] = data.deprecated
else return
if (!deprWarned[data._id]) {
deprWarned[data._id] = true
log.warn("deprecated", "%s: %s", data._id, data.deprecated)
}
}
@@ -63,6 +63,7 @@ function exit (code, noLog) {
// if we're really exiting, then let it exit on its own, so that
// in-process stuff can finish or clean up first.
if (!doExit) process.emit("exit", code)
npm.spinner.stop()
}
}

@@ -162,6 +162,9 @@ function runCmd (note, cmd, pkg, env, stage, wd, unsafe, cb) {
, group = unsafe ? null : npm.config.get("group")

if (log.level !== 'silent') {
if (npm.spinner.int) {
npm.config.get("logstream").write("\r \r")
}
console.log(note)
}
log.verbose("unsafe-perm in lifecycle", unsafe)
@@ -0,0 +1,52 @@
var crypto = require("crypto")
var path = require("path")

var npm = require("../npm.js")
var lockFile = require("lockfile")
var log = require("npmlog")
var getCacheStat = require("../cache/get-stat.js")

function lockFileName (u) {
var c = u.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "")
, h = crypto.createHash("sha1").update(u).digest("hex")
h = h.substr(0, 8)
c = c.substr(-32)
log.silly("lockFile", h + "-" + c, u)
return path.resolve(npm.config.get("cache"), h + "-" + c + ".lock")
}

var myLocks = {}
function lock (u, cb) {
// the cache dir needs to exist already for this.
getCacheStat(function (er, cs) {
if (er) return cb(er)
var opts = { stale: npm.config.get("cache-lock-stale")
, retries: npm.config.get("cache-lock-retries")
, wait: npm.config.get("cache-lock-wait") }
var lf = lockFileName(u)
log.verbose("lock", u, lf)
lockFile.lock(lf, opts, function(er) {
if (!er) myLocks[lf] = true
cb(er)
})
})
}

function unlock (u, cb) {
var lf = lockFileName(u)
, 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")
}
}

module.exports = {
lock: lock,
unlock: unlock,
_lockFileName: lockFileName
}
@@ -8,21 +8,21 @@ var npm = require("../npm.js")
, uidNumber = require("uid-number")
, rm = require("./gently-rm.js")
, readJson = require("read-package-json")
, cache = require("../cache.js")
, myUid = process.getuid && process.getuid()
, myGid = process.getgid && process.getgid()
, tar = require("tar")
, zlib = require("zlib")
, fstream = require("fstream")
, Packer = require("fstream-npm")
, lifecycle = require("./lifecycle.js")
, locker = require("./locker.js")

function lock(path, cb) {
return cache.lock('tar://' + path, cb)
return locker.lock('tar://' + path, cb)
}

function unlock(path, cb) {
return cache.unlock('tar://' + path, cb)
return locker.unlock('tar://' + path, cb)
}

if (process.env.SUDO_UID && myUid === 0) {
@@ -11,7 +11,7 @@ var exec = require("child_process").execFile
, which = require("which")
, npm = require("./npm.js")

version.usage = "npm version [<newversion> | major | minor | patch]\n"
version.usage = "npm version [<newversion> | major | minor | patch | prerelease | preminor | premajor ]\n"
+ "\n(run in package dir)\n"
+ "'npm -v' or 'npm --version' to print npm version "
+ "("+npm.version+")\n"
@@ -105,6 +105,11 @@ function checkGit (data, cb) {
chain
( [ [ exec, git, [ "add", "package.json" ], {env: process.env} ]
, [ exec, git, [ "commit", "-m", message ], {env: process.env} ]
, sign && function (cb) {
npm.spinner.stop()
cb()
}

, [ exec, git, [ "tag", "v" + data.version, flag, message ]
, {env: process.env} ] ]
, cb )
@@ -208,7 +208,7 @@ function printData (data, name, cb) {
d = JSON.stringify(d)
}
if (f && showFields) f += " = "
if (d.indexOf("\n") !== -1) d = "\n" + d
if (d.indexOf("\n") !== -1) d = " \n" + d
msg += (showVersions ? name + "@" + v + " " : "")
+ (showFields ? f : "") + d + "\n"
})
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM" "1" "May 2014" "" ""
.TH "NPM" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm\fR \-\- node package manager![Build Status \fIhttps://img\.shields\.io/travis/npm/npm/master\.svg)](https://travis\-ci\.org/npm/npm\fR
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-ADDUSER" "1" "May 2014" "" ""
.TH "NPM\-ADDUSER" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-adduser\fR \-\- Add a registry user account
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-BIN" "1" "May 2014" "" ""
.TH "NPM\-BIN" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-bin\fR \-\- Display npm bin folder
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-BUGS" "1" "May 2014" "" ""
.TH "NPM\-BUGS" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-bugs\fR \-\- Bugs for a package in a web browser maybe
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-BUILD" "1" "May 2014" "" ""
.TH "NPM\-BUILD" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-build\fR \-\- Build a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-BUNDLE" "1" "May 2014" "" ""
.TH "NPM\-BUNDLE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-bundle\fR \-\- REMOVED
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-CACHE" "1" "May 2014" "" ""
.TH "NPM\-CACHE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-cache\fR \-\- Manipulates packages cache
@@ -46,12 +46,8 @@ For each package that is added to the cache, three pieces of information are
stored in \fB{cache}/{name}/{version}\fR:
.
.IP "\(bu" 4
\|\.\.\./package/:
A folder containing the package contents as they appear in the tarball\.
.
.IP "\(bu" 4
\|\.\.\./package\.json:
The package\.json file, as npm sees it, with overlays applied and a _id attribute\.
\|\.\.\./package/package\.json:
The package\.json file, as npm sees it\.
.
.IP "\(bu" 4
\|\.\.\./package\.tgz:
@@ -62,7 +58,7 @@ The tarball for that version\.
.P
Additionally, whenever a registry request is made, a \fB\|\.cache\.json\fR file
is placed at the corresponding URI, to store the ETag and the requested
data\.
data\. This is stored in \fB{cache}/{hostname}/{path}/\.cache\.json\fR\|\.
.
.P
Commands that make non\-essential registry requests (such as \fBsearch\fR and \fBview\fR, or the completion scripts) generally specify a minimum timeout\.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-COMPLETION" "1" "May 2014" "" ""
.TH "NPM\-COMPLETION" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-completion\fR \-\- Tab Completion for npm
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-CONFIG" "1" "May 2014" "" ""
.TH "NPM\-CONFIG" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-config\fR \-\- Manage the npm configuration files
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-DEDUPE" "1" "May 2014" "" ""
.TH "NPM\-DEDUPE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-dedupe\fR \-\- Reduce duplication
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-DEPRECATE" "1" "May 2014" "" ""
.TH "NPM\-DEPRECATE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-deprecate\fR \-\- Deprecate a version of a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-DOCS" "1" "May 2014" "" ""
.TH "NPM\-DOCS" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-docs\fR \-\- Docs for a package in a web browser maybe
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-EDIT" "1" "May 2014" "" ""
.TH "NPM\-EDIT" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-edit\fR \-\- Edit an installed package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-EXPLORE" "1" "May 2014" "" ""
.TH "NPM\-EXPLORE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-explore\fR \-\- Browse an installed package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-HELP\-SEARCH" "1" "May 2014" "" ""
.TH "NPM\-HELP\-SEARCH" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-help-search\fR \-\- Search npm help documentation
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-HELP" "1" "May 2014" "" ""
.TH "NPM\-HELP" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-help\fR \-\- Get help on npm
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-INIT" "1" "May 2014" "" ""
.TH "NPM\-INIT" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-init\fR \-\- Interactively create a package\.json file
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-INSTALL" "1" "May 2014" "" ""
.TH "NPM\-INSTALL" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-install\fR \-\- Install a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-LINK" "1" "May 2014" "" ""
.TH "NPM\-LINK" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-link\fR \-\- Symlink a package folder
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-LS" "1" "May 2014" "" ""
.TH "NPM\-LS" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-ls\fR \-\- List installed packages
@@ -29,7 +29,7 @@ For example, running \fBnpm ls promzard\fR in npm\'s source tree will show:
.IP "" 4
.
.nf
npm@1.4.10 /path/to/npm
npm@1.4.14 /path/to/npm
└─┬ init\-package\-json@0\.0\.4
└── promzard@0\.1\.5
.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-OUTDATED" "1" "May 2014" "" ""
.TH "NPM\-OUTDATED" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-outdated\fR \-\- Check for outdated packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-OWNER" "1" "May 2014" "" ""
.TH "NPM\-OWNER" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-owner\fR \-\- Manage package owners
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PACK" "1" "May 2014" "" ""
.TH "NPM\-PACK" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-pack\fR \-\- Create a tarball from a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PREFIX" "1" "May 2014" "" ""
.TH "NPM\-PREFIX" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-prefix\fR \-\- Display prefix
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PRUNE" "1" "May 2014" "" ""
.TH "NPM\-PRUNE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-prune\fR \-\- Remove extraneous packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PUBLISH" "1" "May 2014" "" ""
.TH "NPM\-PUBLISH" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-publish\fR \-\- Publish a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-REBUILD" "1" "May 2014" "" ""
.TH "NPM\-REBUILD" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-rebuild\fR \-\- Rebuild a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-REPO" "1" "May 2014" "" ""
.TH "NPM\-REPO" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-repo\fR \-\- Open package repository page in the browser
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-RESTART" "1" "May 2014" "" ""
.TH "NPM\-RESTART" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-restart\fR \-\- Start a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-RM" "1" "May 2014" "" ""
.TH "NPM\-RM" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-rm\fR \-\- Remove a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-ROOT" "1" "May 2014" "" ""
.TH "NPM\-ROOT" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-root\fR \-\- Display npm root
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-RUN\-SCRIPT" "1" "May 2014" "" ""
.TH "NPM\-RUN\-SCRIPT" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-run-script\fR \-\- Run arbitrary package scripts
@@ -10,6 +10,7 @@
.
.nf
npm run\-script [<pkg>] [command]
npm run [<pkg>] [command]
.
.fi
.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-SEARCH" "1" "May 2014" "" ""
.TH "NPM\-SEARCH" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-search\fR \-\- Search for packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-SHRINKWRAP" "1" "May 2014" "" ""
.TH "NPM\-SHRINKWRAP" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-shrinkwrap\fR \-\- Lock down dependency versions
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-STAR" "1" "May 2014" "" ""
.TH "NPM\-STAR" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-star\fR \-\- Mark your favorite packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-STARS" "1" "May 2014" "" ""
.TH "NPM\-STARS" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-stars\fR \-\- View packages marked as favorites
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-START" "1" "May 2014" "" ""
.TH "NPM\-START" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-start\fR \-\- Start a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-STOP" "1" "May 2014" "" ""
.TH "NPM\-STOP" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-stop\fR \-\- Stop a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-SUBMODULE" "1" "May 2014" "" ""
.TH "NPM\-SUBMODULE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-submodule\fR \-\- Add a package as a git submodule
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-TAG" "1" "May 2014" "" ""
.TH "NPM\-TAG" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-tag\fR \-\- Tag a published version
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-TEST" "1" "May 2014" "" ""
.TH "NPM\-TEST" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-test\fR \-\- Test a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-RM" "1" "May 2014" "" ""
.TH "NPM\-RM" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-rm\fR \-\- Remove a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-UNPUBLISH" "1" "May 2014" "" ""
.TH "NPM\-UNPUBLISH" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-unpublish\fR \-\- Remove a package from the registry
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-UPDATE" "1" "May 2014" "" ""
.TH "NPM\-UPDATE" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-update\fR \-\- Update a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-VERSION" "1" "May 2014" "" ""
.TH "NPM\-VERSION" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-version\fR \-\- Bump a package version
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-VIEW" "1" "May 2014" "" ""
.TH "NPM\-VIEW" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-view\fR \-\- View registry info
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-WHOAMI" "1" "May 2014" "" ""
.TH "NPM\-WHOAMI" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-whoami\fR \-\- Display npm username
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM" "1" "May 2014" "" ""
.TH "NPM" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm\fR \-\- node package manager
@@ -14,7 +14,7 @@ npm <command> [args]
.fi
.
.SH "VERSION"
1.4.10
1.4.14
.
.SH "DESCRIPTION"
npm is the package manager for the Node JavaScript platform\. It puts
@@ -39,6 +39,20 @@ npm help Use \fBnpm install blerg\fR to install the latest version of "blerg"\.
Use the \fBnpm search\fR command to show everything that\'s available\.
Use \fBnpm ls\fR to show everything you\'ve installed\.
.
.SH "DEPENDENCIES"
If a package references to another package with a git URL, npm depends
on a preinstalled git\.
.
.P
If one of the packages npm tries to install is a native node module and
requires compiling of C++ Code, npm will use node\-gyp \fIhttps://github\.com/TooTallNate/node\-gyp\fR for that task\.
For a Unix system, node\-gyp \fIhttps://github\.com/TooTallNate/node\-gyp\fR
needs Python, make and a buildchain like GCC\. On Windows,
Python and Microsoft Visual Studio C++ is needed\. Python 3 is
not supported by node\-gyp \fIhttps://github\.com/TooTallNate/node\-gyp\fR\|\.
For more information visit the node\-gyp repository \fIhttps://github\.com/TooTallNate/node\-gyp\fR and
the node\-gyp Wiki \fIhttps://github\.com/TooTallNate/node\-gyp/wiki\fR\|\.
.
.SH "DIRECTORIES"
npm help See \fBnpm\-folders\fR to learn about where npm puts stuff\.
.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-BIN" "3" "May 2014" "" ""
.TH "NPM\-BIN" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-bin\fR \-\- Display npm bin folder
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-BUGS" "3" "May 2014" "" ""
.TH "NPM\-BUGS" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-bugs\fR \-\- Bugs for a package in a web browser maybe
@@ -0,0 +1,40 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-CACHE" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-cache\fR \-\- manage the npm cache programmatically
.
.SH "SYNOPSIS"
.
.nf
npm\.commands\.cache([args], callback)
// helpers
npm\.commands\.cache\.clean([args], callback)
npm\.commands\.cache\.add([args], callback)
npm\.commands\.cache\.read(name, version, forceBypass, callback)
.
.fi
.
.SH "DESCRIPTION"
npm help This acts much the same ways as the npm\-cache command line
functionality\.
.
.P
The callback is called with the package\.json data of the thing that is
eventually added to or read from the cache\.
.
.P
The top level \fBnpm\.commands\.cache(\.\.\.)\fR functionality is a public
interface, and like all commands on the \fBnpm\.commands\fR object, it will
match the command line behavior exactly\.
.
.P
However, the cache folder structure and the cache helper functions are
considered \fBinternal\fR API surface, and as such, may change in future
releases of npm, potentially without warning or significant version
incrementation\.
.
.P
Use at your own risk\.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-COMMANDS" "3" "May 2014" "" ""
.TH "NPM\-COMMANDS" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-commands\fR \-\- npm commands
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-CONFIG" "3" "May 2014" "" ""
.TH "NPM\-CONFIG" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-config\fR \-\- Manage the npm configuration files
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-DEPRECATE" "3" "May 2014" "" ""
.TH "NPM\-DEPRECATE" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-deprecate\fR \-\- Deprecate a version of a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-DOCS" "3" "May 2014" "" ""
.TH "NPM\-DOCS" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-docs\fR \-\- Docs for a package in a web browser maybe
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-EDIT" "3" "May 2014" "" ""
.TH "NPM\-EDIT" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-edit\fR \-\- Edit an installed package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-EXPLORE" "3" "May 2014" "" ""
.TH "NPM\-EXPLORE" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-explore\fR \-\- Browse an installed package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-HELP\-SEARCH" "3" "May 2014" "" ""
.TH "NPM\-HELP\-SEARCH" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-help-search\fR \-\- Search the help pages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "INIT" "3" "May 2014" "" ""
.TH "INIT" "3" "June 2014" "" ""
.
.SH "NAME"
\fBinit\fR \-\- Interactively create a package\.json file
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-INSTALL" "3" "May 2014" "" ""
.TH "NPM\-INSTALL" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-install\fR \-\- install a package programmatically
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-LINK" "3" "May 2014" "" ""
.TH "NPM\-LINK" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-link\fR \-\- Symlink a package folder
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-LOAD" "3" "May 2014" "" ""
.TH "NPM\-LOAD" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-load\fR \-\- Load config settings
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-LS" "3" "May 2014" "" ""
.TH "NPM\-LS" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-ls\fR \-\- List installed packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-OUTDATED" "3" "May 2014" "" ""
.TH "NPM\-OUTDATED" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-outdated\fR \-\- Check for outdated packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-OWNER" "3" "May 2014" "" ""
.TH "NPM\-OWNER" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-owner\fR \-\- Manage package owners
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PACK" "3" "May 2014" "" ""
.TH "NPM\-PACK" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-pack\fR \-\- Create a tarball from a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PREFIX" "3" "May 2014" "" ""
.TH "NPM\-PREFIX" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-prefix\fR \-\- Display prefix
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PRUNE" "3" "May 2014" "" ""
.TH "NPM\-PRUNE" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-prune\fR \-\- Remove extraneous packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-PUBLISH" "3" "May 2014" "" ""
.TH "NPM\-PUBLISH" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-publish\fR \-\- Publish a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-REBUILD" "3" "May 2014" "" ""
.TH "NPM\-REBUILD" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-rebuild\fR \-\- Rebuild a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-REPO" "3" "May 2014" "" ""
.TH "NPM\-REPO" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-repo\fR \-\- Open package repository page in the browser
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-RESTART" "3" "May 2014" "" ""
.TH "NPM\-RESTART" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-restart\fR \-\- Start a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-ROOT" "3" "May 2014" "" ""
.TH "NPM\-ROOT" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-root\fR \-\- Display npm root
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-RUN\-SCRIPT" "3" "May 2014" "" ""
.TH "NPM\-RUN\-SCRIPT" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-run-script\fR \-\- Run arbitrary package scripts
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-SEARCH" "3" "May 2014" "" ""
.TH "NPM\-SEARCH" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-search\fR \-\- Search for packages
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-SHRINKWRAP" "3" "May 2014" "" ""
.TH "NPM\-SHRINKWRAP" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-shrinkwrap\fR \-\- programmatically generate package shrinkwrap file
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-START" "3" "May 2014" "" ""
.TH "NPM\-START" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-start\fR \-\- Start a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-STOP" "3" "May 2014" "" ""
.TH "NPM\-STOP" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-stop\fR \-\- Stop a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-SUBMODULE" "3" "May 2014" "" ""
.TH "NPM\-SUBMODULE" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-submodule\fR \-\- Add a package as a git submodule
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-TAG" "3" "May 2014" "" ""
.TH "NPM\-TAG" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-tag\fR \-\- Tag a published version
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-TEST" "3" "May 2014" "" ""
.TH "NPM\-TEST" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-test\fR \-\- Test a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-UNINSTALL" "3" "May 2014" "" ""
.TH "NPM\-UNINSTALL" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-uninstall\fR \-\- uninstall a package programmatically
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-UNPUBLISH" "3" "May 2014" "" ""
.TH "NPM\-UNPUBLISH" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-unpublish\fR \-\- Remove a package from the registry
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-UPDATE" "3" "May 2014" "" ""
.TH "NPM\-UPDATE" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-update\fR \-\- Update a package
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-VERSION" "3" "May 2014" "" ""
.TH "NPM\-VERSION" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-version\fR \-\- Bump a package version
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-VIEW" "3" "May 2014" "" ""
.TH "NPM\-VIEW" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-view\fR \-\- View registry info
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-WHOAMI" "3" "May 2014" "" ""
.TH "NPM\-WHOAMI" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-whoami\fR \-\- Display npm username
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM" "3" "May 2014" "" ""
.TH "NPM" "3" "June 2014" "" ""
.
.SH "NAME"
\fBnpm\fR \-\- node package manager
@@ -21,7 +21,7 @@ npm\.load([configObject, ]function (er, npm) {
.fi
.
.SH "VERSION"
1.4.10
1.4.14
.
.SH "DESCRIPTION"
This is the API documentation for npm\.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-FOLDERS" "5" "May 2014" "" ""
.TH "NPM\-FOLDERS" "5" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-folders\fR \-\- Folder Structures Used by npm
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-FOLDERS" "5" "May 2014" "" ""
.TH "NPM\-FOLDERS" "5" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-folders\fR \-\- Folder Structures Used by npm
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "PACKAGE\.JSON" "5" "May 2014" "" ""
.TH "PACKAGE\.JSON" "5" "June 2014" "" ""
.
.SH "NAME"
\fBpackage.json\fR \-\- Specifics of npm\'s package\.json handling
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPMRC" "5" "May 2014" "" ""
.TH "NPMRC" "5" "June 2014" "" ""
.
.SH "NAME"
\fBnpmrc\fR \-\- The npm config files
@@ -18,7 +18,10 @@ of the user and global npmrc files\.
npm help For a list of available configuration options, see npm\-config\.
.
.SH "FILES"
The three relevant files are:
The four relevant files are:
.
.IP "\(bu" 4
per\-project config file (/path/to/my/project/\.npmrc)
.
.IP "\(bu" 4
per\-user config file (~/\.npmrc)
@@ -49,6 +52,17 @@ Each of these files is loaded, and config options are resolved in
priority order\. For example, a setting in the userconfig file would
override the setting in the globalconfig file\.
.
.SS "Per\-project config file"
When working locally in a project, a \fB\|\.npmrc\fR file in the root of the
project (ie, a sibling of \fBnode_modules\fR and \fBpackage\.json\fR) will set
config values specific to this project\.
.
.P
Note that this only applies to the root of the project that you\'re
running npm in\. It has no effect when your module is published\. For
example, you can\'t publish a module that forces itself to install
globally, or in a different location\.
.
.SS "Per\-user config file"
\fB$HOME/\.npmrc\fR (or the \fBuserconfig\fR param, if set in the environment
or on the command line)
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "PACKAGE\.JSON" "5" "May 2014" "" ""
.TH "PACKAGE\.JSON" "5" "June 2014" "" ""
.
.SH "NAME"
\fBpackage.json\fR \-\- Specifics of npm\'s package\.json handling
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-CODING\-STYLE" "7" "May 2014" "" ""
.TH "NPM\-CODING\-STYLE" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-coding-style\fR \-\- npm\'s "funny" coding style
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-CONFIG" "7" "May 2014" "" ""
.TH "NPM\-CONFIG" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-config\fR \-\- More than you probably want to know about npm configuration
@@ -24,7 +24,10 @@ values are case\-insensitive, so \fBNPM_CONFIG_FOO=bar\fR will work the
same\.
.
.SS "npmrc Files"
The three relevant files are:
The four relevant files are:
.
.IP "\(bu" 4
per\-project config file (/path/to/my/project/\.npmrc)
.
.IP "\(bu" 4
per\-user config file (~/\.npmrc)
@@ -1248,6 +1251,24 @@ using \fB\-s\fR to add a signature\.
Note that git requires you to have set up GPG keys in your git configs
for this to work properly\.
.
.SS "spin"
.
.IP "\(bu" 4
Default: true
.
.IP "\(bu" 4
Type: Boolean or \fB"always"\fR
.
.IP "" 0
.
.P
When set to \fBtrue\fR, npm will display an ascii spinner while it is doing
things, if \fBprocess\.stderr\fR is a TTY\.
.
.P
Set to \fBfalse\fR to suppress the spinner, or set to \fBalways\fR to output
the spinner even for non\-TTY outputs\.
.
.SS "strict\-ssl"
.
.IP "\(bu" 4
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-DEVELOPERS" "7" "May 2014" "" ""
.TH "NPM\-DEVELOPERS" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-developers\fR \-\- Developer Guide
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-DISPUTES" "7" "May 2014" "" ""
.TH "NPM\-DISPUTES" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-disputes\fR \-\- Handling Module Name Disputes
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-FAQ" "7" "May 2014" "" ""
.TH "NPM\-FAQ" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-faq\fR \-\- Frequently Asked Questions
@@ -340,7 +340,7 @@ change it again? npm doesn\'t currently track any state about past
configuration settings, so this would be rather difficult to do
properly\. It would have to track every previous value for this
config, and always accept any of them, or else yesterday\'s install may
be broken tomorrow\. Complexity hurdle #5\.
be broken tomorrow\. Complexity hurdle #4\.
.
.P
Never going to happen\. The folder is named \fBnode_modules\fR\|\. It is
@@ -436,7 +436,7 @@ contributed to it, some of them quite substantially\.
.P
The npm open source project, The npm Registry, and the community
website \fIhttps://www\.npmjs\.org\fR are maintained and operated by the
good folks at npm, Inc\. \fIhttps://www\.npmjs\.com\fR
good folks at npm, Inc\. \fIhttp://www\.npmjs\.com\fR
.
.SH "I have a question or request not addressed here\. Where should I put it?"
Post an issue on the github project:
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-INDEX" "7" "May 2014" "" ""
.TH "NPM\-INDEX" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-index\fR \-\- Index of all npm documentation
@@ -159,6 +159,9 @@ Display npm bin folder
npm apihelp .SH "npm\-bugs"
Bugs for a package in a web browser maybe
.
npm apihelp .SH "npm\-cache"
manage the npm cache programmatically
.
npm apihelp .SH "npm\-commands"
npm commands
.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-REGISTRY" "7" "May 2014" "" ""
.TH "NPM\-REGISTRY" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-registry\fR \-\- The JavaScript Package Registry
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-SCRIPTS" "7" "May 2014" "" ""
.TH "NPM\-SCRIPTS" "7" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-scripts\fR \-\- How npm handles the "scripts" field
@@ -63,7 +63,7 @@ stop and start scripts if no \fBrestart\fR script is provided\.
.IP "" 0
.
.P
Additionally, arbitrary scripts can be run by doing \fBnpm run\-script <stage> <pkg>\fR\|\.
Additionally, arbitrary scripts can be run by doing \fBnpm run\-script <pkg> <stage>\fR\|\.
.
.SH "NOTE: INSTALL SCRIPTS ARE AN ANTIPATTERN"
\fBtl;dr\fR Don\'t use \fBinstall\fR\|\. Use a \fB\|\.gyp\fR file for compilation, and \fBprepublish\fR for anything else\.
@@ -1,7 +1,7 @@
.\" Generated with Ronnjs 0.3.8
.\" http://github.com/kapouer/ronnjs/
.
.TH "NPM\-REMOVAL" "1" "May 2014" "" ""
.TH "NPM\-REMOVAL" "1" "June 2014" "" ""
.
.SH "NAME"
\fBnpm-removal\fR \-\- Cleaning the Slate