From 4524e28ff3a1624480d2ece2397ca9262d70cef8 Mon Sep 17 00:00:00 2001 From: Nick Novitski Date: Thu, 24 Oct 2024 10:09:26 -0700 Subject: [PATCH] feat(volta): unset _VOLTA_TOOL_RECURSION --- examples/volta/package-lock.json | 13 +++++++++++++ examples/volta/package.json | 6 ++++++ shell-modules/volta.nix | 26 ++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 examples/volta/package-lock.json create mode 100644 examples/volta/package.json diff --git a/examples/volta/package-lock.json b/examples/volta/package-lock.json new file mode 100644 index 0000000..30076f4 --- /dev/null +++ b/examples/volta/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "example-volta-project", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "example-volta-project", + "version": "1.0.0", + "license": "MIT" + } + } +} diff --git a/examples/volta/package.json b/examples/volta/package.json new file mode 100644 index 0000000..929067a --- /dev/null +++ b/examples/volta/package.json @@ -0,0 +1,6 @@ +{ + "name": "example-volta-project", + "version": "1.0.0", + "license": "MIT", + "volta": { "node": "23.0.0" } +} diff --git a/shell-modules/volta.nix b/shell-modules/volta.nix index 3a7888b..d1d8cf6 100644 --- a/shell-modules/volta.nix +++ b/shell-modules/volta.nix @@ -49,5 +49,31 @@ VOLTA_HOME="${cfg.home}" export VOLTA_HOME ''; + + # When a volta shim runs an npm script, if the environment variable + # _VOLTA_TOOL_RECURSION is not set, it sets it in the script's + # environment, and prepends the directory containing the non-shim tools + # of the pinned version to PATH. + # + # So with a package.json file like this, the command `npm run script` + # will run the shim `npm`, and the actual node version 23.0.0, with the + # output "v23.0.0": + # ```json + # { + # "scripts": { "script": "node --version" }, + # "volta": { "node": "23.0.0" } + # } + # ``` + # + # However, if the script evaluates this shell again, then the directory + # containing all the shims will be prepended to PATH, prioritizing them + # over the non-shim tools. If the script then runs any of those shims, + # they will not modify PATH, because _VOLTA_TOOL_RECURSION will be set. + # This can happen with scripts that use `direnv exec`, and can cause + # scripts to hang, or to error with `Volta error: is not + # available`. + # + # To prevent all this, we unset the variable when entering a shell. + env._VOLTA_TOOL_RECURSION = null; }; }