feat(cli): post-upgrade cleanup prompt + native mutation commands#56
Merged
Conversation
After a successful upgrade, nodeup upgrade now asks whether to delete
the old Node.js versions left behind. The prompt offers three options
- y deletes every candidate, typing a specific version (e.g. 20.18.0)
deletes only that one, and N (or empty enter) skips. Candidates are
computed as installed \ {new LTS, new Current, currently active}.
To make that prompt reachable, this PR also fills in the Install,
Uninstall, Use, SetDefault, GlobalNpmPrefix, and Current methods for
all 7 working managers (fnm, nvm, Volta, asdf, mise, n, nodenv). The
pre-existing stubs were returning ErrXxxNotImplemented, which made
nodeup upgrade itself fail before even getting to migration or
cleanup. Volta and n's SetDefault remain intentional no-ops (those
managers pin per-project, not per-machine). GlobalNpmPrefix returns
the per-version npm global modules directory for each manager's
on-disk layout. Current runs <manager> current (or per-manager
equivalent) so we can exclude the active version from cleanup
candidates. nvm-windows stays unsupported and returns
ErrNVMWindowsNotImplemented from Current; the prompt treats that
error as "active version unknown" and proceeds without exclusion.
New Manager interface method: Current() (semver.Version, error).
New upgrade flags: --cleanup, --cleanup-version <v>. The existing
--no-cleanup flag stays. Config equivalents (cleanup.auto /
cleanup.prompt) under the documented names; precedence is
--no-cleanup > --cleanup / cleanup.auto > --cleanup-version >
cleanup.prompt > default prompt.
Closes #41.
Co-Authored-By: Sonnet 4.6 <noreply@puku.sh>
- paramTypeCombine (×3): combine adjacent []semver.Version params
into a single declaration (runCleanupPrompt, cleanupCandidates,
intersectCandidates).
- emptyStringTest: replace `len(s) > 0` with `s != ""` in
trimNewline.
- SA4006 (×2): drop the unused `streams, _ := newCleanupIO("")`
calls in TestCleanupPrompt_AutoDeleteAll and
TestCleanupPrompt_PrefilteredOnly — both tests immediately
reassign `streams` from a multi-line buffer anyway.
Co-Authored-By: Sonnet 4.6 <noreply@puku.sh>
e80d24e to
8169e0b
Compare
|
✔️ 0be7a8a...8169e0b - Conventional commits check succeeded. |
This was referenced Jul 1, 2026
Closed
Closed
dipto0321
pushed a commit
that referenced
this pull request
Jul 5, 2026
…pkg-doc collision + dead FileOverlay Residual stale-comment / dead-code cleanups from the 2026-07-03 re-review that didn't belong in any of the active fix-wave PRs. All deletions / docstring edits — no behavior change. - internal/detector/fnm.go: delete ErrFNMNotImplemented (zero call sites, no tests, mutations have been real since PR #56); rewrite the FNM struct doc to describe the actual implemented surface (detection + mutations + layout queries) instead of "Phase 1 only, mutations not implemented"; drop the "left as stubs in Phase 1" paragraph from the mutation section. - internal/packages/sentinel.go: demote `// Package sentinel implements…` to `// Sentinel file handling: …` — godoc attributes package-doc comments to the actual package name (`packages`), so the rendered godoc was wrong. Verified no canonical `// Package packages …` comment exists elsewhere in the package, so this was the sole package-level doc and the move doesn't leave the package undocumented. - internal/config/resolve.go: delete superseded FileOverlay() (the coarse all-fields overlay that marked explicit-zero values as set — exactly the bug FileOverlayFromNode was introduced to fix in #85). Update the Overlay type's doc comment to point at FileOverlayFromNode as the file-layer builder. Closes #104. Co-Authored-By: puku-ai-2.8 <noreply@puku.sh>
dipto0321
pushed a commit
that referenced
this pull request
Jul 5, 2026
Residual stale-comment / dead-code cleanups from the 2026-07-03 re-review that didn't belong in any of the active fix-wave PRs. All deletions / docstring edits — no behavior change. - internal/detector/fnm.go: delete ErrFNMNotImplemented (zero call sites, no tests, mutations real since PR #56); rewrite the FNM struct doc to describe the actual surface (detection + mutations + layout queries) instead of "Phase 1 only, not implemented"; drop the "left as stubs in Phase 1" paragraph from the mutation section. - internal/packages/sentinel.go: demote "// Package sentinel implements..." to "// Sentinel file handling: ..." — godoc attributes package-doc comments to the actual package name (`packages`), so the rendered godoc was wrong. Verified no canonical "// Package packages ..." comment exists elsewhere, so the package isn't left undocumented. - internal/config/resolve.go: delete superseded FileOverlay() (the coarse all-fields overlay that marked explicit-zero values as set — exactly the bug FileOverlayFromNode was introduced to fix in #85). Update the Overlay type's doc comment to point at FileOverlayFromNode as the file-layer builder. Closes #104. Co-Authored-By: puku-ai-2.8 <noreply@puku.sh>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
After a successful upgrade,
nodeup upgradenow asks whether to delete the old Node.js versions left behind. The prompt offers three options —ydeletes every candidate, typing a specific version (e.g.20.18.0) deletes only that one, andN(or empty enter) skips. Candidates are computed asinstalled \ {new LTS, new Current, currently active}.To make the prompt actually reachable, this PR also fills in the
Install,Uninstall,Use,SetDefault,GlobalNpmPrefix, andCurrentmethods for all 7 working managers (fnm, nvm, Volta, asdf, mise, n, nodenv). The pre-existing stubs were returningErrXxxNotImplemented, which madenodeup upgradeitself fail before even getting to migration or cleanup. Volta's and n'sSetDefaultremain intentional no-ops (those managers pin per-project, not per-machine).GlobalNpmPrefixreturns the per-version npm global modules directory for each manager's on-disk layout.Currentruns<manager> current(or per-manager equivalent) so we can exclude the active version from cleanup candidates.nvm-windows stays unsupported and returns
ErrNVMWindowsNotImplementedfromCurrent; the prompt treats that error as "active version unknown" and proceeds without exclusion.Pre-existing problem this PR also fixes
PR #20 merged end-to-end
nodeup upgradewithm.Install(*v)andm.SetDefault(*latest)on lines 221/229 ofinternal/cli/upgrade.go, but everyManagerimplementation had those methods as stubs returningErrXxxNotImplemented. This meant:nodeup upgradewould fail immediately at line 221 withErrFNMNotImplemented(or whichever manager is active).Without implementing the mutation methods, the cleanup prompt is unreachable. So this PR expands scope: it ships the user-requested cleanup feature AND wires the mutations that make it actually work.
Manager interface change
New method on
Manager:Used to detect the currently-active version so the cleanup prompt can exclude it. Returns
ErrNVMWindowsNotImplementedfor nvm-windows (honestly documenting the gap).New CLI flags
--cleanup— auto-confirm deletion of every candidate--cleanup-version <v>— only delete these versions (repeatable; pairs with--cleanup)Existing
--no-cleanupflag stays as the "skip everything" toggle.--yesimplies--cleanupfor non-interactive runs (e.g., CI).Config equivalents
~/.nodeup/config.yaml:Precedence (highest first):
--no-cleanup>--cleanup(orcleanup.auto: true) >--cleanup-version <v>>cleanup.prompt: false> default interactive prompt.Per-manager behavior
fnm install <v>fnm uninstall <v>fnm currentsource nvm.sh && nvm install -s <v>… nvm uninstall <v>… nvm currentsystem/none→ "unknown"volta install node@<v>volta uninstall node@<v>node@<v>row ofvolta list --format=plainSetDefaultis a no-opasdf install nodejs <v>asdf uninstall nodejs <v>asdf current nodejsnodejsmise install node@<v>mise uninstall node@<v>mise current node~/.config/mise/config.tomln install <v>n uninstall <v>n current(n ≥ 8)SetDefaultis a no-opnodenv install <v>nodenv uninstall <v>nodenv version~/.nodenv/versionErrNVMWindowsNotImplementedTests
internal/cli/cleanup_test.go— table-driven prompt tests covering: empty stdin (skip),y/n(delete-all vs skip), per-versiony/nconfirm,--cleanup(auto),--cleanup-version <v>(prefiltered),cleanup.autoconfig-driven, no candidates (skip with friendly note), exclusion logic (active version + new versions excluded), uninstall error handling (one failure doesn't block others).internal/detector/<manager>_test.gofor each of the 7 working managers + nvm-windows: replaced the "stub returns ErrXxxNotImplemented" tests with real ones that capture the shell-out argv and assert it matches the per-manager command shape.-raceand 53.8% coverage.Docs
README.md— added a paragraph to Quickstart explaining the post-upgrade prompt.docs/managers.md— added a "Post-upgrade cleanup" section with the candidate-set formula, the flag table, the per-manager behavior table, and the failure modes.CHANGELOG.md— added entries under Unreleased → Added.Closes
🤖 Generated with puku-cli