update

package
v0.2.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 14, 2025 License: MIT Imports: 3 Imported by: 0

README

pkg/update

Minimal, dependency-free helpers for deciding whether a self-update should proceed.

This package is intended to be used by CLIs that:

  • Determine a target release tag (latest or --tag)
  • Enforce guardrails (major-version guard, explicit downgrade intent)
  • Proceed to a separate verification + install pipeline only when appropriate

This is a building block: to implement a full self-update mechanism you still need code to fetch release metadata, select the right asset, verify integrity and authenticity (signatures + checksums), and install atomically.

API

  • DecideSelfUpdate(current, target string, explicitTag, force bool) (Decision, message string, exitCode int)
  • NormalizeVersion(v string) (normalized string, ok bool)
  • CompareSemver(a, b string) (cmp int, err error)
  • FormatVersionDisplay(v string) string
  • DescribeDecision(d Decision) string

Semver rules

  • Accepts vMAJOR.MINOR[.PATCH] with optional prerelease/build metadata.
    • Examples: v0.2.5, 0.2.5, v0.2.5-rc1, v1.0.0+build123
  • Prerelease precedence follows SemVer:
    • 0.2.5-rc1 < 0.2.5
    • Numeric prerelease identifiers sort numerically: rc.10 > rc.2
  • Build metadata (+...) is ignored for ordering.

Decision semantics

DecideSelfUpdate returns:

  • DecisionSkip when current == target and force == false
  • DecisionReinstall when current == target and force == true
  • DecisionProceed when a normal upgrade is available
  • DecisionDowngrade only when explicitTag == true and target < current
  • DecisionRefuse when the major version changes and force == false (upgrade or downgrade)
  • DecisionDevInstall when current is dev/0.0.0-dev/empty

The message is suitable for end-user output. The suggested exitCode is 0 for “success/skip” and 1 for “refuse”.

What’s intentionally out of scope

  • Release discovery (GitHub API, rate limits, auth, etc.)
  • Asset selection (GOOS/GOARCH matching, archives vs raw, etc.)
  • Verification workflows (minisign/PGP/ed25519; checksum parsing)
  • Installation (atomic replace, Windows lock fallback, permissions)

Documentation

Overview

Package update provides small, dependency-free helpers for deciding whether a self-update should proceed.

It is designed to be useful for any CLI that updates itself from signed releases (for example, from GitHub releases), where you want conservative guardrails and clear user messaging.

This package intentionally does not perform downloads, signature verification, checksum verification, or installation. It focuses on deciding whether an update should proceed given a current version and a target release tag.

Version model

  • Supports semver-like strings in the form "vMAJOR.MINOR[.PATCH]" with optional prerelease/build metadata (e.g., "v0.2.5-rc1", "v1.0.0+build123").
  • Prerelease precedence follows SemVer: "0.2.5-rc1" < "0.2.5".
  • "dev", "0.0.0-dev", and empty versions are treated as non-comparable and default to proceeding (developer escape hatch).

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CompareSemver

func CompareSemver(a, b string) (int, error)

CompareSemver compares two normalized semver-like strings. Returns -1 if a < b, 0 if a == b, 1 if a > b. Supports MAJOR.MINOR[.PATCH] with optional prerelease/build metadata; build metadata is ignored. Returns an error if either version cannot be parsed.

func DescribeDecision

func DescribeDecision(d Decision) string

DescribeDecision returns a human-readable dry-run status.

func FormatVersionDisplay

func FormatVersionDisplay(v string) string

FormatVersionDisplay formats a version string for display, adding "v" prefix if needed.

func NormalizeVersion

func NormalizeVersion(v string) (string, bool)

NormalizeVersion strips the leading "v" prefix and validates that the version is semver-like (at least MAJOR.MINOR, optionally with PATCH, prerelease, and/or build metadata). Returns the normalized version string and a boolean indicating whether comparison is possible. "dev", empty strings, and non-semver formats return ("", false).

Types

type Decision

type Decision string
const (
	DecisionProceed    Decision = "proceed"    // Proceed with update
	DecisionSkip       Decision = "skip"       // Skip, already at target version
	DecisionRefuse     Decision = "refuse"     // Refuse (e.g., cross-major without force)
	DecisionReinstall  Decision = "reinstall"  // Force reinstall same version
	DecisionDowngrade  Decision = "downgrade"  // Explicit downgrade with --tag
	DecisionDevInstall Decision = "devinstall" // Installing release from dev build
)

func DecideSelfUpdate

func DecideSelfUpdate(current, target string, explicitTag, force bool) (Decision, string, int)

DecideSelfUpdate determines whether a self-update should proceed.

current: running binary version (e.g. "0.2.5" or "dev") target: target release tag (e.g. "v0.2.6") explicitTag: true if user specified --tag (allows downgrades) force: true if --self-update-force was specified

Returns a Decision, a human message, and an exit code suggestion (0=success/skip, 1=refuse).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL