Skip to content

Commit

Permalink
fix: correctly translate paths when using bash in windows (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
nlf committed Jul 12, 2022
1 parent 832a0b1 commit 756ff56
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 48 deletions.
21 changes: 10 additions & 11 deletions lib/make-spawn-args.js
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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,
Expand Down
46 changes: 9 additions & 37 deletions test/make-spawn-args.js
Original file line number Diff line number Diff line change
Expand Up @@ -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$/,
Expand All @@ -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')
Expand Down Expand Up @@ -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$/,
Expand All @@ -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')
Expand All @@ -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$/,
Expand All @@ -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')
Expand Down

0 comments on commit 756ff56

Please sign in to comment.