| 'use strict' |
| |
| // This module should *only* be loaded as a main script |
| // by child processes wrapped by spawn-wrap. It sets up |
| // argv to include the injected argv (including the user's |
| // wrapper script) and any environment variables specified. |
| // |
| // If any argv were passed in (ie, if it's used to force |
| // a wrapper script, and not just ensure that an env is kept |
| // around through all the child procs), then we also set up |
| // a require('spawn-wrap').runMain() function that will strip |
| // off the injected arguments and run the main file. |
| |
| // wrap in iife for babylon to handle module-level return |
| ;(function () { |
| |
| if (module !== require.main) { |
| throw new Error('spawn-wrap: cli wrapper invoked as non-main script') |
| } |
| |
| var util |
| var doDebug = process.env.SPAWN_WRAP_DEBUG === '1' |
| var fs |
| function debug () { |
| if (!doDebug) |
| return |
| |
| if (!fs) { |
| fs = require('fs') |
| util = require('util') |
| } |
| |
| var message = util.format.apply(util, arguments).trim() |
| var pref = 'SW ' + process.pid + ': ' |
| message = pref + message.split('\n').join('\n' + pref) |
| fs.writeSync(2, message + '\n') |
| } |
| |
| debug('shim', [process.argv[0]].concat(process.execArgv, process.argv.slice(1))) |
| |
| var Module = require('module') |
| var assert = require('assert') |
| var path = require('path') |
| |
| var settings = require('./settings.json') |
| var foregroundChild = require(settings.deps.foregroundChild) |
| var argv = settings.argv |
| var nargs = argv.length |
| var env = settings.env |
| var key = settings.key |
| var node = process.env['SW_ORIG_' + key] || process.execPath |
| |
| for (var k in env) { |
| process.env[k] = env[k] |
| } |
| |
| var needExecArgv = settings.execArgv || [] |
| |
| // If the user added their OWN wrapper pre-load script, then |
| // this will pop that off of the argv, and load the "real" main |
| function runMain () { |
| debug('runMain pre', process.argv) |
| process.argv.splice(1, nargs) |
| process.argv[1] = path.resolve(process.argv[1]) |
| delete require.cache[process.argv[1]] |
| debug('runMain post', process.argv) |
| Module.runMain() |
| debug('runMain after') |
| } |
| |
| // Argv coming in looks like: |
| // bin shim execArgv main argv |
| // |
| // Turn it into: |
| // bin settings.execArgv execArgv settings.argv main argv |
| // |
| // If we don't have a main script, then just run with the necessary |
| // execArgv |
| var hasMain = false |
| for (var a = 2; !hasMain && a < process.argv.length; a++) { |
| switch (process.argv[a]) { |
| case '-i': |
| case '--interactive': |
| case '--eval': |
| case '-e': |
| case '-p': |
| case '-pe': |
| hasMain = false |
| a = process.argv.length |
| continue |
| |
| case '-r': |
| case '--require': |
| a += 1 |
| continue |
| |
| default: |
| if (process.argv[a].match(/^-/)) { |
| continue |
| } else { |
| hasMain = a |
| a = process.argv.length |
| break |
| } |
| } |
| } |
| debug('after argv parse hasMain=%j', hasMain) |
| |
| if (hasMain > 2) { |
| // if the main file is above #2, then it means that there |
| // was a --exec_arg *before* it. This means that we need |
| // to slice everything from 2 to hasMain, and pass that |
| // directly to node. This also splices out the user-supplied |
| // execArgv from the argv. |
| var addExecArgv = process.argv.splice(2, hasMain - 2) |
| needExecArgv.push.apply(needExecArgv, addExecArgv) |
| } |
| |
| if (!hasMain) { |
| // we got loaded by mistake for a `node -pe script` or something. |
| var args = process.execArgv.concat(needExecArgv, process.argv.slice(2)) |
| debug('no main file!', args) |
| foregroundChild(node, args) |
| return |
| } |
| |
| // If there are execArgv, and they're not the same as how this module |
| // was executed, then we need to inject those. This is for stuff like |
| // --harmony or --use_strict that needs to be *before* the main |
| // module. |
| if (needExecArgv.length) { |
| var pexec = process.execArgv |
| if (JSON.stringify(pexec) !== JSON.stringify(needExecArgv)) { |
| debug('need execArgv for this', pexec, '=>', needExecArgv) |
| var spawn = require('child_process').spawn |
| var sargs = pexec.concat(needExecArgv).concat(process.argv.slice(1)) |
| foregroundChild(node, sargs) |
| return |
| } |
| } |
| |
| // At this point, we've verified that we got the correct execArgv, |
| // and that we have a main file, and that the main file is sitting at |
| // argv[2]. Splice this shim off the list so it looks like the main. |
| var spliceArgs = [1, 1].concat(argv) |
| process.argv.splice.apply(process.argv, spliceArgs) |
| |
| // Unwrap the PATH environment var so that we're not mucking |
| // with the environment. It'll get re-added if they spawn anything |
| var isWindows = ( |
| process.platform === 'win32' || |
| process.env.OSTYPE === 'cygwin' || |
| process.env.OSTYPE === 'msys' |
| ) |
| |
| if (isWindows) { |
| for (var i in process.env) { |
| if (i.match(/^path$/i)) { |
| process.env[i] = process.env[i].replace(__dirname + ';', '') |
| } |
| } |
| } else { |
| process.env.PATH = process.env.PATH.replace(__dirname + ':', '') |
| } |
| |
| var spawnWrap = require(settings.module) |
| if (nargs) { |
| spawnWrap.runMain = function (original) { return function () { |
| spawnWrap.runMain = original |
| runMain() |
| }}(spawnWrap.runMain) |
| } |
| spawnWrap(argv, env, __dirname) |
| |
| debug('shim runMain', process.argv) |
| delete require.cache[process.argv[1]] |
| Module.runMain() |
| |
| // end iife wrapper for babylon |
| })() |