Skip to content

[feat]: Add installation-aware vizb update command #262

Description

@fahimfaisaal

Problem / use case

Vizb users installed through install.sh or a release archive must currently reinstall manually to receive a new release. Vizb is also distributed through go install and WinGet, so blindly replacing whichever executable appears first on PATH could overwrite a package-manager-owned binary. Persisting a local installation receipt such as .vizb-install.json would add state that can become stale when binaries are moved or copied.

Windows standalone replacement has additional process-locking and installer-lifecycle concerns. It is intentionally deferred from the first version of this command.

Proposed solution

Add a no-argument vizb update command that inspects the executable which is actually running and chooses a safe update path without creating a local receipt or hosted release manifest.

Installation detection

Use the canonical path from os.Executable(), Go build metadata, and a GoReleaser-injected distribution marker in this order:

  1. Detect a WinGet package/link path and delegate with winget upgrade --id goptics.vizb --exact.
  2. Detect a versioned go install github.com/goptics/vizb@... build and delegate with go install github.com/goptics/vizb@latest.
  3. Allow native self-update only for official standalone Linux and macOS archives marked standalone by GoReleaser.
  4. For Windows standalone builds, make no network request or executable change and print irm https://vizb.goptics.org/install.ps1 | iex.
  5. Refuse development, source, or unidentified builds with clear recovery guidance.

Keep detection behind a small registry/interface so future Homebrew or other native package managers can add a detector and update instruction without changing the standalone updater. Windows self-update, Brew, and Docker support are not part of this issue.

Linux/macOS standalone update flow

  • Resolve the latest stable tag from the existing GitHub Releases endpoint.
  • Compare it with the running semantic version and avoid downgrades.
  • Build the existing GoReleaser asset name for the current OS and architecture.
  • Download the archive and the existing checksums.txt asset.
  • Verify SHA-256 before extracting or installing.
  • Stage the replacement beside the canonical executable and atomically rename it into place.
  • Report already-current, delegated, successful, unsupported, and actionable failure states clearly.

No .vizb-install.json, latest.json, or other persistent metadata file is introduced. GitHub Releases, Go build information, and GoReleaser metadata remain the sources of truth.

CLI and documentation

  • Register update as a Cobra subcommand with no positional arguments.
  • Document supported installation types, Windows limitations, and delegation behavior.
  • Mark official release archives with version.Distribution=standalone in .goreleaser.yml.
  • Preserve the existing install.sh and install.ps1 entry points.

Acceptance criteria

  • vizb update is visible in CLI help and rejects positional arguments.
  • An up-to-date Linux/macOS standalone build performs no installation and exits successfully.
  • An older Linux/macOS standalone build downloads the correct platform archive, verifies its entry in checksums.txt, and installs it safely.
  • A checksum mismatch, missing checksum, unsupported platform, unwritable executable directory, invalid release tag, or network failure leaves the running binary unchanged and returns an actionable error.
  • WinGet and Go-toolchain installs are not modified and print their exact manager update commands.
  • Windows standalone builds are not modified and print the existing PowerShell installer command without contacting the release service.
  • Development and unidentified builds are not modified.
  • Existing installer URLs and archive naming remain compatible.
  • No local receipt or new remote manifest is created.
  • New Go tests use testify/suite and cover detection, release resolution/version comparison, archive selection, checksum verification, extraction, replacement, delegation, Windows guidance, already-current behavior, and failure preservation without live network calls.
  • Focused tests, task test:cli, task lint:cli, task format:check, docs build, and goreleaser check pass.

Alternatives considered

  • A local .vizb-install.json receipt was rejected because copied or moved binaries can outlive or disagree with the receipt.
  • Treating every writable executable as standalone was rejected because it can overwrite package-manager-owned files.
  • Downloading and executing the public installer scripts from inside Vizb was rejected because it introduces mutable remote-code execution and can target a different path than the running executable.
  • Adding a hosted latest.json was deferred because GitHub Releases and checksums.txt already contain the required metadata.
  • Windows self-update, Homebrew, and Docker detection are intentionally deferred; the manager detector boundary is included now so they can be added independently later.

Blocked by

None - can start immediately.

Metadata

Metadata

Assignees

Labels

cliCommand line interface related tasksenhancementNew feature or requestrelease

Fields

Priority

Medium

Start date

None yet

Target date

None yet

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions