Skip to content

Commit 756ff56

Browse files
authored
fix: correctly translate paths when using bash in windows (#96)
1 parent 832a0b1 commit 756ff56

File tree

2 files changed

+19
-48
lines changed

2 files changed

+19
-48
lines changed

Diff for: lib/make-spawn-args.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,20 @@
11
/* eslint camelcase: "off" */
22
const isWindows = require('./is-windows.js')
33
const setPATH = require('./set-path.js')
4-
const { chmodSync: chmod, unlinkSync: unlink, writeFileSync: writeFile } = require('fs')
4+
const { unlinkSync: unlink, writeFileSync: writeFile } = require('fs')
55
const { tmpdir } = require('os')
6-
const { isAbsolute, resolve } = require('path')
6+
const { resolve } = require('path')
77
const which = require('which')
88
const npm_config_node_gyp = require.resolve('node-gyp/bin/node-gyp.js')
99
const escape = require('./escape.js')
1010
const { randomBytes } = require('crypto')
1111

12+
const translateWinPathToPosix = (path) => {
13+
return path
14+
.replace(/^([A-z]):/, '/$1')
15+
.replace(/\\/g, '/')
16+
}
17+
1218
const makeSpawnArgs = options => {
1319
const {
1420
event,
@@ -70,24 +76,17 @@ const makeSpawnArgs = options => {
7076
script += ` ${args.map((arg) => escape.cmd(arg, doubleEscape)).join(' ')}`
7177
}
7278
} else {
73-
const shebang = isAbsolute(scriptShell)
74-
? `#!${scriptShell}`
75-
: `#!/usr/bin/env ${scriptShell}`
7679
scriptFile = resolve(tmpdir(), `${fileName}.sh`)
77-
script += `${shebang}\n`
78-
script += cmd
80+
script = cmd
7981
if (args.length) {
8082
script += ` ${args.map((arg) => escape.sh(arg)).join(' ')}`
8183
}
8284
}
8385

8486
writeFile(scriptFile, script)
85-
if (!isCmd) {
86-
chmod(scriptFile, '0775')
87-
}
8887
const spawnArgs = isCmd
8988
? ['/d', '/s', '/c', escape.cmd(scriptFile)]
90-
: ['-c', escape.sh(scriptFile)]
89+
: [isWindows ? translateWinPathToPosix(scriptFile) : scriptFile]
9190

9291
const spawnOpts = {
9392
env: spawnEnv,

Diff for: test/make-spawn-args.js

+9-37
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ if (isWindows) {
148148
cmd: 'script "quoted parameter"; second command',
149149
})
150150
t.equal(shell, 'blrorp', 'used ComSpec as default shell')
151-
t.match(args, ['-c', /\.sh'$/], 'got expected args')
151+
t.match(args, [/\.sh$/], 'got expected args')
152152
t.match(opts, {
153153
env: {
154154
npm_package_json: /package\.json$/,
@@ -160,7 +160,10 @@ if (isWindows) {
160160
windowsVerbatimArguments: undefined,
161161
}, 'got expected options')
162162

163-
const filename = unescapeSh(args[args.length - 1])
163+
let filename = unescapeSh(args[args.length - 1])
164+
if (process.platform === 'win32') {
165+
filename = filename.replace(/^\/([A-z])/, '$1:')
166+
}
164167
t.ok(fs.existsSync(filename), 'script file was written')
165168
cleanup()
166169
t.not(fs.existsSync(filename), 'cleanup removes script file')
@@ -325,7 +328,7 @@ if (isWindows) {
325328
args: ['"quoted parameter";', 'second command'],
326329
})
327330
t.equal(shell, 'sh', 'defaults to sh')
328-
t.match(args, ['-c', /\.sh'$/], 'got expected args')
331+
t.match(args, [/\.sh$/], 'got expected args')
329332
t.match(opts, {
330333
env: {
331334
npm_package_json: /package\.json$/,
@@ -339,7 +342,7 @@ if (isWindows) {
339342

340343
const filename = unescapeSh(args[args.length - 1])
341344
const contents = fs.readFileSync(filename, { encoding: 'utf8' })
342-
t.equal(contents, `#!/usr/bin/env sh\nscript '"quoted parameter";' 'second command'`)
345+
t.equal(contents, `script '"quoted parameter";' 'second command'`)
343346
t.ok(fs.existsSync(filename), 'script file was written')
344347
cleanup()
345348
t.not(fs.existsSync(filename), 'cleanup removes script file')
@@ -357,38 +360,7 @@ if (isWindows) {
357360
t.equal(shell, 'sh', 'defaults to sh')
358361
// no-control-regex disabled because we're specifically testing control chars
359362
// eslint-disable-next-line no-control-regex
360-
t.match(args, ['-c', /(?:\\|\/)[^<:>/\x04]+\.sh'$/], 'got expected args')
361-
t.match(opts, {
362-
env: {
363-
npm_package_json: /package\.json$/,
364-
npm_lifecycle_event: 'event',
365-
npm_lifecycle_script: 'script',
366-
},
367-
stdio: undefined,
368-
cwd: 'path',
369-
windowsVerbatimArguments: undefined,
370-
}, 'got expected options')
371-
372-
const filename = unescapeSh(args[args.length - 1])
373-
const contents = fs.readFileSync(filename, { encoding: 'utf8' })
374-
t.equal(contents, `#!/usr/bin/env sh\nscript '"quoted parameter";' 'second command'`)
375-
t.ok(fs.existsSync(filename), 'script file was written')
376-
cleanup()
377-
t.not(fs.existsSync(filename), 'cleanup removes script file')
378-
379-
t.end()
380-
})
381-
382-
t.test('skips /usr/bin/env if scriptShell is absolute', (t) => {
383-
const [shell, args, opts, cleanup] = makeSpawnArgs({
384-
event: 'event',
385-
path: 'path',
386-
cmd: 'script',
387-
args: ['"quoted parameter";', 'second command'],
388-
scriptShell: '/bin/sh',
389-
})
390-
t.equal(shell, '/bin/sh', 'kept provided setting')
391-
t.match(args, ['-c', /\.sh'$/], 'got expected args')
363+
t.match(args, [/(?:\\|\/)[^<:>/\x04]+\.sh$/], 'got expected args')
392364
t.match(opts, {
393365
env: {
394366
npm_package_json: /package\.json$/,
@@ -402,7 +374,7 @@ if (isWindows) {
402374

403375
const filename = unescapeSh(args[args.length - 1])
404376
const contents = fs.readFileSync(filename, { encoding: 'utf8' })
405-
t.equal(contents, `#!/bin/sh\nscript '"quoted parameter";' 'second command'`)
377+
t.equal(contents, `script '"quoted parameter";' 'second command'`)
406378
t.ok(fs.existsSync(filename), 'script file was written')
407379
cleanup()
408380
t.not(fs.existsSync(filename), 'cleanup removes script file')

0 commit comments

Comments
 (0)