Skip to content

Commit f660f8f

Browse files
authored
fix(sh shim): support running Windows binaries from wsl (#56)
1 parent bb8df42 commit f660f8f

3 files changed

Lines changed: 394 additions & 155 deletions

File tree

src/index.ts

Lines changed: 50 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,8 @@ function generateShShim (src: string, to: string, opts: InternalOptions): string
442442
let shLongProg
443443
shTarget = shTarget.split('\\').join('/')
444444
const quotedPathToTarget = path.isAbsolute(shTarget) ? `"${shTarget}"` : `"$basedir/${shTarget}"`
445+
const quotedPathToTarget_win = path.isAbsolute(shTarget) ? `"${shTarget}"` : `"$basedir_win/${shTarget}"`
446+
let shTarget_win
445447
// For `.cmd`/`.bat` targets the runtime is `cmd` and args is `/C`. When
446448
// Git Bash / MSYS launches a native Win32 process, arguments that look
447449
// like POSIX paths are translated — a bare `/C` becomes `C:\`, which
@@ -460,43 +462,68 @@ function generateShShim (src: string, to: string, opts: InternalOptions): string
460462
shTarget = ''
461463
} else if (opts.prog === 'node' && opts.nodeExecPath) {
462464
shProg = `"${opts.nodeExecPath}"`
463-
shTarget = quotedPathToTarget
465+
shTarget = /\.exe$/.test(opts.nodeExecPath) ? quotedPathToTarget_win : quotedPathToTarget
464466
} else {
465467
shLongProg = `"$basedir/${opts.prog}"`
466468
shTarget = quotedPathToTarget
469+
shTarget_win = quotedPathToTarget_win
467470
}
468471

469472
let progArgs = opts.progArgs ? `${opts.progArgs.join(` `)} ` : ''
470473

471474
// #!/bin/sh
472-
// basedir=`dirname "$0"`
475+
// basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
476+
// basedir_win="$basedir"
473477
//
474-
// case `uname` in
475-
// *CYGWIN*|*MINGW*|*MSYS*)
476-
// if command -v cygpath > /dev/null 2>&1; then
477-
// basedir=`cygpath -w "$basedir"`
478-
// fi
479-
// ;;
478+
// case `uname -a` in
479+
// *CYGWIN*|*MINGW*|*MSYS*)
480+
// if command -v cygpath > /dev/null 2>&1; then
481+
// basedir=`cygpath -w "$basedir"`
482+
// basedir_win="$basedir"
483+
// fi
484+
// ;;
485+
// *WSL2*)
486+
// if command -v wslpath > /dev/null 2>&1; then
487+
// basedir_win="$(wslpath -w "$basedir" 2> /dev/null)"
488+
// if [ $? -ne 0 ] || [ -z "$basedir_win" ]; then
489+
// basedir_win="$basedir"
490+
// fi
491+
// fi
492+
// ;;
480493
// esac
481494
//
482495
// export NODE_PATH="<nodepath>"
483496
//
484497
// if [ -x "$basedir/node.exe" ]; then
485-
// exec "$basedir/node.exe" "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
498+
// exec "$basedir/node.exe" "$basedir_win/node_modules/npm/bin/npm-cli.js" "$@"
499+
// elif [ -x "$basedir/node" ]; then
500+
// exec "$basedir/node" "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
501+
// elif [ -x node ]; then
502+
// exec node "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
486503
// else
487-
// exec node "$basedir/node_modules/npm/bin/npm-cli.js" "$@"
504+
// exec node.exe "$basedir_win/node_modules/npm/bin/npm-cli.js" "$@"
488505
// fi
489506

490507
let sh = `\
491508
#!/bin/sh
492509
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
493-
494-
case \`uname\` in
495-
*CYGWIN*|*MINGW*|*MSYS*)
496-
if command -v cygpath > /dev/null 2>&1; then
497-
basedir=\`cygpath -w "$basedir"\`
498-
fi
499-
;;
510+
basedir_win="$basedir"
511+
512+
case \`uname -a\` in
513+
*CYGWIN*|*MINGW*|*MSYS*)
514+
if command -v cygpath > /dev/null 2>&1; then
515+
basedir=\`cygpath -w "$basedir"\`
516+
basedir_win="$basedir"
517+
fi
518+
;;
519+
*WSL2*)
520+
if command -v wslpath > /dev/null 2>&1; then
521+
basedir_win="$(wslpath -w "$basedir" 2> /dev/null)"
522+
if [ $? -ne 0 ] || [ -z "$basedir_win" ]; then
523+
basedir_win="$basedir"
524+
fi
525+
fi
526+
;;
500527
esac
501528
502529
`
@@ -517,10 +544,14 @@ fi
517544

518545
if (shLongProg) {
519546
sh += `\
520-
if [ -x ${shLongProg} ]; then
547+
if [ -x ${shLongProg.replace(/"$/, '.exe"')} ]; then
548+
exec ${shLongProg.replace(/"$/, '.exe"')} ${args} ${shTarget_win} ${progArgs}"$@"
549+
elif [ -x ${shLongProg} ]; then
521550
exec ${shLongProg} ${args} ${shTarget} ${progArgs}"$@"
522-
else
551+
elif [ -x ${shProg} ]; then
523552
exec ${shProg} ${args} ${shTarget} ${progArgs}"$@"
553+
else
554+
exec ${shProg}.exe ${args} ${shTarget_win} ${progArgs}"$@"
524555
fi
525556
`
526557
} else {

test/e2e.test.js.snapshot

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,23 @@ exports[`create a command shim for a .exe file > shim files 1`] = `
22

33
#!/bin/sh
44
basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
5-
6-
case \`uname\` in
7-
*CYGWIN*|*MINGW*|*MSYS*)
8-
if command -v cygpath > /dev/null 2>&1; then
9-
basedir=\`cygpath -w "$basedir"\`
10-
fi
11-
;;
5+
basedir_win="$basedir"
6+
7+
case \`uname -a\` in
8+
*CYGWIN*|*MINGW*|*MSYS*)
9+
if command -v cygpath > /dev/null 2>&1; then
10+
basedir=\`cygpath -w "$basedir"\`
11+
basedir_win="$basedir"
12+
fi
13+
;;
14+
*WSL2*)
15+
if command -v wslpath > /dev/null 2>&1; then
16+
basedir_win="$(wslpath -w "$basedir" 2> /dev/null)"
17+
if [ $? -ne 0 ] || [ -z "$basedir_win" ]; then
18+
basedir_win="$basedir"
19+
fi
20+
fi
21+
;;
1222
esac
1323

1424
exec "$basedir/foo" "$@"

0 commit comments

Comments
 (0)