Skip to content

fix(cli): --yes no longer overrides --no-cleanup precedence#86

Merged
dipto0321 merged 1 commit into
mainfrom
fix/cli/upgrade-no-cleanup-precedence
Jul 3, 2026
Merged

fix(cli): --yes no longer overrides --no-cleanup precedence#86
dipto0321 merged 1 commit into
mainfrom
fix/cli/upgrade-no-cleanup-precedence

Conversation

@dipto0321

Copy link
Copy Markdown
Owner

Summary

nodeup upgrade --yes --no-cleanup silently auto-deleted every eligible old Node.js version. The if yes { ... } block in runUpgrade ran unconditionally after the switch that was supposed to make --no-cleanup win — it flipped NonInteractive back to false and set AutoDeleteAll=true, regardless of noCleanup. That contradicts the documented contract of --no-cleanup ("never prompt, never delete") and is a real-world hazard for any CI script that habitually passes -y/--yes.

This PR factors the cleanup-toggle resolution into a pure helper resolveCleanupConfig(noCleanup, autoCleanup, yes, versions, cfg) in cleanup.go, and guards the --yes block with && !noCleanup so --no-cleanup wins on every flag combination.

Linked issues

Fixes #57

Type of change

  • fix — bug fix (PATCH bump)
  • feat — new feature (MINOR bump)
  • refactor — no behavior change
  • perf — performance improvement
  • docs — documentation only
  • test — tests only
  • chore — maintenance / dependency bump
  • ci — CI/CD only
  • build — build system only
  • Breaking change (MAJOR bump) — explain below

Checklist

Screenshots / output

Pre-fix behavior:

$ nodeup upgrade --yes --no-cleanup
Installing v22.11.0...
Installing v24.15.0...
Setting default...
Restoring packages for fnm...
Cleanup: Deleted: v18.20.4, v20.10.0  ← user did NOT ask for this

Post-fix behavior:

$ nodeup upgrade --yes --no-cleanup
Installing v22.11.0...
Installing v24.15.0...
Setting default...
Restoring packages for fnm...
Upgrade complete!

--yes alone (the CI-friendly behavior the bug tried to defend) is unchanged:

$ nodeup upgrade --yes
Installing v22.11.0...
...
Cleanup: Deleted: v18.20.4, v20.10.0  ← still works

Files touched

  • internal/cli/cleanup.go — new helper resolveCleanupConfig(noCleanup, autoCleanup, yes, cleanupVersions, cfg config.CleanupConfig) cleanupConfig. Doc comment carries the precedence table and references bug(cli): --yes silently overrides --no-cleanup, auto-deletes with zero confirmation #57. New import: internal/config.
  • internal/cli/upgrade.go — replaces the inline 30-line resolution block with a single call to resolveCleanupConfig(...). Drops the _ = yes placeholder and the now-redundant precedence comment.
  • internal/cli/cleanup_config_test.go — new file. 7 top-level test functions / 9 sub-tests pinning the precedence table end-to-end:
    • TestResolveCleanupConfig_NoCleanupBeatsYes — the regression test for bug(cli): --yes silently overrides --no-cleanup, auto-deletes with zero confirmation #57.
    • TestResolveCleanupConfig_YesAutoDeletesWithoutNoCleanup — pins that CI scripts passing -y still get auto-confirm.
    • TestResolveCleanupConfig_CleanupFlagSetsAutoDeleteAll, TestResolveCleanupConfig_ConfigAutoSetsAutoDeleteAll — each input knob individually.
    • TestResolveCleanupConfig_PrefilteredPropagates--cleanup-version flows through unchanged.
    • TestResolveCleanupConfig_DefaultsAreInteractive, TestResolveCleanupConfig_CfgPromptFalseSkipsPerVersion — default and cfg.Cleanup.Prompt=false paths.
    • TestResolveCleanupConfig_NoCleanupBeatsEverythingElse — negative-path matrix (4 sub-tests) covering every knob --no-cleanup must beat, so a future regression that re-introduces the bug (or its sibling in a new knob) is caught at the helper level rather than via a full end-to-end upgrade run.
  • CHANGELOG.md### Fixed entry under [Unreleased] documenting the change with the bug(cli): --yes silently overrides --no-cleanup, auto-deletes with zero confirmation #57 reference.

The `if yes { ... }` block in runUpgrade ran unconditionally AFTER
the `switch` that was supposed to make `--no-cleanup` win. It
flipped `NonInteractive` back to `false` and set
`AutoDeleteAll=true`, so `nodeup upgrade --yes --no-cleanup`
silently deleted every eligible old Node.js version with zero
confirmation of any kind — the exact opposite of `--no-cleanup`'s
documented "never prompt, never delete" contract.

This is a real-world hazard: CI scripts habitually pass
`-y`/`--yes` to every CLI, and a maintainer's npm/nodeup
playbook running such a script could lose Node installs it never
asked to remove.

The cleanup-toggle resolution is factored into a pure helper
`resolveCleanupConfig(noCleanup, autoCleanup, yes, versions, cfg)`
in cleanup.go, and the `--yes` block is guarded with
`&& !noCleanup` so `--no-cleanup` wins on every flag combination.

New tests in cleanup_config_test.go pin the precedence table:

- TestResolveCleanupConfig_NoCleanupBeatsYes (the bug)
- TestResolveCleanupConfig_YesAutoDeletesWithoutNoCleanup (CI
  scripts still get the auto-confirm they expect)
- TestResolveCleanupConfig_CleanupFlagSetsAutoDeleteAll /
  TestResolveCleanupConfig_ConfigAutoSetsAutoDeleteAll (each input
  knob individually)
- TestResolveCleanupConfig_PrefilteredPropagates (--cleanup-version
  flows through unchanged)
- TestResolveCleanupConfig_DefaultsAreInteractive /
  TestResolveCleanupConfig_CfgPromptFalseSkipsPerVersion
- TestResolveCleanupConfig_NoCleanupBeatsEverythingElse — negative
  matrix covering every knob `--no-cleanup` must beat, so a future
  regression that re-introduces the bug (or its sibling in a new
  knob) is caught at the helper level rather than via a full
  end-to-end upgrade run.

Refs #57
@cocogitto-bot

cocogitto-bot Bot commented Jul 3, 2026

Copy link
Copy Markdown

✔️ 9ad9d02 - Conventional commits check succeeded.

@dipto0321 dipto0321 merged commit 93c2bcb into main Jul 3, 2026
10 checks passed
@dipto0321 dipto0321 deleted the fix/cli/upgrade-no-cleanup-precedence branch July 3, 2026 03:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(cli): --yes silently overrides --no-cleanup, auto-deletes with zero confirmation

1 participant