diff options
Diffstat (limited to 'node_modules/spawn-wrap/index.js')
-rw-r--r-- | node_modules/spawn-wrap/index.js | 447 |
1 files changed, 0 insertions, 447 deletions
diff --git a/node_modules/spawn-wrap/index.js b/node_modules/spawn-wrap/index.js deleted file mode 100644 index 30a2d32e7..000000000 --- a/node_modules/spawn-wrap/index.js +++ /dev/null @@ -1,447 +0,0 @@ -module.exports = wrap -wrap.runMain = runMain - -var Module = require('module') -var fs = require('fs') -var cp = require('child_process') -var ChildProcess = cp.ChildProcess -var assert = require('assert') -var crypto = require('crypto') -var mkdirp = require('mkdirp') -var rimraf = require('rimraf') -var path = require('path') -var signalExit = require('signal-exit') -var home = process.env.SPAWN_WRAP_SHIM_ROOT || require('os-homedir')() -var homedir = home + '/.node-spawn-wrap-' -var which = require('which') -var util = require('util') - -var doDebug = process.env.SPAWN_WRAP_DEBUG === '1' -var debug = doDebug ? function () { - var message = util.format.apply(util, arguments).trim() - var pref = 'SW ' + process.pid + ': ' - message = pref + message.split('\n').join('\n' + pref) - process.stderr.write(message + '\n') -} : function () {} - -var shebang = process.platform === 'os390' ? - '#!/bin/env ' : '#!' - -var shim = shebang + process.execPath + '\n' + - fs.readFileSync(__dirname + '/shim.js') - -var isWindows = require('./lib/is-windows')() - -var pathRe = /^PATH=/ -if (isWindows) pathRe = /^PATH=/i - -var colon = isWindows ? ';' : ':' - -function wrap (argv, env, workingDir) { - if (!ChildProcess) { - var child = cp.spawn(process.execPath, []) - ChildProcess = child.constructor - if (process.platform === 'os390') - child.kill('SIGABRT') - else - child.kill('SIGKILL') - } - - // spawn_sync available since Node v0.11 - var spawnSyncBinding, spawnSync - try { - spawnSyncBinding = process.binding('spawn_sync') - } catch (e) {} - - // if we're passed in the working dir, then it means that setup - // was already done, so no need. - var doSetup = !workingDir - if (doSetup) { - workingDir = setup(argv, env) - } - var spawn = ChildProcess.prototype.spawn - if (spawnSyncBinding) { - spawnSync = spawnSyncBinding.spawn - } - - function unwrap () { - if (doSetup && !doDebug) { - rimraf.sync(workingDir) - } - ChildProcess.prototype.spawn = spawn - if (spawnSyncBinding) { - spawnSyncBinding.spawn = spawnSync - } - } - - if (spawnSyncBinding) { - spawnSyncBinding.spawn = wrappedSpawnFunction(spawnSync, workingDir) - } - ChildProcess.prototype.spawn = wrappedSpawnFunction(spawn, workingDir) - - return unwrap -} - -function wrappedSpawnFunction (fn, workingDir) { - return wrappedSpawn - - function wrappedSpawn (options) { - munge(workingDir, options) - debug('WRAPPED', options) - return fn.call(this, options) - } -} - -function isSh (file) { - return file === 'dash' || - file === 'sh' || - file === 'bash' || - file === 'zsh' -} - -function mungeSh (workingDir, options) { - var cmdi = options.args.indexOf('-c') - if (cmdi === -1) - return // no -c argument - - var c = options.args[cmdi + 1] - var re = /^\s*((?:[^\= ]*\=[^\=\s]*)*[\s]*)([^\s]+|"[^"]+"|'[^']+')( .*)?$/ - var match = c.match(re) - if (!match) - return // not a command invocation. weird but possible - - var command = match[2] - // strip quotes off the command - var quote = command.charAt(0) - if ((quote === '"' || quote === '\'') && quote === command.slice(-1)) { - command = command.slice(1, -1) - } - var exe = path.basename(command) - - if (isNode(exe)) { - options.originalNode = command - c = match[1] + match[2] + ' "' + workingDir + '/node" ' + match[3] - options.args[cmdi + 1] = c - } else if (exe === 'npm' && !isWindows) { - // XXX this will exhibit weird behavior when using /path/to/npm, - // if some other npm is first in the path. - var npmPath = whichOrUndefined('npm') - - if (npmPath) { - c = c.replace(re, '$1 "' + workingDir + '/node" "' + npmPath + '" $3') - options.args[cmdi + 1] = c - debug('npm munge!', c) - } - } -} - -function isCmd (file) { - var comspec = path.basename(process.env.comspec || '').replace(/\.exe$/i, '') - return isWindows && (file === comspec || /^cmd(\.exe|\.EXE)?$/.test(file)) -} - -function mungeCmd (workingDir, options) { - var cmdi = options.args.indexOf('/c') - if (cmdi === -1) - return - - var re = /^\s*("*)([^"]*?\b(?:node|iojs)(?:\.exe|\.EXE)?)("*)( .*)?$/ - var npmre = /^\s*("*)([^"]*?\b(?:npm))("*)( |$)/ - var path_ = require('path') - if (path_.win32) - path_ = path_.win32 - - var command = options.args[cmdi + 1] - if (!command) - return - - var m = command.match(re) - var replace - if (m) { - options.originalNode = m[2] - replace = m[1] + workingDir + '/node.cmd' + m[3] + m[4] - options.args[cmdi + 1] = m[1] + m[2] + m[3] + - ' "' + workingDir + '\\node"' + m[4] - } else { - // XXX probably not a good idea to rewrite to the first npm in the - // path if it's a full path to npm. And if it's not a full path to - // npm, then the dirname will not work properly! - m = command.match(npmre) - if (!m) - return - - var npmPath = whichOrUndefined('npm') || 'npm' - npmPath = path_.dirname(npmPath) + '\\node_modules\\npm\\bin\\npm-cli.js' - replace = m[1] + workingDir + '/node.cmd' + - ' "' + npmPath + '"' + - m[3] + m[4] - options.args[cmdi + 1] = command.replace(npmre, replace) - } -} - -function isNode (file) { - var cmdname = path.basename(process.execPath).replace(/\.exe$/i, '') - return file === 'node' || file === 'iojs' || cmdname === file -} - -function mungeNode (workingDir, options) { - options.originalNode = options.file - var command = path.basename(options.file).replace(/\.exe$/i, '') - // make sure it has a main script. - // otherwise, just let it through. - var a = 0 - var hasMain = false - var mainIndex = 1 - for (var a = 1; !hasMain && a < options.args.length; a++) { - switch (options.args[a]) { - case '-p': - case '-i': - case '--interactive': - case '--eval': - case '-e': - case '-pe': - hasMain = false - a = options.args.length - continue - - case '-r': - case '--require': - a += 1 - continue - - default: - if (options.args[a].match(/^-/)) { - continue - } else { - hasMain = true - mainIndex = a - a = options.args.length - break - } - } - } - - if (hasMain) { - var replace = workingDir + '/' + command - options.args.splice(mainIndex, 0, replace) - } - - // If the file is just something like 'node' then that'll - // resolve to our shim, and so to prevent double-shimming, we need - // to resolve that here first. - // This also handles the case where there's not a main file, like - // `node -e 'program'`, where we want to avoid the shim entirely. - if (options.file === options.basename) { - var realNode = whichOrUndefined(options.file) || process.execPath - options.file = options.args[0] = realNode - } - - debug('mungeNode after', options.file, options.args) -} - -function mungeShebang (workingDir, options) { - try { - var resolved = which.sync(options.file) - } catch (er) { - // nothing to do if we can't resolve - // Most likely: file doesn't exist or is not executable. - // Let exec pass through, probably will fail, oh well. - return - } - - var shebang = fs.readFileSync(resolved, 'utf8') - var match = shebang.match(/^#!([^\r\n]+)/) - if (!match) - return // not a shebang script, probably a binary - - var shebangbin = match[1].split(' ')[0] - var maybeNode = path.basename(shebangbin) - if (!isNode(maybeNode)) - return // not a node shebang, leave untouched - - options.originalNode = shebangbin - options.basename = maybeNode - options.file = shebangbin - options.args = [shebangbin, workingDir + '/' + maybeNode] - .concat(resolved) - .concat(match[1].split(' ').slice(1)) - .concat(options.args.slice(1)) -} - -function mungeEnv (workingDir, options) { - var pathEnv - for (var i = 0; i < options.envPairs.length; i++) { - var ep = options.envPairs[i] - if (ep.match(pathRe)) { - pathEnv = ep.substr(5) - var k = ep.substr(0, 5) - options.envPairs[i] = k + workingDir + colon + pathEnv - } - } - if (!pathEnv) { - options.envPairs.push((isWindows ? 'Path=' : 'PATH=') + workingDir) - } - if (options.originalNode) { - var key = path.basename(workingDir).substr('.node-spawn-wrap-'.length) - options.envPairs.push('SW_ORIG_' + key + '=' + options.originalNode) - } - - options.envPairs.push('SPAWN_WRAP_SHIM_ROOT=' + homedir) - - if (process.env.SPAWN_WRAP_DEBUG === '1') - options.envPairs.push('SPAWN_WRAP_DEBUG=1') -} - -function isnpm (file) { - // XXX is this even possible/necessary? - // wouldn't npm just be detected as a node shebang? - return file === 'npm' && !isWindows -} - -function mungenpm (workingDir, options) { - debug('munge npm') - // XXX weird effects of replacing a specific npm with a global one - var npmPath = whichOrUndefined('npm') - - if (npmPath) { - options.args[0] = npmPath - - options.file = workingDir + '/node' - options.args.unshift(workingDir + '/node') - } -} - -function munge (workingDir, options) { - options.basename = path.basename(options.file).replace(/\.exe$/i, '') - - // XXX: dry this - if (isSh(options.basename)) { - mungeSh(workingDir, options) - } else if (isCmd(options.basename)) { - mungeCmd(workingDir, options) - } else if (isNode(options.basename)) { - mungeNode(workingDir, options) - } else if (isnpm(options.basename)) { - // XXX unnecessary? on non-windows, npm is just another shebang - mungenpm(workingDir, options) - } else { - mungeShebang(workingDir, options) - } - - // now the options are munged into shape. - // whether we changed something or not, we still update the PATH - // so that if a script somewhere calls `node foo`, it gets our - // wrapper instead. - - mungeEnv(workingDir, options) -} - -function whichOrUndefined (executable) { - var path - try { - path = which.sync(executable) - } catch (er) {} - return path -} - -function setup (argv, env) { - if (argv && typeof argv === 'object' && !env && !Array.isArray(argv)) { - env = argv - argv = [] - } - - if (!argv && !env) { - throw new Error('at least one of "argv" and "env" required') - } - - if (argv) { - assert(Array.isArray(argv), 'argv must be array') - } else { - argv = [] - } - - if (env) { - assert(typeof env === 'object', 'env must be an object') - } else { - env = {} - } - - debug('setup argv=%j env=%j', argv, env) - - // For stuff like --use_strict or --harmony, we need to inject - // the argument *before* the wrap-main. - var execArgv = [] - for (var i = 0; i < argv.length; i++) { - if (argv[i].match(/^-/)) { - execArgv.push(argv[i]) - if (argv[i] === '-r' || argv[i] === '--require') { - execArgv.push(argv[++i]) - } - } else { - break - } - } - if (execArgv.length) { - if (execArgv.length === argv.length) { - argv.length = 0 - } else { - argv = argv.slice(execArgv.length) - } - } - - var key = process.pid + '-' + crypto.randomBytes(6).toString('hex') - var workingDir = homedir + key - - var settings = JSON.stringify({ - module: __filename, - deps: { - foregroundChild: require.resolve('foreground-child'), - signalExit: require.resolve('signal-exit'), - }, - key: key, - workingDir: workingDir, - argv: argv, - execArgv: execArgv, - env: env, - root: process.pid - }, null, 2) + '\n' - - signalExit(function () { - if (!doDebug) - rimraf.sync(workingDir) - }) - - mkdirp.sync(workingDir) - workingDir = fs.realpathSync(workingDir) - if (isWindows) { - var cmdShim = - '@echo off\r\n' + - 'SETLOCAL\r\n' + - 'SET PATHEXT=%PATHEXT:;.JS;=;%\r\n' + - '"' + process.execPath + '"' + ' "%~dp0\\.\\node" %*\r\n' - - fs.writeFileSync(workingDir + '/node.cmd', cmdShim) - fs.chmodSync(workingDir + '/node.cmd', '0755') - fs.writeFileSync(workingDir + '/iojs.cmd', cmdShim) - fs.chmodSync(workingDir + '/iojs.cmd', '0755') - } - fs.writeFileSync(workingDir + '/node', shim) - fs.chmodSync(workingDir + '/node', '0755') - fs.writeFileSync(workingDir + '/iojs', shim) - fs.chmodSync(workingDir + '/iojs', '0755') - var cmdname = path.basename(process.execPath).replace(/\.exe$/i, '') - if (cmdname !== 'iojs' && cmdname !== 'node') { - fs.writeFileSync(workingDir + '/' + cmdname, shim) - fs.chmodSync(workingDir + '/' + cmdname, '0755') - } - fs.writeFileSync(workingDir + '/settings.json', settings) - - return workingDir -} - -function runMain () { - process.argv.splice(1, 1) - process.argv[1] = path.resolve(process.argv[1]) - delete require.cache[process.argv[1]] - Module.runMain() -} |