diff --git a/lib/make-spawn-args.js b/lib/make-spawn-args.js index 54cd57a..f2253d7 100644 --- a/lib/make-spawn-args.js +++ b/lib/make-spawn-args.js @@ -1,14 +1,20 @@ /* eslint camelcase: "off" */ const isWindows = require('./is-windows.js') const setPATH = require('./set-path.js') -const { chmodSync: chmod, unlinkSync: unlink, writeFileSync: writeFile } = require('fs') +const { unlinkSync: unlink, writeFileSync: writeFile } = require('fs') const { tmpdir } = require('os') -const { isAbsolute, resolve } = require('path') +const { resolve } = require('path') const which = require('which') const npm_config_node_gyp = require.resolve('node-gyp/bin/node-gyp.js') const escape = require('./escape.js') const { randomBytes } = require('crypto') +const translateWinPathToPosix = (path) => { + return path + .replace(/^([A-z]):/, '/$1') + .replace(/\\/g, '/') +} + const makeSpawnArgs = options => { const { event, @@ -70,24 +76,17 @@ const makeSpawnArgs = options => { script += ` ${args.map((arg) => escape.cmd(arg, doubleEscape)).join(' ')}` } } else { - const shebang = isAbsolute(scriptShell) - ? `#!${scriptShell}` - : `#!/usr/bin/env ${scriptShell}` scriptFile = resolve(tmpdir(), `${fileName}.sh`) - script += `${shebang}\n` - script += cmd + script = cmd if (args.length) { script += ` ${args.map((arg) => escape.sh(arg)).join(' ')}` } } writeFile(scriptFile, script) - if (!isCmd) { - chmod(scriptFile, '0775') - } const spawnArgs = isCmd ? ['/d', '/s', '/c', escape.cmd(scriptFile)] - : ['-c', escape.sh(scriptFile)] + : [isWindows ? translateWinPathToPosix(scriptFile) : scriptFile] const spawnOpts = { env: spawnEnv, diff --git a/test/make-spawn-args.js b/test/make-spawn-args.js index dd441f5..66573bb 100644 --- a/test/make-spawn-args.js +++ b/test/make-spawn-args.js @@ -148,7 +148,7 @@ if (isWindows) { cmd: 'script "quoted parameter"; second command', }) t.equal(shell, 'blrorp', 'used ComSpec as default shell') - t.match(args, ['-c', /\.sh'$/], 'got expected args') + t.match(args, [/\.sh$/], 'got expected args') t.match(opts, { env: { npm_package_json: /package\.json$/, @@ -160,7 +160,10 @@ if (isWindows) { windowsVerbatimArguments: undefined, }, 'got expected options') - const filename = unescapeSh(args[args.length - 1]) + let filename = unescapeSh(args[args.length - 1]) + if (process.platform === 'win32') { + filename = filename.replace(/^\/([A-z])/, '$1:') + } t.ok(fs.existsSync(filename), 'script file was written') cleanup() t.not(fs.existsSync(filename), 'cleanup removes script file') @@ -325,7 +328,7 @@ if (isWindows) { args: ['"quoted parameter";', 'second command'], }) t.equal(shell, 'sh', 'defaults to sh') - t.match(args, ['-c', /\.sh'$/], 'got expected args') + t.match(args, [/\.sh$/], 'got expected args') t.match(opts, { env: { npm_package_json: /package\.json$/, @@ -339,7 +342,7 @@ if (isWindows) { const filename = unescapeSh(args[args.length - 1]) const contents = fs.readFileSync(filename, { encoding: 'utf8' }) - t.equal(contents, `#!/usr/bin/env sh\nscript '"quoted parameter";' 'second command'`) + t.equal(contents, `script '"quoted parameter";' 'second command'`) t.ok(fs.existsSync(filename), 'script file was written') cleanup() t.not(fs.existsSync(filename), 'cleanup removes script file') @@ -357,38 +360,7 @@ if (isWindows) { t.equal(shell, 'sh', 'defaults to sh') // no-control-regex disabled because we're specifically testing control chars // eslint-disable-next-line no-control-regex - t.match(args, ['-c', /(?:\\|\/)[^<:>/\x04]+\.sh'$/], 'got expected args') - t.match(opts, { - env: { - npm_package_json: /package\.json$/, - npm_lifecycle_event: 'event', - npm_lifecycle_script: 'script', - }, - stdio: undefined, - cwd: 'path', - windowsVerbatimArguments: undefined, - }, 'got expected options') - - const filename = unescapeSh(args[args.length - 1]) - const contents = fs.readFileSync(filename, { encoding: 'utf8' }) - t.equal(contents, `#!/usr/bin/env sh\nscript '"quoted parameter";' 'second command'`) - t.ok(fs.existsSync(filename), 'script file was written') - cleanup() - t.not(fs.existsSync(filename), 'cleanup removes script file') - - t.end() - }) - - t.test('skips /usr/bin/env if scriptShell is absolute', (t) => { - const [shell, args, opts, cleanup] = makeSpawnArgs({ - event: 'event', - path: 'path', - cmd: 'script', - args: ['"quoted parameter";', 'second command'], - scriptShell: '/bin/sh', - }) - t.equal(shell, '/bin/sh', 'kept provided setting') - t.match(args, ['-c', /\.sh'$/], 'got expected args') + t.match(args, [/(?:\\|\/)[^<:>/\x04]+\.sh$/], 'got expected args') t.match(opts, { env: { npm_package_json: /package\.json$/, @@ -402,7 +374,7 @@ if (isWindows) { const filename = unescapeSh(args[args.length - 1]) const contents = fs.readFileSync(filename, { encoding: 'utf8' }) - t.equal(contents, `#!/bin/sh\nscript '"quoted parameter";' 'second command'`) + t.equal(contents, `script '"quoted parameter";' 'second command'`) t.ok(fs.existsSync(filename), 'script file was written') cleanup() t.not(fs.existsSync(filename), 'cleanup removes script file')