summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/npm-lifecycle/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/npm-lifecycle/index.js')
-rw-r--r--deps/npm/node_modules/npm-lifecycle/index.js90
1 files changed, 58 insertions, 32 deletions
diff --git a/deps/npm/node_modules/npm-lifecycle/index.js b/deps/npm/node_modules/npm-lifecycle/index.js
index 4eb83255a9..0972870b18 100644
--- a/deps/npm/node_modules/npm-lifecycle/index.js
+++ b/deps/npm/node_modules/npm-lifecycle/index.js
@@ -4,6 +4,9 @@ exports = module.exports = lifecycle
exports.makeEnv = makeEnv
exports._incorrectWorkingDirectory = _incorrectWorkingDirectory
+// for testing
+const platform = process.env.__TESTING_FAKE_PLATFORM__ || process.platform
+const isWindows = platform === 'win32'
const spawn = require('./lib/spawn')
const path = require('path')
const Stream = require('stream').Stream
@@ -18,17 +21,28 @@ const resolveFrom = require('resolve-from')
const DEFAULT_NODE_GYP_PATH = resolveFrom(__dirname, 'node-gyp/bin/node-gyp')
const hookStatCache = new Map()
-let PATH = 'PATH'
-
-// windows calls it's path 'Path' usually, but this is not guaranteed.
-if (process.platform === 'win32') {
- PATH = 'Path'
- Object.keys(process.env).forEach(function (e) {
- if (e.match(/^PATH$/i)) {
- PATH = e
- }
- })
+let PATH = isWindows ? 'Path' : 'PATH'
+exports._pathEnvName = PATH
+const delimiter = path.delimiter
+
+// windows calls its path 'Path' usually, but this is not guaranteed.
+// merge them all together in the order they appear in the object.
+const mergePath = env =>
+ Object.keys(env).filter(p => /^path$/i.test(p) && env[p])
+ .map(p => env[p].split(delimiter))
+ .reduce((set, p) => set.concat(p.filter(p => !set.includes(p))), [])
+ .join(delimiter)
+exports._mergePath = mergePath
+
+const setPathEnv = (env, path) => {
+ // first ensure that the canonical value is set.
+ env[PATH] = path
+ // also set any other case values, because windows.
+ Object.keys(env)
+ .filter(p => p !== PATH && /^path$/i.test(p))
+ .forEach(p => { env[p] = path })
}
+exports._setPathEnv = setPathEnv
function logid (pkg, stage) {
return pkg._id + '~' + stage + ':'
@@ -120,8 +134,10 @@ function lifecycle_ (pkg, stage, wd, opts, env, cb) {
pathArr.push(path.dirname(process.execPath))
}
- if (env[PATH]) pathArr.push(env[PATH])
- env[PATH] = pathArr.join(process.platform === 'win32' ? ';' : ':')
+ const existingPath = mergePath(env)
+ if (existingPath) pathArr.push(existingPath)
+ const envPath = pathArr.join(isWindows ? ';' : ':')
+ setPathEnv(env, envPath)
var packageLifecycle = pkg.scripts && pkg.scripts.hasOwnProperty(stage)
@@ -164,10 +180,9 @@ function shouldPrependCurrentNodeDirToPATH (opts) {
var isDifferentNodeInPath
- var isWindows = process.platform === 'win32'
var foundExecPath
try {
- foundExecPath = which.sync(path.basename(process.execPath), {pathExt: isWindows ? ';' : ':'})
+ foundExecPath = which.sync(path.basename(process.execPath), { pathExt: isWindows ? ';' : ':' })
// Apply `fs.realpath()` here to avoid false positives when `node` is a symlinked executable.
isDifferentNodeInPath = fs.realpathSync(process.execPath).toUpperCase() !==
fs.realpathSync(foundExecPath).toUpperCase()
@@ -242,7 +257,7 @@ function runCmd (note, cmd, pkg, env, stage, wd, opts, cb) {
}
opts.log.verbose('lifecycle', logid(pkg, stage), 'unsafe-perm in lifecycle', unsafe)
- if (process.platform === 'win32') {
+ if (isWindows) {
unsafe = true
}
@@ -255,14 +270,8 @@ function runCmd (note, cmd, pkg, env, stage, wd, opts, cb) {
}
}
-function runCmd_ (cmd, pkg, env, wd, opts, stage, unsafe, uid, gid, cb_) {
- function cb (er) {
- cb_.apply(null, arguments)
- opts.log.resume()
- process.nextTick(dequeue)
- }
-
- var conf = {
+const getSpawnArgs = ({ cmd, wd, opts, uid, gid, unsafe, env }) => {
+ const conf = {
cwd: wd,
env: env,
stdio: opts.stdio || [ 0, 1, 2 ]
@@ -273,24 +282,40 @@ function runCmd_ (cmd, pkg, env, wd, opts, stage, unsafe, uid, gid, cb_) {
conf.gid = gid ^ 0
}
- var sh = 'sh'
- var shFlag = '-c'
-
- var customShell = opts.scriptShell
+ const customShell = opts.scriptShell
+ let sh = 'sh'
+ let shFlag = '-c'
if (customShell) {
sh = customShell
- } else if (process.platform === 'win32') {
+ } else if (isWindows || opts._TESTING_FAKE_WINDOWS_) {
sh = process.env.comspec || 'cmd'
- shFlag = '/d /s /c'
- conf.windowsVerbatimArguments = true
+ // '/d /s /c' is used only for cmd.exe.
+ if (/^(?:.*\\)?cmd(?:\.exe)?$/i.test(sh)) {
+ shFlag = '/d /s /c'
+ conf.windowsVerbatimArguments = true
+ }
}
+ return [sh, [shFlag, cmd], conf]
+}
+
+exports._getSpawnArgs = getSpawnArgs
+
+function runCmd_ (cmd, pkg, env, wd, opts, stage, unsafe, uid, gid, cb_) {
+ function cb (er) {
+ cb_.apply(null, arguments)
+ opts.log.resume()
+ process.nextTick(dequeue)
+ }
+
+ const [sh, args, conf] = getSpawnArgs({ cmd, wd, opts, uid, gid, unsafe, env })
+
opts.log.verbose('lifecycle', logid(pkg, stage), 'PATH:', env[PATH])
opts.log.verbose('lifecycle', logid(pkg, stage), 'CWD:', wd)
- opts.log.silly('lifecycle', logid(pkg, stage), 'Args:', [shFlag, cmd])
+ opts.log.silly('lifecycle', logid(pkg, stage), 'Args:', args)
- var proc = spawn(sh, [shFlag, cmd], conf, opts.log)
+ var proc = spawn(sh, args, conf, opts.log)
proc.on('error', procError)
proc.on('close', function (code, signal) {
@@ -333,6 +358,7 @@ function runCmd_ (cmd, pkg, env, wd, opts, stage, unsafe, uid, gid, cb_) {
process.removeListener('SIGTERM', procKill)
process.removeListener('SIGTERM', procInterupt)
process.removeListener('SIGINT', procKill)
+ process.removeListener('SIGINT', procInterupt)
return cb(er)
}
function procKill () {