From 9707118d94f003d71bc82772a2423336617b752e Mon Sep 17 00:00:00 2001 From: dipto0321 Date: Fri, 3 Jul 2026 09:01:19 +0600 Subject: [PATCH] fix(detector): align asdf env var on ASDF_DATA_DIR across detector, classifier, docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The asdf branch of `managerManagedRoots` (system_node.go) was reading `$ASDF_DIR` to discover the manager's data dir, while `asdfDataDir()` (the function the detector's actual `Install`/`ListInstalled` paths shell out against) reads `$ASDF_DATA_DIR` — and `docs/managers.md` documented `$ASDF_DIR` in the supported-manager table. The three were inconsistent. A user with `ASDF_DIR=/path/to/asdf-source` (the source checkout from a git-clone install) would have nodeup classify the `node` binary under that source dir as `manager`-managed even though the manager's actual install location was elsewhere (typically `~/.asdf`). Conversely, a user with the canonical `ASDF_DATA_DIR` override would have it silently ignored by the path classifier, leaving their manager install to be reported as `unknown` in `nodeup check` and triggering the upgrade-time warning. Unify all three on `$ASDF_DATA_DIR`, matching the variable `asdfDataDir()` already used and the official asdf docs (the source-checkout variable is `$ASDF_DIR`; the data dir override is `$ASDF_DATA_DIR`). Update the `system_node_test.go` "asdf env wins" case to drive the new variable, and `detector.go`'s package doc comment to match. Closes #50. Co-Authored-By: puku-ai-2.8 --- CHANGELOG.md | 16 ++++++++++++++++ docs/managers.md | 2 +- internal/detector/detector.go | 2 +- internal/detector/system_node.go | 12 +++++++++++- internal/detector/system_node_test.go | 6 +++--- 5 files changed, 32 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43c97d5..469a425 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -251,6 +251,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 part of #48 — `packages.go` was the last `RunE` file in the tree still using `context.Background()`. The unused `"context"` import is dropped. Closes #49. +- `internal/detector/system_node.go`: the asdf branch of + `managerManagedRoots` was reading `$ASDF_DIR` to discover the + manager's data dir, while `asdfDataDir()` (the function the + detector's actual `Install`/`ListInstalled` paths shell out + against) reads `$ASDF_DATA_DIR` — and `docs/managers.md` + documented `$ASDF_DIR` in the supported-manager table. The three + were inconsistent: a user with `ASDF_DIR=/path/to/asdf-source` + (the source checkout from git-clone) would have `nodeup` classify + the `node` binary under that source dir as `manager`-managed even + though the manager's actual install location was elsewhere + (typically `~/.asdf`), and a user with the canonical `ASDF_DATA_DIR` + override would have it silently ignored by the path classifier. + Unified all three on `$ASDF_DATA_DIR`, matching the variable + `asdfDataDir()` already used and the official asdf docs. + Updated `system_node_test.go`'s "asdf env wins" case to drive + the new variable. Closes #50. ## [0.0.0] - 2024-07-01 diff --git a/docs/managers.md b/docs/managers.md index d17f26a..a88b549 100644 --- a/docs/managers.md +++ b/docs/managers.md @@ -14,7 +14,7 @@ priority order — earlier managers win when multiple are installed. | [fnm](https://github.com/Schniz/fnm) | macOS, Linux, Windows | `fnm` on PATH, `FNM_DIR`, `~/Library/Application Support/fnm` (macOS) / `~/.local/share/fnm` (Linux) / `%AppData%\fnm` (Windows) | | [nvm](https://github.com/nvm-sh/nvm) | macOS, Linux | `NVM_DIR`, `~/.nvm/nvm.sh` | | [Volta](https://volta.sh) | macOS, Linux, Windows | `volta` on PATH, `VOLTA_HOME`, `~/.volta` | -| [asdf](https://asdf-vm.com) | macOS, Linux | `asdf` on PATH, `ASDF_DIR`, `~/.asdf`, `nodejs` plugin | +| [asdf](https://asdf-vm.com) | macOS, Linux | `asdf` on PATH, `ASDF_DATA_DIR`, `~/.asdf`, `nodejs` plugin | | [mise](https://mise.jdx.dev) | macOS, Linux | `mise` on PATH, `node` plugin | | [n](https://github.com/tj/n) | macOS, Linux | `n` on PATH, `N_PREFIX` | | [nodenv](https://github.com/nodenv/nodenv) | macOS, Linux | `nodenv` on PATH, `~/.nodenv/shims` | diff --git a/internal/detector/detector.go b/internal/detector/detector.go index 08fced9..596010d 100644 --- a/internal/detector/detector.go +++ b/internal/detector/detector.go @@ -9,7 +9,7 @@ // Detection priority (highest first): // 1. --manager CLI flag (caller-supplied) // 2. ~/.nodeup/config.yaml setting -// 3. environment variables (NVM_DIR, FNM_DIR, VOLTA_HOME, ASDF_DIR, ...) +// 3. environment variables (NVM_DIR, FNM_DIR, VOLTA_HOME, ASDF_DATA_DIR, ...) // 4. binary lookup on PATH // 5. well-known data directories // diff --git a/internal/detector/system_node.go b/internal/detector/system_node.go index 04c3633..fe1c6c7 100644 --- a/internal/detector/system_node.go +++ b/internal/detector/system_node.go @@ -412,7 +412,17 @@ func managerManagedRoots(m Manager) (roots []string, ok bool) { } return []string{}, true case "asdf": - if d := strings.TrimSpace(getenv("ASDF_DIR")); d != "" { + // $ASDF_DATA_DIR is the canonical override (matches + // asdfDataDir()'s view of the same variable, which is what + // the detector's Install/ListInstalled actually shell out + // against). $ASDF_DIR is a separate variable pointing at + // the asdf source checkout — not a data dir, not where + // versions live — and using it here would let the + // classifier claim a node binary under + // `/path/to/asdf-source/shims/node` is manager-managed when + // the manager's actual data dir is somewhere else entirely. + // See issue #50. + if d := strings.TrimSpace(getenv("ASDF_DATA_DIR")); d != "" { return []string{d}, true } if h, err := userHomeDir(); err == nil { diff --git a/internal/detector/system_node_test.go b/internal/detector/system_node_test.go index d8a8d51..25e61aa 100644 --- a/internal/detector/system_node_test.go +++ b/internal/detector/system_node_test.go @@ -305,7 +305,7 @@ func TestManagerManagedRoots(t *testing.T) { // "fall back to home" assertions noisy. t.Setenv saves and // restores each one to its pre-test value. for _, v := range []string{ - "FNM_DIR", "NVM_DIR", "VOLTA_HOME", "ASDF_DIR", + "FNM_DIR", "NVM_DIR", "VOLTA_HOME", "ASDF_DIR", "ASDF_DATA_DIR", "MISE_DATA_DIR", "N_PREFIX", "NODENV_ROOT", "XDG_DATA_HOME", } { @@ -366,10 +366,10 @@ func TestManagerManagedRoots(t *testing.T) { }, { name: "asdf env wins", - mgr: "asdf", envKey: "ASDF_DIR", envVal: "/opt/asdf", + mgr: "asdf", envKey: "ASDF_DATA_DIR", envVal: "/opt/asdf", wantRoots: []string{"/opt/asdf"}, wantOK: true, - description: "ASDF_DIR override", + description: "ASDF_DATA_DIR override (canonical asdf data-dir env)", }, { name: "mise env wins",