Skip to content

Commit

Permalink
fix(core): Read PATH & PATHEXT /w case insensitivity, normalize on write
Browse files Browse the repository at this point in the history
  • Loading branch information
zenflow committed Sep 21, 2020
1 parent 9982ae9 commit c3f8612
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 14 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
"http-proxy-middleware": "^1.0.5",
"merge-stream": "^2.0.0",
"npm-run-path": "^4.0.1",
"path-key": "^3.1.1",
"serialize-javascript": "^5.0.1",
"split": "^1.0.1",
"ts-interface-checker": "^0.1.13",
Expand Down
46 changes: 34 additions & 12 deletions src/core/spawnProcess.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { spawn } from 'child_process'
import { resolve, normalize } from 'path'
import npmRunPath from 'npm-run-path'
import getPathKey from 'path-key'
import which from 'which'
import { NormalizedServiceConfig } from './validateAndNormalizeConfig'

// Match the isWindows definition from `node-which`
// https://github.com/npm/node-which/blob/6a822d836de79f92fb3170f685a6e283fbfeff87/which.js#L1-L3
const isWindows =
process.platform === 'win32' ||
Expand All @@ -16,18 +16,15 @@ export function spawnProcess(config: NormalizedServiceConfig) {
let [binary, ...args] = config.command
let env = { ...config.env }

// Use uppercase PATH key regardless of OS or original key
env.PATH = filterBlankParts(
npmRunPath({
cwd,
path: config.env[getPathKey({ env: config.env })] || '',
}),
)
let path = readEnvCaseInsensitive(env, 'PATH') || ''
path = filterBlankParts(npmRunPath({ cwd, path }))
env = writeEnvCaseNormalized(env, 'PATH', path)

if (isWindows) {
env.PATHEXT =
config.env.PATHEXT || '.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH'

const pathExt =
readEnvCaseInsensitive(env, 'PATHEXT') ||
'.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH'
env = writeEnvCaseNormalized(env, 'PATHEXT', pathExt)
/*
Work around issue (same issue):
- https://github.com/nodejs/node-v0.x-archive/issues/2318
Expand All @@ -39,12 +36,37 @@ export function spawnProcess(config: NormalizedServiceConfig) {
Instead just replace `binary` with a fully-qualified version.
*/
binary = normalize(myWhich(cwd, binary, env.PATH, env.PATHEXT) || binary)
binary = normalize(myWhich(cwd, binary, path, pathExt) || binary)
}

return spawn(binary, args, { cwd, env })
}

function readEnvCaseInsensitive(
env: { [key: string]: string },
key: string,
): string | undefined {
const upperCaseKey = key.toUpperCase()
const caseInsensitiveKey = Object.keys(env)
.reverse()
.find(key => key.toUpperCase() === upperCaseKey)
return caseInsensitiveKey === undefined ? undefined : env[caseInsensitiveKey]
}

function writeEnvCaseNormalized(
env: { [key: string]: string },
key: string,
value: string,
): { [key: string]: string } {
const upperCaseKey = key.toUpperCase()
return {
...Object.fromEntries(
Object.entries(env).filter(([key]) => key.toUpperCase() !== upperCaseKey),
),
[upperCaseKey]: value,
}
}

function filterBlankParts(string: string) {
const colon = isWindows ? ';' : ':'
return string
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7312,7 +7312,7 @@ path-key@^2.0.0, path-key@^2.0.1:
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=

path-key@^3.0.0, path-key@^3.1.0, path-key@^3.1.1:
path-key@^3.0.0, path-key@^3.1.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
Expand Down

0 comments on commit c3f8612

Please sign in to comment.