@@ -446,18 +446,9 @@ function generateShShim (src: string, to: string, opts: InternalOptions): string
446446 shTarget = shTarget . split ( '\\' ) . join ( '/' )
447447 const quotedPathToTarget = path . isAbsolute ( shTarget ) ? `"${ shTarget } "` : `"$basedir/${ shTarget } "`
448448 const quotedPathToTarget_win = path . isAbsolute ( shTarget ) ? `"${ shTarget } "` : `"$basedir_win/${ shTarget } "`
449- let shTarget_win
450- // For `.cmd`/`.bat` targets the runtime is `cmd` and args is `/C`. When
451- // Git Bash / MSYS launches a native Win32 process, arguments that look
452- // like POSIX paths are translated — a bare `/C` becomes `C:\`, which
453- // drops the switch and leaves cmd.exe running interactively. Prefixing
454- // with `//` is the MSYS escape: it survives the translation and reaches
455- // cmd.exe as `/C`. Scoped to the cmd runtime so shebang-derived `/C`
456- // args on other shims are passed through unchanged.
449+ let shTarget_win = ''
457450 let args = opts . args || ''
458- if ( opts . prog === 'cmd' || opts . prog === 'cmd.exe' ) {
459- args = escapeMsysCmdSwitches ( args )
460- }
451+ const isCmdRuntime = opts . prog === 'cmd' || opts . prog === 'cmd.exe'
461452 const shNodePath = normalizePathEnvVar ( opts . nodePath ) . posix
462453 if ( ! shProg ) {
463454 shProg = quotedPathToTarget
@@ -481,14 +472,15 @@ function generateShShim (src: string, to: string, opts: InternalOptions): string
481472 // basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
482473 // basedir_win="$basedir"
483474 // exe=""
475+ // msys=""
484476 //
485477 // case `uname -a` in
486478 // *CYGWIN*|*MINGW*|*MSYS*)
487479 // if command -v cygpath > /dev/null 2>&1; then
488- // basedir=`cygpath -w "$basedir"`
489- // basedir_win="$basedir"
480+ // basedir_win=`cygpath -w "$basedir"`
490481 // fi
491482 // exe=".exe"
483+ // msys="true"
492484 // ;;
493485 // *WSL2*)
494486 // if command -v wslpath > /dev/null 2>&1; then
@@ -521,14 +513,15 @@ function generateShShim (src: string, to: string, opts: InternalOptions): string
521513basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')")
522514basedir_win="$basedir"
523515exe=""
516+ msys=""
524517
525518case \`uname -a\` in
526519 *CYGWIN*|*MINGW*|*MSYS*)
527520 if command -v cygpath > /dev/null 2>&1; then
528- basedir=\`cygpath -w "$basedir"\`
529- basedir_win="$basedir"
521+ basedir_win=\`cygpath -w "$basedir"\`
530522 fi
531523 exe=".exe"
524+ msys="true"
532525 ;;
533526 *WSL2*)
534527 if command -v wslpath > /dev/null 2>&1; then
558551`
559552 }
560553
561- if ( shLongProg ) {
562- if ( shProgHasExe ) {
563- sh += `\
554+ const generateExecBlock = ( execArgs : string ) => {
555+ if ( shLongProg ) {
556+ if ( shProgHasExe ) {
557+ return `\
564558if [ -x ${ shLongProgExe } ]; then
565- exec ${ shLongProgExe } ${ args } ${ shTarget_win } ${ progArgs } "$@"
559+ exec ${ shLongProgExe } ${ execArgs } ${ shTarget_win } ${ progArgs } "$@"
566560else
567- exec ${ shProgExe } ${ args } ${ shTarget_win } ${ progArgs } "$@"
561+ exec ${ shProgExe } ${ execArgs } ${ shTarget_win } ${ progArgs } "$@"
568562fi
569563`
570- } else {
571- sh += `\
564+ } else {
565+ return `\
572566if [ -n "$exe" ] && [ -x ${ shLongProgExe } ]; then
573- exec ${ shLongProgExe } ${ args } ${ shTarget_win } ${ progArgs } "$@"
567+ exec ${ shLongProgExe } ${ execArgs } ${ shTarget_win } ${ progArgs } "$@"
574568elif [ -x ${ shLongProg } ]; then
575- exec ${ shLongProg } ${ args } ${ shTarget } ${ progArgs } "$@"
569+ exec ${ shLongProg } ${ execArgs } ${ shTarget } ${ progArgs } "$@"
576570elif command -v ${ shProg } >/dev/null 2>&1; then
577- exec ${ shProg } ${ args } ${ shTarget } ${ progArgs } "$@"
571+ exec ${ shProg } ${ execArgs } ${ shTarget } ${ progArgs } "$@"
578572elif [ -n "$exe" ] && command -v ${ shProgExe } >/dev/null 2>&1; then
579- exec ${ shProgExe } ${ args } ${ shTarget_win } ${ progArgs } "$@"
573+ exec ${ shProgExe } ${ execArgs } ${ shTarget_win } ${ progArgs } "$@"
580574else
581- exec ${ shProg } ${ args } ${ shTarget } ${ progArgs } "$@"
575+ exec ${ shProg } ${ execArgs } ${ shTarget } ${ progArgs } "$@"
582576fi
577+ `
578+ }
579+ } else {
580+ return `\
581+ exec ${ shProg } ${ execArgs } ${ shTarget } ${ progArgs } "$@"
582+ exit $?
583583`
584584 }
585- } else {
585+ }
586+
587+ const msysArgs = isCmdRuntime ? escapeMsysCmdSwitches ( args ) : args
588+ if ( msysArgs !== args ) {
586589 sh += `\
587- exec ${ shProg } ${ args } ${ shTarget } ${ progArgs } "$@"
588- exit $?
590+ if [ -n "$msys" ]; then
591+ ${ indentShellBlock ( generateExecBlock ( msysArgs ) ) }
592+ else
593+ ${ indentShellBlock ( generateExecBlock ( args ) ) }
594+ fi
589595`
596+ } else {
597+ sh += generateExecBlock ( args )
590598 }
591599
592600 // Marker used by consumers to detect whether the shim is up-to-date
@@ -596,6 +604,10 @@ exit $?
596604 return sh
597605}
598606
607+ function indentShellBlock ( script : string ) : string {
608+ return script . split ( '\n' ) . map ( line => line ? ` ${ line } ` : line ) . join ( '\n' )
609+ }
610+
599611/**
600612 * Generate the content of a shim for PowerShell.
601613 *
0 commit comments