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

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisaacs <i@izs.me>2014-05-14 04:44:56 +0400
committerisaacs <i@izs.me>2014-05-14 23:41:32 +0400
commit1707fcedb7503251eb77719aba7ac52931721205 (patch)
tree2dbb06489bdb58ecbb02d96464e0ce430b6675fd
parent08e0b101f3190d9548a6530096844674b16ce8d7 (diff)
npmconf@1.0.0, Refactor config/uid/prefix loading process
Closes #4751
-rw-r--r--lib/npm.js126
-rw-r--r--node_modules/npmconf/lib/find-prefix.js (renamed from lib/utils/find-prefix.js)5
-rw-r--r--node_modules/npmconf/lib/load-prefix.js51
-rw-r--r--node_modules/npmconf/lib/load-uid.js15
-rw-r--r--node_modules/npmconf/lib/set-user.js23
-rw-r--r--node_modules/npmconf/npmconf.js103
-rw-r--r--node_modules/npmconf/package.json13
-rw-r--r--node_modules/npmconf/test/basic.js13
-rw-r--r--node_modules/npmconf/test/builtin.js13
-rw-r--r--node_modules/npmconf/test/fixtures/.npmrc1
-rw-r--r--node_modules/npmconf/test/fixtures/package.json0
-rw-r--r--node_modules/npmconf/test/project.js85
-rw-r--r--package.json3
13 files changed, 285 insertions, 166 deletions
diff --git a/lib/npm.js b/lib/npm.js
index d1932a1e4..c0c744f99 100644
--- a/lib/npm.js
+++ b/lib/npm.js
@@ -24,11 +24,6 @@ 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")
@@ -42,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 {
@@ -370,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)
- })
- })
-}
-
-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 gp = Object.getOwnPropertyDescriptor(config, "globalPrefix")
+ Object.defineProperty(npm, "globalPrefix", gp)
-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)
- }
-}
+ var lp = Object.getOwnPropertyDescriptor(config, "localPrefix")
+ Object.defineProperty(npm, "localPrefix", lp)
-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
diff --git a/lib/utils/find-prefix.js b/node_modules/npmconf/lib/find-prefix.js
index a61d9e136..bb00cd6b1 100644
--- a/lib/utils/find-prefix.js
+++ b/node_modules/npmconf/lib/find-prefix.js
@@ -2,9 +2,8 @@
module.exports = findPrefix
-var fs = require("graceful-fs")
- , path = require("path")
- , npm = require("../npm.js")
+var fs = require("fs")
+var path = require("path")
function findPrefix (p, cb_) {
function cb (er, p) {
diff --git a/node_modules/npmconf/lib/load-prefix.js b/node_modules/npmconf/lib/load-prefix.js
new file mode 100644
index 000000000..c161b0649
--- /dev/null
+++ b/node_modules/npmconf/lib/load-prefix.js
@@ -0,0 +1,51 @@
+module.exports = loadPrefix
+
+var findPrefix = require("./find-prefix.js")
+var mkdirp = require("mkdirp")
+var path = require('path')
+
+function loadPrefix (cb) {
+ var cli = this.list[0]
+
+ // try to guess at a good node_modules location.
+ var p
+ , gp
+
+ if (!Object.prototype.hasOwnProperty.call(cli, "prefix")) {
+ p = process.cwd()
+ } else {
+ p = this.get("prefix")
+ }
+ gp = this.get("prefix")
+
+ findPrefix(p, function (er, p) {
+ Object.defineProperty(this, "localPrefix",
+ { get : function () { return p }
+ , set : function (r) { return p = r }
+ , enumerable : true
+ })
+ // the prefix MUST exist, or else nothing works.
+ if (!this.get("global")) {
+ mkdirp(p, next.bind(this))
+ } else {
+ next.bind(this)(er)
+ }
+ }.bind(this))
+
+ gp = path.resolve(gp)
+ Object.defineProperty(this, "globalPrefix",
+ { get : function () { return gp }
+ , set : function (r) { return gp = r }
+ , enumerable : true
+ })
+ // the prefix MUST exist, or else nothing works.
+ mkdirp(gp, next.bind(this))
+
+ var i = 2
+ var errState = null
+ function next (er) {
+ if (errState) return
+ if (er) return cb(errState = er)
+ if (--i === 0) return cb()
+ }
+}
diff --git a/node_modules/npmconf/lib/load-uid.js b/node_modules/npmconf/lib/load-uid.js
new file mode 100644
index 000000000..3ca798773
--- /dev/null
+++ b/node_modules/npmconf/lib/load-uid.js
@@ -0,0 +1,15 @@
+module.exports = loadUid
+
+var getUid = require("uid-number")
+
+// Call in the context of a npmconf object
+
+function loadUid (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 (!this.get("unsafe-perm")) {
+ getUid(this.get("user"), this.get("group"), cb)
+ } else {
+ process.nextTick(cb)
+ }
+}
diff --git a/node_modules/npmconf/lib/set-user.js b/node_modules/npmconf/lib/set-user.js
new file mode 100644
index 000000000..2e7774aec
--- /dev/null
+++ b/node_modules/npmconf/lib/set-user.js
@@ -0,0 +1,23 @@
+module.exports = setUser
+
+var path = require('path')
+var fs = require('fs')
+
+function setUser (cb) {
+ var defaultConf = Object.getPrototypeOf(this.root)
+
+ // 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 (this.get("global")) return cb()
+ if (process.env.SUDO_UID) {
+ defaultConf.user = +(process.env.SUDO_UID)
+ return cb()
+ }
+
+ var prefix = path.resolve(this.get("prefix"))
+ fs.stat(prefix, function (er, st) {
+ defaultConf.user = st && st.uid
+ return cb(er)
+ })
+}
diff --git a/node_modules/npmconf/npmconf.js b/node_modules/npmconf/npmconf.js
index 46ff2b813..aa2c7b2e6 100644
--- a/node_modules/npmconf/npmconf.js
+++ b/node_modules/npmconf/npmconf.js
@@ -10,6 +10,7 @@ var nopt = require('nopt')
var ini = require('ini')
var Octal = configDefs.Octal
var mkdirp = require('mkdirp')
+var path = require('path')
exports.load = load
exports.Conf = Conf
@@ -17,9 +18,11 @@ exports.loaded = false
exports.rootConf = null
exports.usingBuiltin = false
exports.defs = configDefs
+
Object.defineProperty(exports, 'defaults', { get: function () {
return configDefs.defaults
}, enumerable: true })
+
Object.defineProperty(exports, 'types', { get: function () {
return configDefs.types
}, enumerable: true })
@@ -67,6 +70,7 @@ function load (cli_, builtin_, cb_) {
loadCbs.push(cb)
if (loading)
return
+
loading = true
cb = once(function (er, conf) {
@@ -81,46 +85,68 @@ function load (cli_, builtin_, cb_) {
// check for a builtin if provided.
exports.usingBuiltin = !!builtin
var rc = exports.rootConf = new Conf()
- var defaults = configDefs.defaults
if (builtin)
rc.addFile(builtin, 'builtin')
else
rc.add({}, 'builtin')
rc.on('load', function () {
- var conf = new Conf(rc)
- conf.usingBuiltin = !!builtin
- conf.add(cli, 'cli')
- conf.addEnv()
+ load_(builtin, rc, cli, cb)
+ })
+}
+
+function load_(builtin, rc, cli, cb) {
+ var defaults = configDefs.defaults
+ var conf = new Conf(rc)
+
+ conf.usingBuiltin = !!builtin
+ conf.add(cli, 'cli')
+ conf.addEnv()
+
+ conf.loadExtras(function(er) {
+ if (er)
+ return cb(er)
+
+ if (!conf.get('global')) {
+ var projectConf = path.resolve(conf.localPrefix, '.npmrc')
+ conf.addFile(projectConf, 'project')
+ conf.once('load', afterPrefix)
+ }
+ else return afterPrefix()
+ })
+
+ function afterPrefix() {
conf.addFile(conf.get('userconfig'), 'user')
conf.once('error', cb)
+ conf.once('load', afterUser)
+ }
+
+ function afterUser () {
+ // globalconfig and globalignorefile defaults
+ // need to respond to the 'prefix' setting up to this point.
+ // Eg, `npm config get globalconfig --prefix ~/local` should
+ // return `~/local/etc/npmrc`
+ // annoying humans and their expectations!
+ if (conf.get('prefix')) {
+ var etc = path.resolve(conf.get('prefix'), 'etc')
+ defaults.globalconfig = path.resolve(etc, 'npmrc')
+ defaults.globalignorefile = path.resolve(etc, 'npmignore')
+ }
+
+ conf.addFile(conf.get('globalconfig'), 'global')
+
+ // move the builtin into the conf stack now.
+ conf.root = defaults
+ conf.add(rc.shift(), 'builtin')
conf.once('load', function () {
- // globalconfig and globalignorefile defaults
- // need to respond to the "prefix" setting up to this point.
- // Eg, `npm config get globalconfig --prefix ~/local` should
- // return `~/local/etc/npmrc`
- // annoying humans and their expectations!
- if (conf.get('prefix')) {
- var etc = path.resolve(conf.get("prefix"), "etc")
- defaults.globalconfig = path.resolve(etc, "npmrc")
- defaults.globalignorefile = path.resolve(etc, "npmignore")
- }
- conf.addFile(conf.get('globalconfig'), 'global')
-
- // move the builtin into the conf stack now.
- conf.root = defaults
- conf.add(rc.shift(), 'builtin')
- conf.once('load', function () {
- // warn about invalid bits.
- validate(conf)
- exports.loaded = conf
- cb(null, conf)
- })
+ // warn about invalid bits.
+ validate(conf)
+ exports.loaded = conf
+ cb(null, conf)
})
- })
+ }
}
-
// Basically the same as CC, but:
// 1. Always ini
// 2. Parses environment variable names in field values
@@ -142,6 +168,23 @@ function Conf (base) {
this.root = configDefs.defaults
}
+Conf.prototype.loadPrefix = require('./lib/load-prefix.js')
+Conf.prototype.loadUid = require('./lib/load-uid.js')
+Conf.prototype.setUser = require('./lib/set-user.js')
+Conf.prototype.findPrefix = require('./lib/find-prefix.js')
+
+Conf.prototype.loadExtras = function(cb) {
+ this.loadPrefix(function(er) {
+ if (er)
+ return cb(er)
+ this.setUser(function(er) {
+ if (er)
+ return cb(er)
+ this.loadUid(cb)
+ }.bind(this))
+ }.bind(this))
+}
+
Conf.prototype.save = function (where, cb) {
var target = this.sources[where]
if (!target || !(target.path || target.source) || !target.data) {
@@ -316,7 +359,7 @@ function parseField (f, k, emptyIsFalse) {
}
function envReplace (f) {
- if (typeof f !== "string" || !f) return f
+ if (typeof f !== 'string' || !f) return f
// replace any ${ENV} values with the appropriate environ.
var envExpr = /(\\*)\$\{([^}]+)\}/g
@@ -325,7 +368,7 @@ function envReplace (f) {
if (esc)
return orig
if (undefined === process.env[name])
- throw new Error("Failed to replace env in config: "+orig)
+ throw new Error('Failed to replace env in config: '+orig)
return process.env[name]
})
}
diff --git a/node_modules/npmconf/package.json b/node_modules/npmconf/package.json
index 0ac83acf3..4708b9bc5 100644
--- a/node_modules/npmconf/package.json
+++ b/node_modules/npmconf/package.json
@@ -1,6 +1,6 @@
{
"name": "npmconf",
- "version": "0.2.0",
+ "version": "1.0.0",
"description": "The config thing npm uses",
"main": "npmconf.js",
"directories": {
@@ -9,12 +9,13 @@
"dependencies": {
"config-chain": "~1.1.8",
"inherits": "~2.0.0",
- "once": "~1.3.0",
+ "ini": "~1.1.0",
"mkdirp": "~0.3.3",
- "osenv": "0.0.3",
"nopt": "2",
+ "once": "~1.3.0",
+ "osenv": "0.0.3",
"semver": "2",
- "ini": "~1.1.0"
+ "uid-number": "0.0.5"
},
"devDependencies": {
"tap": "~0.4.0"
@@ -45,7 +46,7 @@
"url": "https://github.com/isaacs/npmconf/issues"
},
"homepage": "https://github.com/isaacs/npmconf",
- "_id": "npmconf@0.2.0",
- "_shasum": "5c237d793aa50f8865cb8a289ae95ece009bde7c",
+ "_id": "npmconf@1.0.0",
+ "_shasum": "6015381e63743ecbbe1dcdda5eebafd6c49697c9",
"_from": "npmconf@latest"
}
diff --git a/node_modules/npmconf/test/basic.js b/node_modules/npmconf/test/basic.js
index 83832c2ef..f17f0fb8e 100644
--- a/node_modules/npmconf/test/basic.js
+++ b/node_modules/npmconf/test/basic.js
@@ -1,6 +1,9 @@
var test = require('tap').test
var npmconf = require('../npmconf.js')
var common = require('./00-setup.js')
+var path = require('path')
+
+var projectData = {}
var ucData =
{ globalconfig: common.globalconfig,
@@ -29,6 +32,7 @@ var ucData =
httponly: true } }
var envData = { userconfig: common.userconfig, 'other-env-thing': '1000' }
+var envDataFix = { userconfig: common.userconfig, 'other-env-thing': 1000 }
var gcData = { 'package-config:foo': 'boo' }
@@ -38,7 +42,8 @@ var cli = { foo: 'bar', umask: 022 }
var expectList =
[ cli,
- envData,
+ envDataFix,
+ projectData,
ucData,
gcData,
biData ]
@@ -46,9 +51,13 @@ var expectList =
var expectSources =
{ cli: { data: cli },
env:
- { data: envData,
+ { data: envDataFix,
source: envData,
prefix: '' },
+ project:
+ { path: path.resolve(__dirname, '..', '.npmrc'),
+ type: 'ini',
+ data: projectData },
user:
{ path: common.userconfig,
type: 'ini',
diff --git a/node_modules/npmconf/test/builtin.js b/node_modules/npmconf/test/builtin.js
index c5216ed90..0a305d2a6 100644
--- a/node_modules/npmconf/test/builtin.js
+++ b/node_modules/npmconf/test/builtin.js
@@ -1,6 +1,7 @@
var test = require('tap').test
var npmconf = require('../npmconf.js')
var common = require('./00-setup.js')
+var path = require('path')
var ucData =
{ globalconfig: common.globalconfig,
@@ -29,6 +30,7 @@ var ucData =
httponly: true } }
var envData = { userconfig: common.userconfig, 'other-env-thing': '1000' }
+var envDataFix = { userconfig: common.userconfig, 'other-env-thing': 1000 }
var gcData = { 'package-config:foo': 'boo' }
@@ -36,9 +38,12 @@ var biData = { 'builtin-config': true }
var cli = { foo: 'bar', heading: 'foo', 'git-tag-version': false }
+var projectData = {}
+
var expectList =
[ cli,
- envData,
+ envDataFix,
+ projectData,
ucData,
gcData,
biData ]
@@ -46,9 +51,13 @@ var expectList =
var expectSources =
{ cli: { data: cli },
env:
- { data: envData,
+ { data: envDataFix,
source: envData,
prefix: '' },
+ project:
+ { path: path.resolve(__dirname, '..', '.npmrc'),
+ type: 'ini',
+ data: projectData },
user:
{ path: common.userconfig,
type: 'ini',
diff --git a/node_modules/npmconf/test/fixtures/.npmrc b/node_modules/npmconf/test/fixtures/.npmrc
new file mode 100644
index 000000000..7d59bd8be
--- /dev/null
+++ b/node_modules/npmconf/test/fixtures/.npmrc
@@ -0,0 +1 @@
+just = testing
diff --git a/node_modules/npmconf/test/fixtures/package.json b/node_modules/npmconf/test/fixtures/package.json
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/node_modules/npmconf/test/fixtures/package.json
diff --git a/node_modules/npmconf/test/project.js b/node_modules/npmconf/test/project.js
new file mode 100644
index 000000000..04e063855
--- /dev/null
+++ b/node_modules/npmconf/test/project.js
@@ -0,0 +1,85 @@
+var test = require('tap').test
+var npmconf = require('../npmconf.js')
+var common = require('./00-setup.js')
+var path = require('path')
+var fix = path.resolve(__dirname, 'fixtures')
+var projectRc = path.resolve(fix, '.npmrc')
+
+var projectData = { just: 'testing' }
+
+var ucData =
+ { globalconfig: common.globalconfig,
+ email: 'i@izs.me',
+ 'env-thing': 'asdf',
+ 'init.author.name': 'Isaac Z. Schlueter',
+ 'init.author.email': 'i@izs.me',
+ 'init.author.url': 'http://blog.izs.me/',
+ 'proprietary-attribs': false,
+ 'npm:publishtest': true,
+ '_npmjs.org:couch': 'https://admin:password@localhost:5984/registry',
+ _auth: 'dXNlcm5hbWU6cGFzc3dvcmQ=',
+ 'npm-www:nocache': '1',
+ nodedir: '/Users/isaacs/dev/js/node-v0.8',
+ 'sign-git-tag': true,
+ message: 'v%s',
+ 'strict-ssl': false,
+ 'tmp': process.env.HOME + '/.tmp',
+ username : "username",
+ _password : "password",
+ _token:
+ { AuthSession: 'yabba-dabba-doodle',
+ version: '1',
+ expires: '1345001053415',
+ path: '/',
+ httponly: true } }
+
+var envData = { userconfig: common.userconfig, 'other-env-thing': '1000' }
+var envDataFix = { userconfig: common.userconfig, 'other-env-thing': 1000 }
+
+var gcData = { 'package-config:foo': 'boo' }
+
+var biData = {}
+
+var cli = { foo: 'bar', umask: 022, prefix: fix }
+
+var expectList =
+[ cli,
+ envDataFix,
+ projectData,
+ ucData,
+ gcData,
+ biData ]
+
+var expectSources =
+{ cli: { data: cli },
+ env:
+ { data: envDataFix,
+ source: envData,
+ prefix: '' },
+ project:
+ { path: projectRc,
+ type: 'ini',
+ data: projectData },
+ user:
+ { path: common.userconfig,
+ type: 'ini',
+ data: ucData },
+ global:
+ { path: common.globalconfig,
+ type: 'ini',
+ data: gcData },
+ builtin: { data: biData } }
+
+test('no builtin', function (t) {
+ npmconf.load(cli, function (er, conf) {
+ if (er) throw er
+ t.same(conf.list, expectList)
+ t.same(conf.sources, expectSources)
+ t.same(npmconf.rootConf.list, [])
+ t.equal(npmconf.rootConf.root, npmconf.defs.defaults)
+ t.equal(conf.root, npmconf.defs.defaults)
+ t.equal(conf.get('umask'), 022)
+ t.equal(conf.get('heading'), 'npm')
+ t.end()
+ })
+})
diff --git a/package.json b/package.json
index f30dbf7dd..d63f84147 100644
--- a/package.json
+++ b/package.json
@@ -65,7 +65,7 @@
"npm-install-checks": "~1.0.0",
"npm-registry-client": "~0.4.11",
"npm-user-validate": "~0.1.0",
- "npmconf": "~0.2.0",
+ "npmconf": "~1.0.0",
"npmlog": "0.0.6",
"once": "~1.3.0",
"opener": "~1.3.0",
@@ -83,7 +83,6 @@
"sorted-object": "~1.0.0",
"tar": "~0.1.19",
"text-table": "~0.2.0",
- "uid-number": "0.0.5",
"which": "1"
},
"bundleDependencies": [