diff --git a/lib/index.js b/lib/index.js index cf223fe..76ea2cb 100644 --- a/lib/index.js +++ b/lib/index.js @@ -19,7 +19,9 @@ const { const { dirname, relative } = require('path') const toBatchSyntax = require('./to-batch-syntax') -const shebangExpr = /^#!\s*(?:\/usr\/bin\/env\s*((?:[^ \t=]+=[^ \t=]+\s+)*))?([^ \t]+)(.*)$/ +// linting disabled because this regex is really long +// eslint-disable-next-line max-len +const shebangExpr = /^#!\s*(?:\/usr\/bin\/env\s+(?:-S\s+)?((?:[^ \t=]+=[^ \t=]+\s+)*))?([^ \t]+)(.*)$/ const cmdShimIfExists = (from, to) => stat(from).then(() => cmdShim(from, to), () => {}) diff --git a/tap-snapshots/test/basic.js.test.cjs b/tap-snapshots/test/basic.js.test.cjs index 0f1e9c4..74e1486 100644 --- a/tap-snapshots/test/basic.js.test.cjs +++ b/tap-snapshots/test/basic.js.test.cjs @@ -556,3 +556,72 @@ esac exec "$basedir/from.exe" "$@" ` + +exports[`test/basic.js TAP shebang with env -S > cmd 1`] = ` +@ECHO off\\r +GOTO start\\r +:find_dp0\\r +SET dp0=%~dp0\\r +EXIT /b\\r +:start\\r +SETLOCAL\\r +CALL :find_dp0\\r +\\r +IF EXIST "%dp0%\\node.exe" (\\r + SET "_prog=%dp0%\\node.exe"\\r +) ELSE (\\r + SET "_prog=node"\\r + SET PATHEXT=%PATHEXT:;.JS;=;%\\r +)\\r +\\r +endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" --expose_gc "%dp0%\\from.env.S" %*\\r + +` + +exports[`test/basic.js TAP shebang with env -S > cmd 2`] = ` +#!/usr/bin/env pwsh +$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent + +$exe="" +if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) { + # Fix case when both the Windows and Linux builds of Node + # are installed in the same directory + $exe=".exe" +} +$ret=0 +if (Test-Path "$basedir/node$exe") { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "$basedir/node$exe" --expose_gc "$basedir/from.env.S" $args + } else { + & "$basedir/node$exe" --expose_gc "$basedir/from.env.S" $args + } + $ret=$LASTEXITCODE +} else { + # Support pipeline input + if ($MyInvocation.ExpectingInput) { + $input | & "node$exe" --expose_gc "$basedir/from.env.S" $args + } else { + & "node$exe" --expose_gc "$basedir/from.env.S" $args + } + $ret=$LASTEXITCODE +} +exit $ret + +` + +exports[`test/basic.js TAP shebang with env -S > shell 1`] = ` +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") + +case \`uname\` in + *CYGWIN*|*MINGW*|*MSYS*) basedir=\`cygpath -w "$basedir"\`;; +esac + +if [ -x "$basedir/node" ]; then + exec "$basedir/node" --expose_gc "$basedir/from.env.S" "$@" +else + exec node --expose_gc "$basedir/from.env.S" "$@" +fi + +` diff --git a/test/00-setup.js b/test/00-setup.js index 239748a..5c2e6c0 100644 --- a/test/00-setup.js +++ b/test/00-setup.js @@ -13,6 +13,8 @@ const froms = { 'from.sh': '#!/usr/bin/sh\necho hi\n', 'from.sh.args': '#!/usr/bin/sh -x\necho hi\n', 'from.env.multiple.variables': '#!/usr/bin/env key=value key2=value2 node --flag-one --flag-two', + 'from.env.S': '#!/usr/bin/env -S node --expose_gc\ngc()\n', + 'from.env.nospace': '#!/usr/bin/envnode\nconsole.log(/hi/)\n', } mkdirSync(fixtures, { recursive: true }) diff --git a/test/basic.js b/test/basic.js index c33d919..3442b12 100755 --- a/test/basic.js +++ b/test/basic.js @@ -120,3 +120,12 @@ test('multiple variables', async t => { matchSnapshot(t, fs.readFileSync(to + '.cmd', 'utf8'), 'cmd') matchSnapshot(t, fs.readFileSync(to + '.ps1', 'utf8'), 'ps1') }) + +test('shebang with env -S', async t => { + var from = path.resolve(fixtures, 'from.env.S') + var to = path.resolve(fixtures, 'sh.env.S.shim') + await cmdShim(from, to) + matchSnapshot(t, fs.readFileSync(to, 'utf8'), 'shell') + matchSnapshot(t, fs.readFileSync(to + '.cmd', 'utf8'), 'cmd') + matchSnapshot(t, fs.readFileSync(to + '.ps1', 'utf8'), 'cmd') +})