From cbb8bed927d36c4042063f7af5cfe458274d21d0 Mon Sep 17 00:00:00 2001 From: Mikhail Korotin Date: Mon, 29 Sep 2025 15:38:23 +0200 Subject: [PATCH 1/2] use realpath for building path of bin-file if use virtual-store outside of node_modules and node_modules outside of build dir, bin path can be broke for example we have this hypothetical structure ``` ~/Projects/app/node_modules -> ~/.cache/modules/app/node_modules ~/.cache/modules/app/node_modules/eslint -> ~/.cache/vstore/app/eslint@8.56.0/node_modules/eslint ~/.cache/modules/app/node_modules/.bin/eslint => $0 => node_modules/.bin/eslint basedir => node_modules/.bin ... node "node_modules/.bin/../../../../vstore/app/eslint@8.56.0/node_modules/eslint/bin/eslint.js" => error, module not found ``` module not found, because path is incorrect `~/Projects/app/node_modules/.bin/../../../../vstore/app/eslint@8.56.0/node_modules/eslint/bin/eslint.js` with realpath it will fixed ``` realpath $0 => ~/.cache/modules/app/node_modules/.bin/eslint basedir => ~/.cache/modules/app/node_modules/.bin node ~/.cache/modules/app/node_modules/.bin/../../../../vstore/app/eslint@8.56.0/node_modules/eslint/bin/eslint.js => no errors ``` ps: we have node_modules outside of our build dir for some optimisation --- src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/index.ts b/src/index.ts index 91e2ae9..2c1f066 100644 --- a/src/index.ts +++ b/src/index.ts @@ -458,7 +458,7 @@ function generateShShim (src: string, to: string, opts: InternalOptions): string let sh = `\ #!/bin/sh -basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") +basedir=$(dirname "$(realpath "$0" | sed -e 's,\\\\,/,g')") case \`uname\` in *CYGWIN*|*MINGW*|*MSYS*) From 3ead6bbe7fb499bdbd32377157697036ec19f233 Mon Sep 17 00:00:00 2001 From: Mikhail Korotin Date: Thu, 9 Oct 2025 22:30:30 +0000 Subject: [PATCH 2/2] fix snapshot --- src/index.ts | 18 ++- test/__snapshots__/e2e.test.js.snap | 2 +- test/__snapshots__/test.js.snap | 237 ++++++++++++++++++++++++++-- 3 files changed, 243 insertions(+), 14 deletions(-) diff --git a/src/index.ts b/src/index.ts index 2c1f066..88bd251 100644 --- a/src/index.ts +++ b/src/index.ts @@ -458,7 +458,7 @@ function generateShShim (src: string, to: string, opts: InternalOptions): string let sh = `\ #!/bin/sh -basedir=$(dirname "$(realpath "$0" | sed -e 's,\\\\,/,g')") +basedir=$(dirname "$(echo "$0" | sed -e 's,\\\\,/,g')") case \`uname\` in *CYGWIN*|*MINGW*|*MSYS*) @@ -466,6 +466,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac ` diff --git a/test/__snapshots__/e2e.test.js.snap b/test/__snapshots__/e2e.test.js.snap index 1f4d141..ac9ebbf 100644 --- a/test/__snapshots__/e2e.test.js.snap +++ b/test/__snapshots__/e2e.test.js.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`create a command shim for a .exe file 1`] = ` "#!/bin/sh diff --git a/test/__snapshots__/test.js.snap b/test/__snapshots__/test.js.snap index 7b2edf7..e335a86 100644 --- a/test/__snapshots__/test.js.snap +++ b/test/__snapshots__/test.js.snap @@ -1,4 +1,4 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP +// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing exports[`batch script bat.shim 1`] = ` "#!/bin/sh @@ -10,6 +10,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir/cmd" ]; then @@ -73,6 +89,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac "/.pnpm/nodejs/16.0.0/node" "$basedir/src.env" "$@" @@ -116,6 +148,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir/node" ]; then @@ -179,6 +227,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -z "$NODE_PATH" ]; then @@ -265,6 +329,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac export PATH="/add-to-path:$PATH" @@ -340,6 +420,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir/node" ]; then @@ -403,6 +499,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir/node" ]; then @@ -466,6 +578,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir/node" ]; then @@ -529,6 +657,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir//usr/bin/sh" ]; then @@ -592,6 +736,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir//usr/bin/sh" ]; then @@ -664,17 +824,6 @@ else fi `; -exports[`explicit shebang with args, linking to another drive on Windows sh.args.shim.CMD 1`] = ` -"@SETLOCAL -@IF EXIST "%~dp0\\/usr/bin/sh.exe" ( - "%~dp0\\/usr/bin/sh.exe" -x "J:\\cmd-shim\\fixtures\\src.sh.args" %* -) ELSE ( - @SET PATHEXT=%PATHEXT:;.JS;=;% - /usr/bin/sh -x "J:\\cmd-shim\\fixtures\\src.sh.args" %* -) -" -`; - exports[`explicit shebang with args, linking to another drive on Windows sh.args.shim.ps1 1`] = ` "#!/usr/bin/env pwsh $basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent @@ -717,6 +866,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir//usr/bin/sh" ]; then @@ -780,6 +945,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac "$basedir/src.exe" "$@" @@ -817,6 +998,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac "$basedir/src.exe" "$@" @@ -860,6 +1057,22 @@ case \`uname\` in basedir=\`cygpath -w "$basedir"\` fi ;; + *) + if command -v realpath >/dev/null 2>&1; then + basedir=\`realpath "$basedir"\` + elif command -v readlink >/dev/null 2>&1; then + # some systems has the readlink, but doesn't have "-f" flag + if readlink -f "$basedir" >/dev/null 2>&1; then + basedir=\`readlink -f "$basedir"\` + else + basedir=\`readlink "$basedir"\` + fi + elif command -v perl >/dev/null 2>&1; then + basedir=\`perl -e 'use Cwd "abs_path"; print abs_path(shift)' "$basedir"\` + elif [[ $basedir != /* ]]; then + basedir="$PWD/\${basedir#./}" + fi + ;; esac if [ -x "$basedir/node" ]; then