diff options
author | isaacs <i@izs.me> | 2011-12-13 18:53:02 -0800 |
---|---|---|
committer | isaacs <i@izs.me> | 2011-12-14 14:17:16 -0800 |
commit | bb9316da28feaad035eb2f61aeafc5f1a7a57ae2 (patch) | |
tree | 2ee858b80a3819c3c1d10c96932637261f5f0ca2 /deps/npm/lib | |
parent | f490934c33bdf134cfb24c6f26975a7e26d64953 (diff) | |
download | node-new-bb9316da28feaad035eb2f61aeafc5f1a7a57ae2.tar.gz |
npm 1.1.0-beta-2
Diffstat (limited to 'deps/npm/lib')
-rw-r--r-- | deps/npm/lib/adduser.js | 8 | ||||
-rw-r--r-- | deps/npm/lib/bugs.js | 4 | ||||
-rw-r--r-- | deps/npm/lib/cache.js | 107 | ||||
-rw-r--r-- | deps/npm/lib/init.js | 69 | ||||
-rw-r--r-- | deps/npm/lib/install.js | 2 | ||||
-rw-r--r-- | deps/npm/lib/npm.js | 4 | ||||
-rw-r--r-- | deps/npm/lib/rebuild.js | 30 | ||||
-rw-r--r-- | deps/npm/lib/search.js | 73 | ||||
-rw-r--r-- | deps/npm/lib/substack.js | 10 | ||||
-rw-r--r-- | deps/npm/lib/unpublish.js | 9 | ||||
-rw-r--r-- | deps/npm/lib/utils/config-defs.js | 12 | ||||
-rw-r--r-- | deps/npm/lib/utils/excludes.js | 2 | ||||
-rw-r--r-- | deps/npm/lib/utils/fetch.js | 9 | ||||
-rw-r--r-- | deps/npm/lib/utils/get-agent.js | 2 | ||||
-rw-r--r-- | deps/npm/lib/utils/ini.js | 2 | ||||
-rw-r--r-- | deps/npm/lib/utils/lifecycle.js | 5 | ||||
-rw-r--r-- | deps/npm/lib/utils/log.js | 19 | ||||
-rw-r--r-- | deps/npm/lib/utils/npm-registry-client/get.js | 11 | ||||
-rw-r--r-- | deps/npm/lib/utils/npm-registry-client/publish.js | 11 | ||||
-rw-r--r-- | deps/npm/lib/utils/npm-registry-client/request.js | 6 | ||||
-rw-r--r-- | deps/npm/lib/utils/prompt.js | 69 | ||||
-rw-r--r-- | deps/npm/lib/utils/tar.js | 22 |
22 files changed, 312 insertions, 174 deletions
diff --git a/deps/npm/lib/adduser.js b/deps/npm/lib/adduser.js index b6d08ed760..d65eed5952 100644 --- a/deps/npm/lib/adduser.js +++ b/deps/npm/lib/adduser.js @@ -5,7 +5,7 @@ var registry = require("./utils/npm-registry-client/index.js") , ini = require("./utils/ini.js") , log = require("./utils/log.js") , npm = require("./npm.js") - , prompt = require("./utils/prompt.js") + , read = require("read") , promiseChain = require("./utils/promise-chain.js") , crypto @@ -26,15 +26,15 @@ function adduser (args, cb) { , changed = false promiseChain(cb) - (prompt, ["Username: ", u.u], function (un) { + (read, [{prompt: "Username: ", default: u.u}], function (un) { changed = u.u !== un u.u = un }) (function (cb) { if (u.p && !changed) return cb(null, u.p) - prompt("Password: ", u.p, true, cb) + read({prompt: "Password: ", default: u.p, silent: true}, cb) }, [], function (pw) { u.p = pw }) - (prompt, ["Email: ", u.e], function (em) { u.e = em }) + (read, [{prompt: "Email: ", default: u.e}], function (em) { u.e = em }) (function (cb) { if (changed) npm.config.del("_auth") registry.adduser(u.u, u.p, u.e, function (er) { diff --git a/deps/npm/lib/bugs.js b/deps/npm/lib/bugs.js index 1c52ffda0e..a3a017cc02 100644 --- a/deps/npm/lib/bugs.js +++ b/deps/npm/lib/bugs.js @@ -23,8 +23,8 @@ function bugs (args, cb) { var bugs = d.bugs , repo = d.repository || d.repositories if (bugs) { - if (typeof bugs === "string") return open(bugs, cb) - if (bugs.url) return open(bugs.url, cb) + if (typeof bugs === "string") return open(bugs, cb) + if (bugs.url) return open(bugs.url, cb) } if (repo) { if (Array.isArray(repo)) repo = repo.shift() diff --git a/deps/npm/lib/cache.js b/deps/npm/lib/cache.js index 7260ab61a3..a73a874621 100644 --- a/deps/npm/lib/cache.js +++ b/deps/npm/lib/cache.js @@ -105,9 +105,7 @@ function read (name, ver, forceBypass, cb) { return cb(er, data) } - if (forceBypass - && (npm.config.get("force") - || process.platform === "cygwin")) { + if (forceBypass && npm.config.get("force")) { log.verbose(true, "force found, skipping cache") return addNamed(name, ver, c) } @@ -335,7 +333,7 @@ function addRemoteGit (u, parsed, name, cb_) { // name@blah thing. var inFlightNames = {} function addNamed (name, x, cb_) { - log.info([name, x], "addNamed") + log.verbose([name, x], "addNamed") var k = name + "@" + x if (!inFlightNames[k]) inFlightNames[k] = [] var iF = inFlightNames[k] @@ -368,10 +366,11 @@ function addNameTag (name, tag, cb) { engineFilter(data) if (data["dist-tags"] && data["dist-tags"][tag] && data.versions[data["dist-tags"][tag]]) { - return addNameVersion(name, data["dist-tags"][tag], cb) + var ver = data["dist-tags"][tag] + return addNameVersion(name, ver, data.versions[ver], cb) } if (!explicit && Object.keys(data.versions).length) { - return addNameRange(name, "*", cb) + return addNameRange(name, "*", data, cb) } return cb(installTargetsError(tag, data)) }) @@ -393,24 +392,84 @@ function engineFilter (data) { }) } -function addNameRange (name, range, cb) { +function addNameRange (name, range, data, cb) { + if (typeof cb !== "function") cb = data, data = null + range = semver.validRange(range) if (range === null) return cb(new Error( "Invalid version range: "+range)) - registry.get(name, function (er, data, json, response) { + + log.silly([name, range, !!data], "name, range, hasData") + + if (data) return next() + registry.get(name, function (er, d, json, response) { if (er) return cb(er) + data = d + next() + }) + + function next () { + log.silly([name, range, !!data], "name, range, hasData 2") engineFilter(data) + + if (npm.config.get("registry")) return next_() + + cachedFilter(data, range, function (er) { + if (er) return cb(er) + if (Object.keys(data.versions).length === 0) { + return cb(new Error( "Can't fetch, and not cached: " + + data.name + "@" + range)) + } + next_() + }) + } + + function next_ () { + log.silly([data.name, Object.keys(data.versions)], "versions") // if the tagged version satisfies, then use that. var tagged = data["dist-tags"][npm.config.get("tag")] if (tagged && data.versions[tagged] && semver.satisfies(tagged, range)) { - return addNameVersion(name, tagged, cb) + return addNameVersion(name, tagged, data.versions[tagged], cb) } + // find the max satisfying version. var ms = semver.maxSatisfying(Object.keys(data.versions || {}), range) if (!ms) { return cb(installTargetsError(range, data)) } - addNameVersion(name, ms, cb) + + // if we don't have a registry connection, try to see if + // there's a cached copy that will be ok. + addNameVersion(name, ms, data.versions[ms], cb) + } +} + +// filter the versions down based on what's already in cache. +function cachedFilter (data, range, cb) { + log.silly(data.name, "cachedFilter") + ls_(data.name, 1, function (er, files) { + if (er) return log.er(cb, "Not in cache, can't fetch: "+data.name)(er) + files = files.map(function (f) { + return path.basename(f.replace(/(\\|\/)$/, "")) + }).filter(function (f) { + return semver.valid(f) && semver.satisfies(f, range) + }) + + if (files.length === 0) { + return cb(new Error("Not in cache, can't fetch: "+data.name+"@"+range)) + } + + log.silly([data.name, files], "cached") + Object.keys(data.versions).forEach(function (v) { + if (files.indexOf(v) === -1) delete data.versions[v] + }) + + if (Object.keys(data.versions).length === 0) { + return log.er(cb, "Not in cache, can't fetch: "+data.name)(er) + } + + log.silly([data.name, Object.keys(data.versions)], "filtered") + cb(null, data) }) } @@ -430,11 +489,26 @@ function installTargetsError (requested, data) { + requested + "\n" + targets) } -function addNameVersion (name, ver, cb) { +function addNameVersion (name, ver, data, cb) { + if (typeof cb !== "function") cb = data, data = null + ver = semver.valid(ver) if (ver === null) return cb(new Error("Invalid version: "+ver)) - registry.get(name, ver, function (er, data, json, response) { + + var response + + if (data) { + response = null + return next() + } + registry.get(name, ver, function (er, d, json, resp) { if (er) return cb(er) + data = d + response = resp + next() + }) + + function next () { deprCheck(data) var dist = data.dist @@ -452,8 +526,7 @@ function addNameVersion (name, ver, cb) { if (!dist.tarball) return cb(new Error( "No dist.tarball in " + data._id + " package")) - if (response.statusCode !== 304 || npm.config.get("force") - || process.platform === "cygwin") { + if ((response && response.statusCode !== 304) || npm.config.get("force")) { return fetchit() } @@ -469,6 +542,10 @@ function addNameVersion (name, ver, cb) { }) function fetchit () { + if (!npm.config.get("registry")) { + return cb(new Error("Cannot fetch: "+dist.tarball)) + } + // use the same protocol as the registry. // https registry --> https tarballs. var tb = url.parse(dist.tarball) @@ -480,7 +557,7 @@ function addNameVersion (name, ver, cb) { , name+"-"+ver , cb ) } - }) + } } function addLocal (p, name, cb_) { diff --git a/deps/npm/lib/init.js b/deps/npm/lib/init.js index 950cb45885..ee7e8773af 100644 --- a/deps/npm/lib/init.js +++ b/deps/npm/lib/init.js @@ -3,7 +3,7 @@ module.exports = init -var prompt = require("./utils/prompt.js") +var read = require("read") , path = require("path") , readJson = require("./utils/read-json.js") , fs = require("graceful-fs") @@ -66,24 +66,26 @@ function init_ (data, folder, cb) { ,"" ].join("\n")) promiseChain(cb) - ( prompt - , ["Package name: ", defaultName(folder, data)] + ( read + , [{prompt: "Package name: ", default: defaultName(folder, data)}] , function (n) { data.name = n } ) - ( prompt - , ["Description: ", data.description] + ( read + , [{prompt: "Description: ", default: data.description}] , function (d) { data.description = d } ) ( defaultVersion, [folder, data], function (v) { data.version = v } ) (function (cb) { - prompt("Package version: ", data.version, function (er, v) { + read( { prompt: "Package version: ", default: data.version } + , function (er, v) { if (er) return cb(er) data.version = v cb() }) }, []) - ( prompt - , ["Project homepage: ", data.homepage || data.url || "none"] + ( read + , [ { prompt: "Project homepage: " + , default: data.homepage || data.url || "none" } ] , function (u) { if (u === "none") return data.homepage = u @@ -92,40 +94,42 @@ function init_ (data, folder, cb) { ) ( defaultRepo, [folder, data], function (r) { data.repository = r } ) (function (cb) { - prompt( "Project git repository: " - , data.repository && data.repository.url || "none" - , function (er, r) { - if (er) return cb(er) - if (r !== "none") { - data.repository = (data.repository || {}).url = r - } - cb() + read( { prompt: "Project git repository: " + , default: data.repository && data.repository.url || "none" } + , function (er, r) { + if (er) return cb(er) + if (r !== "none") { + data.repository = (data.repository || {}).url = r } - ) + cb() + } + ) }, []) - ( prompt - , ["Author name: ", data.author && data.author.name] + ( read + , [{ prompt: "Author name: ", default: data.author && data.author.name }] , function (n) { if (!n) return (data.author = data.author || {}).name = n } ) - ( prompt - , ["Author email: ", data.author && data.author.email || "none"] + ( read + , [ { prompt: "Author email: " + , default: data.author && data.author.email || "none" } ] , function (n) { if (n === "none") return (data.author = data.author || {}).email = n } ) - ( prompt - , ["Author url: ", data.author && data.author.url || "none"] + ( read + , [ { prompt: "Author url: " + , default: data.author && data.author.url || "none" } ] , function (n) { if (n === "none") return (data.author = data.author || {}).url = n } ) - ( prompt - , ["Main module/entry point: ", data.main || "none"] + ( read + , [ { prompt: "Main module/entry point: ", default: data.main || "none" } ] , function (m) { if (m === "none") { delete data.main @@ -134,18 +138,17 @@ function init_ (data, folder, cb) { data.main = m } ) - ( prompt - , ["Test command: ", data.scripts && data.scripts.test || "none"] + ( read + , [ { prompt: "Test command: " + , default: data.scripts && data.scripts.test || "none" } ] , function (t) { if (t === "none") return (data.scripts = data.scripts || {}).test = t } ) - ( prompt - , [ "What versions of node does it run on? " - , data.engines && data.engines.node - || (eng) - ] + ( read + , [ { prompt: "What versions of node does it run on? " + , default: data.engines && data.engines.node || (eng) } ] , function (nodever) { (data.engines = data.engines || {}).node = nodever } @@ -167,7 +170,7 @@ function init_ (data, folder, cb) { output.write(msg, cb) }) (function (cb) { - prompt("\nIs this ok? ", "yes", function (er, ok) { + read({ prompt: "\nIs this ok? ", default: "yes" }, function (er, ok) { if (er) return cb(er) if (ok.toLowerCase().charAt(0) !== "y") { return cb(new Error("cancelled")) diff --git a/deps/npm/lib/install.js b/deps/npm/lib/install.js index 4d71b9a512..ca54585e03 100644 --- a/deps/npm/lib/install.js +++ b/deps/npm/lib/install.js @@ -565,7 +565,7 @@ function write (target, targetFolder, family, ancestors, cb_) { // cache.unpack returns the data object, and all we care about // is the list of installed packages from that last thing. if (!er) return cb_(er, data) - log.error(er, "error installing "+target._id) + log.error(target._id,"error installing") if (false === npm.config.get("rollback")) return cb_(er) npm.commands.unbuild([targetFolder], function (er2) { if (er2) log.error(er2, "error rolling back "+target._id) diff --git a/deps/npm/lib/npm.js b/deps/npm/lib/npm.js index 51f7d64b88..44a687f99d 100644 --- a/deps/npm/lib/npm.js +++ b/deps/npm/lib/npm.js @@ -11,9 +11,6 @@ if (typeof WScript !== "undefined") { } -process.title = "npm" - - // FIXME there really ought to be a path.split in node core require("path").SPLIT_CHAR = process.platform === "win32" ? "\\" : "/" @@ -166,6 +163,7 @@ var commandCache = {} , plumbing = [ "build" , "unbuild" , "xmas" + , "substack" ] , fullList = npm.fullList = cmdList.concat(aliasNames).filter(function (c) { return plumbing.indexOf(c) === -1 diff --git a/deps/npm/lib/rebuild.js b/deps/npm/lib/rebuild.js index f3f7596204..fc5f96825d 100644 --- a/deps/npm/lib/rebuild.js +++ b/deps/npm/lib/rebuild.js @@ -7,6 +7,9 @@ var readInstalled = require("./utils/read-installed.js") , path = require("path") , npm = require("./npm.js") , output = require("./utils/output.js") + , asyncMap = require("slide").asyncMap + , fs = require("graceful-fs") + , exec = require("./utils/exec.js") rebuild.usage = "npm rebuild [<name>[@<version>] [name[@<version>] ...]]" @@ -22,6 +25,33 @@ function rebuild (args, cb) { }) if (!folders.length) return cb() log.silly(folders, "rebuild set") + cleanBuild(folders, set, cb) + }) +} + +function cleanBuild (folders, set, cb) { + // https://github.com/isaacs/npm/issues/1872 + // If there's a makefile, try 'make clean' + // If there's a wscript, try 'node-waf clean' + // But don't die on either of those if they fail. + // Just a best-effort kind of deal. + asyncMap(folders, function (f, cb) { + fs.readdir(f, function (er, files) { + // everything should be a dir. + if (er) return cb(er) + if (files.indexOf("wscript") !== -1) { + exec("node-waf", ["clean"], null, false, f, thenBuild) + } else if (files.indexOf("Makefile") !== -1) { + exec("make", ["clean"], null, false, f, thenBuild) + } else thenBuild() + }) + function thenBuild (er) { + // ignore error, just continue + // it could be that it's not configured yet or whatever. + cb() + } + }, function (er) { + if (er) return cb(er) npm.commands.build(folders, function (er) { if (er) return cb(er) output.write(folders.map(function (f) { diff --git a/deps/npm/lib/search.js b/deps/npm/lib/search.js index 45e436a0c1..92f4319f58 100644 --- a/deps/npm/lib/search.js +++ b/deps/npm/lib/search.js @@ -82,13 +82,19 @@ function filter (data, args, notArgs) { } function stripData (data) { - return { name:data.name - , description:npm.config.get("description") ? data.description : "" - , maintainers:(data.maintainers || []).map(function (m) { + return { name: data.name + , description: npm.config.get("description") ? data.description : "" + , maintainers: (data.maintainers || []).map(function (m) { return "=" + m.name }) - , url:!Object.keys(data.versions || {}).length ? data.url : null - , keywords:data.keywords || [] + , url: !Object.keys(data.versions || {}).length ? data.url : null + , keywords: data.keywords || [] + , time: data.time + && data.time.modified + && (new Date(data.time.modified).toISOString() + .split("T").join(" ") + .replace(/:[0-9]{2}\.[0-9]{3}Z$/, "")) + || "(prehistoric)" } } @@ -108,16 +114,23 @@ function getWords (data) { function filterWords (data, args, notArgs) { var words = data.words for (var i = 0, l = args.length; i < l; i ++) { - if (words.indexOf(args[i]) === -1) { - return false - } + if (!match(words, args[i])) return false } for (var i = 0, l = notArgs.length; i < l; i ++) { - if (words.indexOf(notArgs[i]) !== -1) return false + if (match(words, notArgs[i])) return false } return true } +function match (words, arg) { + if (arg.charAt(0) === "/") { + arg = arg.replace(/\/$/, "") + arg = new RegExp(arg.substr(1, arg.length - 1)) + return words.match(arg) + } + return words.indexOf(arg) !== -1 +} + function prettify (data, args) { try { var tty = require("tty") @@ -130,14 +143,24 @@ function prettify (data, args) { // name, desc, author, keywords var longest = [] , spaces - , maxLen = [20, 60, 20, Infinity] - , headings = ["NAME", "DESCRIPTION", "AUTHOR", "KEYWORDS"] + , maxLen = npm.config.get("description") + ? [20, 60, 20, 20, Infinity] + : [20, 20, 20, Infinity] + , headings = npm.config.get("description") + ? ["NAME", "DESCRIPTION", "AUTHOR", "DATE", "KEYWORDS"] + : ["NAME", "AUTHOR", "DATE", "KEYWORDS"] , lines + , searchsort = (npm.config.get("searchsort") || "NAME").toLowerCase() + , sortFields = { name: 0 + , description: 1 + , author: 2 + , date: 3 + , keywords: 4 } + , searchRev = searchsort.charAt(0) === "-" + , sortField = sortFields[searchsort.replace(/^\-+/, "")] lines = Object.keys(data).map(function (d) { return data[d] - }).filter(function (data) { - return data.name }).map(function (data) { // turn a pkg data into a string // [name,who,desc,targets,keywords] tuple @@ -149,6 +172,7 @@ function prettify (data, args) { var l = [ data.name , data.description || "" , data.maintainers.join(" ") + , data.time , (data.keywords || []).join(" ") ] l.forEach(function (s, i) { @@ -162,6 +186,13 @@ function prettify (data, args) { l[i] = l[i].replace(/\s+/g, " ") }) return l + }).sort(function (a, b) { + // a and b are "line" objects of [name, desc, maint, time, kw] + var aa = a[sortField].toLowerCase() + , bb = b[sortField].toLowerCase() + return aa === bb ? 0 + : aa < bb ? (searchRev ? 1 : -1) + : (searchRev ? -1 : 1) }).map(function (line) { return line.map(function (s, i) { spaces = spaces || longest.map(function (n) { @@ -173,8 +204,6 @@ function prettify (data, args) { } return s + spaces[i].substr(len) }).join(" ").substr(0, cols).trim() - }).sort(function (a, b) { - return a === b ? 0 : a > b ? 1 : -1 }).map(function (line) { // colorize! args.forEach(function (arg, i) { @@ -201,8 +230,18 @@ function addColorMarker (str, arg, i) { var m = i % cl + 1 , markStart = String.fromCharCode(m) , markEnd = String.fromCharCode(0) - , pieces = str.toLowerCase().split(arg.toLowerCase()) + + if (arg.charAt(0) === "/") { + //arg = arg.replace(/\/$/, "") + return str.replace( new RegExp(arg.substr(1, arg.length - 1), "gi") + , function (bit) { return markStart + bit + markEnd } ) + + } + + // just a normal string, do the split/map thing + var pieces = str.toLowerCase().split(arg.toLowerCase()) , p = 0 + return pieces.map(function (piece, i) { piece = str.substr(p, piece.length) var mark = markStart @@ -211,8 +250,8 @@ function addColorMarker (str, arg, i) { p += piece.length + arg.length return piece + mark }).join("") - return str.split(arg).join(mark) } + function colorize (line) { for (var i = 0; i < cl; i ++) { var m = i + 1 diff --git a/deps/npm/lib/substack.js b/deps/npm/lib/substack.js new file mode 100644 index 0000000000..95a90f8246 --- /dev/null +++ b/deps/npm/lib/substack.js @@ -0,0 +1,10 @@ +module.exports = substack +var npm = require("./npm.js") + , log = require("./utils/log.js") + +function substack (args, cb) { + console.log("\033[32mbeep \033[35mboop\033[m") + var c = args.shift() + if (c) npm.commands[c](args, cb) + else cb() +} diff --git a/deps/npm/lib/unpublish.js b/deps/npm/lib/unpublish.js index 2945a7887f..b7f6cbec89 100644 --- a/deps/npm/lib/unpublish.js +++ b/deps/npm/lib/unpublish.js @@ -39,10 +39,19 @@ unpublish.completion = function (opts, cb) { } function unpublish (args, cb) { + + if (args.length > 1) return cb(unpublish.usage) + var thing = args.length ? args.shift().split("@") : [] , project = thing.shift() , version = thing.join("@") + if (!version && !npm.config.get("force")) { + return cb("Refusing to delete entire project.\n" + +"Run with --force to do this.\n" + +unpublish.usage) + } + if (!project || path.resolve(project) === npm.prefix) { // if there's a package.json in the current folder, then // read the package name and version out of that. diff --git a/deps/npm/lib/utils/config-defs.js b/deps/npm/lib/utils/config-defs.js index c0ed1fca88..c4663b5820 100644 --- a/deps/npm/lib/utils/config-defs.js +++ b/deps/npm/lib/utils/config-defs.js @@ -141,6 +141,7 @@ Object.defineProperty(exports, "defaults", {get: function () { : path.resolve( home || temp, ".npm") , color : process.platform !== "win32" || winColor + , coverage: false , depth: Infinity , description : true , dev : false @@ -159,7 +160,7 @@ Object.defineProperty(exports, "defaults", {get: function () { , "init.author.url" : "" , link: false , logfd : 2 - , loglevel : "warn" + , loglevel : "http" , logprefix : process.platform !== "win32" || winColor , long : false , message : "%s" @@ -182,6 +183,7 @@ Object.defineProperty(exports, "defaults", {get: function () { , save : false , searchopts: "" , searchexclude: null + , searchsort: "name" , shell : process.platform === "win32" ? process.env.ComSpec || "cmd" : process.env.SHELL || "bash" @@ -216,6 +218,7 @@ exports.types = , ca: [null, String] , cache : path , color : ["always", Boolean] + , coverage: Boolean , depth : Number , description : Boolean , dev : Boolean @@ -233,7 +236,7 @@ exports.types = , "init.author.url" : ["", url] , link: Boolean , logfd : [Number, Stream] - , loglevel : ["silent","win","error","warn","info","verbose","silly"] + , loglevel : ["silent","win","error","warn","http","info","verbose","silly"] , logprefix : Boolean , long : Boolean , message: String @@ -254,6 +257,11 @@ exports.types = , save : Boolean , searchopts : String , searchexclude: [null, String] + , searchsort: [ "name", "-name" + , "description", "-description" + , "author", "-author" + , "date", "-date" + , "keywords", "-keywords" ] , shell : String , "strict-ssl": Boolean , tag : String diff --git a/deps/npm/lib/utils/excludes.js b/deps/npm/lib/utils/excludes.js index 6df89ccaf4..c9920670f7 100644 --- a/deps/npm/lib/utils/excludes.js +++ b/deps/npm/lib/utils/excludes.js @@ -98,7 +98,7 @@ function test (file, excludeList) { // chop the filename down to be relative to excludeDir var rf = relativize(file, dir, true) - rf = rf.replace(/^\.\//, "") + rf = rf.replace(/^\.?\//, "") for (var ii = 0, ll = excludes.length; ii < ll; ii ++) { //log.warn(JSON.stringify(excludes[ii]), "ex") diff --git a/deps/npm/lib/utils/fetch.js b/deps/npm/lib/utils/fetch.js index 726be8848b..fcb413986f 100644 --- a/deps/npm/lib/utils/fetch.js +++ b/deps/npm/lib/utils/fetch.js @@ -16,7 +16,6 @@ module.exports = fetch function fetch (remote, local, headers, cb) { if (typeof cb !== "function") cb = headers, headers = {} - log.info(remote, "fetch") log.verbose(local, "fetch to") mkdir(path.dirname(local), function (er) { if (er) return cb(er) @@ -42,6 +41,7 @@ function fetch_ (remote, local, headers, cb) { function makeRequest (remote, fstr, headers) { remote = url.parse(remote) + log.http(remote.href, "GET") regHost = regHost || url.parse(npm.config.get("registry")).host if (remote.host === regHost && npm.config.get("always-auth")) { @@ -58,5 +58,10 @@ function makeRequest (remote, fstr, headers) { request({ url: remote , proxy: proxy , agent: getAgent(remote) - , strictSSL: npm.config.get("strict-ssl") }).pipe(fstr) + , strictSSL: npm.config.get("strict-ssl") + , onResponse: onResponse }).pipe(fstr) + function onResponse (er, res) { + if (er) return cb(er) + log.http(res.statusCode + " " + remote.href) + } } diff --git a/deps/npm/lib/utils/get-agent.js b/deps/npm/lib/utils/get-agent.js index b4a5738d2d..4bc074f29b 100644 --- a/deps/npm/lib/utils/get-agent.js +++ b/deps/npm/lib/utils/get-agent.js @@ -13,7 +13,7 @@ var npm = require("../npm.js") , url = require("url") , agents = {} , isHttp2 = !!require("http").globalAgent - , registry = url.parse(npm.config.get("registry")) + , registry = url.parse(npm.config.get("registry") || "") , regCA = npm.config.get("ca") function getAgent (remote) { diff --git a/deps/npm/lib/utils/ini.js b/deps/npm/lib/utils/ini.js index 7d7d4680ec..ac45c8bc5e 100644 --- a/deps/npm/lib/utils/ini.js +++ b/deps/npm/lib/utils/ini.js @@ -162,6 +162,8 @@ function parseEnv (env) { Object.keys(env) .filter(function (k) { return k.match(/^npm_config_[^_]/i) }) .forEach(function (k) { + if (!env[k]) return + conf[k.replace(/^npm_config_/i, "") .toLowerCase() .replace(/_/g, "-")] = parseField(env[k], k) diff --git a/deps/npm/lib/utils/lifecycle.js b/deps/npm/lib/utils/lifecycle.js index 878fc88cf3..547bbef0eb 100644 --- a/deps/npm/lib/utils/lifecycle.js +++ b/deps/npm/lib/utils/lifecycle.js @@ -232,7 +232,10 @@ function makeEnv (data, prefix, env) { if (i.charAt(0) === "_" && i.indexOf("_"+namePref) !== 0) { return } - var value = String(ini.get(i)) + var value = ini.get(i) + if (!value) value = "" + else if (typeof value !== "string") value = JSON.stringify(value) + value = -1 !== value.indexOf("\n") ? JSON.stringify(value) : value diff --git a/deps/npm/lib/utils/log.js b/deps/npm/lib/utils/log.js index dece9e3d19..07867e3e96 100644 --- a/deps/npm/lib/utils/log.js +++ b/deps/npm/lib/utils/log.js @@ -1,21 +1,4 @@ -/* -log levels: -0,1,2,3 -verbose,info,warn,error - -Default setting for logs is "info" -Default setting to show is "info" - -Possible values of level/loglevel: -silly,verbose,info,warn,error,win,silent - -silent quiets everything - - -*/ - - module.exports = log var output = require("./output.js") @@ -28,6 +11,7 @@ var l = -1 , LEVEL = { silly : l++ , verbose : l++ , info : l++ + , "http" : l++ , WARN : l++ , "ERR!" : l++ , ERROR : "ERR!" @@ -59,6 +43,7 @@ Object.keys(LEVEL).forEach(function (l) { COLOR[LEVEL.silly] = 30 COLOR[LEVEL.verbose] = "34;40" COLOR[LEVEL.info] = 32 +COLOR[LEVEL.http] = "32;40" COLOR[LEVEL.warn] = "30;41" COLOR[LEVEL.error] = "31;40" for (var c in COLOR) COLOR[LEVEL[c]] = COLOR[c] diff --git a/deps/npm/lib/utils/npm-registry-client/get.js b/deps/npm/lib/utils/npm-registry-client/get.js index 062244df3a..375bb5f972 100644 --- a/deps/npm/lib/utils/npm-registry-client/get.js +++ b/deps/npm/lib/utils/npm-registry-client/get.js @@ -119,6 +119,13 @@ function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) { } GET(uri, etag, nofollow, function (er, remoteData, raw, response) { + // if we get an error talking to the registry, but we have it + // from the cache, then just pretend we got it. + if (er && cache) { + er = null + response = {statusCode: 304} + } + if (response) { log.silly([response.statusCode, response.headers], "get cb") if (response.statusCode === 304 && etag) { @@ -128,6 +135,10 @@ function get_ (uri, timeout, cache, stat, data, nofollow, staleOk, cb) { } data = remoteData + if (!data) { + er = new Error("failed to fetch from registry: " + uri) + } + if (er) return cb(er, data, raw, response) // just give the write the old college try. if it fails, whatever. diff --git a/deps/npm/lib/utils/npm-registry-client/publish.js b/deps/npm/lib/utils/npm-registry-client/publish.js index 86cfdc6a89..a196a3c072 100644 --- a/deps/npm/lib/utils/npm-registry-client/publish.js +++ b/deps/npm/lib/utils/npm-registry-client/publish.js @@ -13,7 +13,7 @@ var request = require("./request.js") , url = require("url") function publish (data, prebuilt, readme, cb) { - if (typeof readme === "function") cb = readme, readme = null + if (typeof readme === "function") cb = readme, readme = "" if (typeof prebuilt === "function") cb = prebuilt, prebuilt = null // add the dist-url to the data, pointing at the tarball. // if the {name} isn't there, then create it. @@ -23,13 +23,15 @@ function publish (data, prebuilt, readme, cb) { var registry = reg() if (registry instanceof Error) return cb(registry) + readme = readme ? "" + readme : "" + var fullData = { _id : data.name , name : data.name , description : data.description , "dist-tags" : {} , versions : {} - , readme: readme ? "" + readme : null + , readme: readme , maintainers : [ { name : npm.config.get("username") , email : npm.config.get("email") @@ -103,6 +105,11 @@ function publish (data, prebuilt, readme, cb) { }) } + // this way, it'll also get attached to packages that were previously + // published with a version of npm that lacked this feature. + if (!fullData.readme) { + data.readme = readme + } PUT(dataURI, data, function (er) { if (er) { if (er.message.indexOf("conflict Document update conflict.") === 0) { diff --git a/deps/npm/lib/utils/npm-registry-client/request.js b/deps/npm/lib/utils/npm-registry-client/request.js index d19e3ac31f..d98135e49e 100644 --- a/deps/npm/lib/utils/npm-registry-client/request.js +++ b/deps/npm/lib/utils/npm-registry-client/request.js @@ -23,8 +23,6 @@ function regRequest (method, where, what, etag, nofollow, cb_) { if (typeof cb_ !== "function") cb_ = etag, etag = null if (typeof cb_ !== "function") cb_ = what, what = null - log.verbose(where||"/", method) - // Since there are multiple places where an error could occur, // don't let the cb be called more than once. var errState = null @@ -119,6 +117,8 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb) { opts.followRedirect = false } + log.http(remote.href || "/", method) + var req = request(opts, requestDone(method, where, cb)) var r = npm.config.get("registry") if (!r) { @@ -136,6 +136,8 @@ function makeRequest (method, remote, where, what, etag, nofollow, cb) { function requestDone (method, where, cb) { return function (er, response, data) { if (er) return cb(er) + log.http(response.statusCode + " " + url.parse(where).href) + var parsed if (Buffer.isBuffer(data)) { diff --git a/deps/npm/lib/utils/prompt.js b/deps/npm/lib/utils/prompt.js deleted file mode 100644 index d23e4ac587..0000000000 --- a/deps/npm/lib/utils/prompt.js +++ /dev/null @@ -1,69 +0,0 @@ - -module.exports = prompt - -var log = require("./log.js") - , buffer = "" - , tty = require("tty") - -function prompt (p, def, silent, cb) { - if (!cb) cb = silent, silent = false - if (!cb) cb = def, def = null - if (def) p += "("+(silent ? "<hidden>" : def)+") " - var r = (silent ? silentRead : read).bind(null, def, cb) - if (!process.stdout.write(p)) process.stdout.on("drain", function D () { - process.stdout.removeListener("drain", D) - r() - }) - else r() -} - -function read (def, cb) { - var stdin = process.openStdin() - , val = "" - stdin.resume() - stdin.setEncoding("utf8") - stdin.on("error", cb) - stdin.on("data", function D (chunk) { - val += buffer + chunk - buffer = "" - val = val.replace(/\r/g, '') - if (val.indexOf("\n") !== -1) { - if (val !== "\n") val = val.replace(/^\n+/, "") - buffer = val.substr(val.indexOf("\n")) - val = val.substr(0, val.indexOf("\n")) - stdin.pause() - stdin.removeListener("data", D) - stdin.removeListener("error", cb) - val = val.trim() || def - cb(null, val) - } - }) -} - -function silentRead (def, cb) { - var stdin = process.openStdin() - , val = "" - tty.setRawMode(true) - stdin.resume() - stdin.on("error", cb) - stdin.on("data", function D (c) { - c = "" + c - switch (c) { - case "\n": case "\r": case "\r\n": case "\u0004": - tty.setRawMode(false) - stdin.removeListener("data", D) - stdin.removeListener("error", cb) - val = val.trim() || def - process.stdout.write("\n") - stdin.pause() - return cb(null, val) - case "\u0003": case "\0": - return cb("cancelled") - break - default: - val += buffer + c - buffer = "" - break - } - }) -} diff --git a/deps/npm/lib/utils/tar.js b/deps/npm/lib/utils/tar.js index 2c2b96f9a6..f315bbf961 100644 --- a/deps/npm/lib/utils/tar.js +++ b/deps/npm/lib/utils/tar.js @@ -29,7 +29,10 @@ exports.makeList = makeList function pack (targetTarball, folder, pkg, dfc, cb) { if (typeof cb !== "function") cb = dfc, dfc = true - folder = path.resolve(process.cwd(), folder) + folder = path.resolve(folder) + + log.verbose(folder, "pack") + if (typeof pkg === "function") { cb = pkg, pkg = null return readJson(path.resolve(folder, "package.json"), function (er, pkg) { @@ -88,7 +91,22 @@ function packFiles (targetTarball, parent, files, pkg, cb_) { // being installed from some wackey vm-mounted // read-only filesystem. this.props.mode = this.props.mode | 0200 - return -1 !== files.indexOf(this.path) + var inc = -1 !== files.indexOf(this.path) + + // WARNING! Hackety hack! + // XXX Fix this in a better way. + // Rename .gitignore to .npmignore if there is not a + // .npmignore file there already, the better to lock + // down installed packages with git for deployment. + if (this.basename === ".gitignore") { + if (this.parent._entries.indexOf(".npmignore") !== -1) { + return false + } + var d = path.dirname(this.path) + this.basename = ".npmignore" + this.path = path.join(d, ".npmignore") + } + return inc } }) .on("error", log.er(cb, "error reading "+parent)) |