Skip to content

Go Edition: Uninstall command #500

Description

@Zordrak

Summary

Implement the tfenv uninstall command for the Go edition with full parity to the Bash edition, including multi-version uninstall, version resolution, and version-file fallback.

Parent Epic

Part of #488 — Go Edition: Full Feature Parity Implementation

Motivation

Users need to remove installed Terraform versions to reclaim disk space or clean up old versions. The Bash edition supports multiple versions in a single call, version resolution keywords (latest, latest:<regex>), reading from version files when no argument is given, and TFENV_TERRAFORM_VERSION override. The Go edition must match all of this.

Clean-Room Constraint

This is a clean-room implementation. Contributors MUST NOT read, reference, copy, or adapt source code from tofuutils/tenv, hashicorp/hc-install, or any other third-party tfenv-like tool. The sole reference is tfenv's own Bash source code, documentation, and test suite.

Proposed Design

Command Interface

tfenv uninstall <version> [<version2> ...]
tfenv uninstall latest
tfenv uninstall latest:<regex>
tfenv uninstall                          # reads from version file or TFENV_TERRAFORM_VERSION

Version Collection

The versions to uninstall are collected from (in priority order):

  1. Command-line arguments — one or more version specifiers
  2. TFENV_TERRAFORM_VERSION — if no args given and env var is set
  3. Version file chain — if no args and no env var, read from .terraform-version walk or ${TFENV_CONFIG_DIR}/version
  4. Error — if none of the above produce a version

Reference: libexec/tfenv-uninstall lines 105-134.

Single Version Uninstall Flow (uninstall_single_version)

For each version specifier:

  1. Reject min-required — not a valid uninstall target
  2. Reject latest-allowed — not a valid uninstall target
  3. Version resolution for latest keywords:
    • latest:<regex> → search locally installed versions matching regex, pick newest
    • latest (no regex) → search locally installed versions, pick newest
    • Exact version → use as-is, anchored with ^version$ regex
  4. Match against locally installed versions (via tfenv list output, stripped of markers and arch info)
  5. Verify ${TFENV_CONFIG_DIR}/versions/${version}/terraform exists
  6. Remove the version directory recursively (os.RemoveAll())
  7. Print confirmation: Terraform v${version} is successfully uninstalled

Reference: libexec/tfenv-uninstall lines 65-100.

Multi-Version Uninstall

When multiple arguments are given, each is uninstalled independently. If one fails, the others still proceed. The command tracks failures and returns non-zero exit code if ANY uninstall failed.

The Bash edition runs each uninstall in a subshell so that log 'error' (which calls exit 1) doesn't kill the loop. The Go edition should catch errors per-version and continue.

Post-Uninstall Cleanup

After all uninstalls complete, if the ${TFENV_CONFIG_DIR}/versions/ directory is empty, remove it with os.Remove() (not RemoveAll — only succeeds if actually empty). This is a courtesy cleanup, not an error if it fails.

Reference: libexec/tfenv-uninstall lines 141-143.

Path Traversal Protection

The version string MUST be validated before constructing filesystem paths. Reject any version containing /, \, .., or null bytes. This prevents path traversal attacks where a malicious .terraform-version file could cause deletion of arbitrary directories.

Acceptance Criteria

  • tfenv uninstall 1.5.0 removes the 1.5.0 version directory
  • tfenv uninstall 1.5.0 1.4.0 uninstalls both versions
  • tfenv uninstall latest uninstalls the newest locally installed version
  • tfenv uninstall latest:^1.5 uninstalls the newest installed 1.5.x version
  • tfenv uninstall (no args) reads version from .terraform-version or default version file
  • TFENV_TERRAFORM_VERSION is respected when no args given
  • tfenv uninstall min-required produces clear error ("unsupported option for uninstall")
  • tfenv uninstall latest-allowed produces clear error ("unsupported option for uninstall")
  • Error if version is not installed (clear message, non-zero exit)
  • Multi-version: continues past individual failures, returns non-zero if any failed
  • Empty versions/ directory is cleaned up after last version removed
  • Exit code 0 on full success, non-zero if any version failed
  • Does not affect other installed versions
  • Path traversal protection: rejects versions containing .., /, \, or null bytes
  • Acceptance tests verify single uninstall, multi-version uninstall, keyword resolution, and error cases

Dependencies

Implementation Notes

  • Reference libexec/tfenv-uninstall — 145 lines including standalone boilerplate. The actual logic is lines 65-145.
  • Key Bash behaviours to match:
    • Lines 70-72: min-required and latest-allowed rejected as unsupported
    • Lines 74-88: Version resolution — latest:regex, latest, and exact version handling
    • Lines 90: Match version against tfenv-list output (stripped of *, whitespace, arch info)
    • Lines 92-100: Check binary exists, remove directory, confirm
    • Lines 105-134: Version collection from args, TFENV_TERRAFORM_VERSION, or version file
    • Lines 136-140: Loop with failure counting (subshell per version)
    • Lines 142-143: Cleanup empty versions directory
  • Issue Add the option to uninstall several versions #449 (uninstall several versions) — the Bash edition already supports this; ensure parity
  • The Go edition uses os.RemoveAll() instead of rm -r
  • Version matching against installed versions must strip the * prefix and (arch) suffix from tfenv list output — or better, query the versions directory directly

Labels

type:feature, priority:high, complexity:small, category:uninstall

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions