| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495 | const {spawn} = require('cross-spawn')const commandConvert = require('./command')const varValueConvert = require('./variable')module.exports = crossEnvconst envSetterRegex = /(\w+)=('(.*)'|"(.*)"|(.*))/function crossEnv(args, options = {}) {  const [envSetters, command, commandArgs] = parseCommand(args)  const env = getEnvVars(envSetters)  if (command) {    const proc = spawn(      // run `path.normalize` for command(on windows)      commandConvert(command, env, true),      // by default normalize is `false`, so not run for cmd args      commandArgs.map(arg => commandConvert(arg, env)),      {        stdio: 'inherit',        shell: options.shell,        env,      },    )    process.on('SIGTERM', () => proc.kill('SIGTERM'))    process.on('SIGINT', () => proc.kill('SIGINT'))    process.on('SIGBREAK', () => proc.kill('SIGBREAK'))    process.on('SIGHUP', () => proc.kill('SIGHUP'))    proc.on('exit', (code, signal) => {      let crossEnvExitCode = code      // exit code could be null when OS kills the process(out of memory, etc) or due to node handling it      // but if the signal is SIGINT the user exited the process so we want exit code 0      if (crossEnvExitCode === null) {        crossEnvExitCode = signal === 'SIGINT' ? 0 : 1      }      process.exit(crossEnvExitCode) //eslint-disable-line no-process-exit    })    return proc  }  return null}function parseCommand(args) {  const envSetters = {}  let command = null  let commandArgs = []  for (let i = 0; i < args.length; i++) {    const match = envSetterRegex.exec(args[i])    if (match) {      let value      if (typeof match[3] !== 'undefined') {        value = match[3]      } else if (typeof match[4] === 'undefined') {        value = match[5]      } else {        value = match[4]      }      envSetters[match[1]] = value    } else {      // No more env setters, the rest of the line must be the command and args      let cStart = []      cStart = args        .slice(i)        // Regex:        // match "\'" or "'"        // or match "\" if followed by [$"\] (lookahead)        .map(a => {          const re = /\\\\|(\\)?'|([\\])(?=[$"\\])/g          // Eliminate all matches except for "\'" => "'"          return a.replace(re, m => {            if (m === '\\\\') return '\\'            if (m === "\\'") return "'"            return ''          })        })      command = cStart[0]      commandArgs = cStart.slice(1)      break    }  }  return [envSetters, command, commandArgs]}function getEnvVars(envSetters) {  const envVars = {...process.env}  if (process.env.APPDATA) {    envVars.APPDATA = process.env.APPDATA  }  Object.keys(envSetters).forEach(varName => {    envVars[varName] = varValueConvert(envSetters[varName], varName)  })  return envVars}
 |