This repository has been archived by the owner on Jan 6, 2021. It is now read-only.
/
index.js
85 lines (77 loc) 路 2.3 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
import {spawn} from 'cross-spawn'
import commandConvert from './command'
import varValueConvert from './variable'
module.exports = crossEnv
const 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', 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 = new RegExp(/(\\)?'|([\\])(?=[$"\\])/, 'g')
// Eliminate all matches except for "\'" => "'"
return a.replace(re, (m) => {
if(m === "\\'") return "'"
return ""
})
})
command = cStart[0]
commandArgs = cStart.slice(1)
break
}
}
return [envSetters, command, commandArgs]
}
function getEnvVars(envSetters) {
const envVars = Object.assign({}, process.env)
if (process.env.APPDATA) {
envVars.APPDATA = process.env.APPDATA
}
Object.keys(envSetters).forEach(varName => {
envVars[varName] = varValueConvert(envSetters[varName], varName)
})
return envVars
}