From 0823f18435e43639f3b6b9f296b7385e99cffa3b Mon Sep 17 00:00:00 2001 From: Remy Sharp Date: Sat, 10 Jul 2021 16:02:51 +0100 Subject: [PATCH] fix(windows): properly handle quoted args in event Fixes: #1823 This mirrors the command parsing from run.js into the separate parser for launching event driven shells. --- lib/spawn.js | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/lib/spawn.js b/lib/spawn.js index d0adaeb1..9aa4f80e 100644 --- a/lib/spawn.js +++ b/lib/spawn.js @@ -1,3 +1,4 @@ +const path = require('path'); const utils = require('./utils'); const merge = utils.merge; const bus = utils.bus; @@ -10,26 +11,43 @@ module.exports = function spawnCommand(command, config, eventArgs) { stdio = ['pipe', process.stdout, process.stderr]; } + const env = merge(process.env, { FILENAME: eventArgs[0] }); + var sh = 'sh'; var shFlag = '-c'; + var spawnOptions = { + env: merge(config.options.execOptions.env, env), + stdio: stdio, + }; - if (utils.isWindows) { - sh = 'cmd'; - shFlag = '/c'; + if (!Array.isArray(command)) { + command = [command]; } + if (utils.isWindows) { + // if the exec includes a forward slash, reverse it for windows compat + // but *only* apply to the first command, and none of the arguments. + // ref #1251 and #1236 + command = command.map(executable => { + if (executable.indexOf('/') === -1) { + return executable; + } - if (!Array.isArray(command)) { - command = [command]; + return executable.split(' ').map((e, i) => { + if (i === 0) { + return path.normalize(e); + } + return e; + }).join(' '); + }); + // taken from npm's cli: https://git.io/vNFD4 + sh = process.env.comspec || 'cmd'; + shFlag = '/d /s /c'; + spawnOptions.windowsVerbatimArguments = true; } const args = command.join(' '); - - const env = merge(process.env, { FILENAME: eventArgs[0] }); - const child = spawn(sh, [shFlag, args], { - env: merge(config.options.execOptions.env, env), - stdio: stdio, - }); + const child = spawn(sh, [shFlag, args], spawnOptions); if (config.required) { var emit = {