selfupdate

package
v0.14.0 Latest Latest
Warning

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

Go to latest
Published: Jun 18, 2026 License: Apache-2.0 Imports: 19 Imported by: 0

Documentation

Overview

Package selfupdate resolves the latest stable release of the specscore CLI from GitHub and compares it against the running build's version.

Index

Constants

View Source
const DevVersion = "dev"

DevVersion is the placeholder reported by binaries built without -ldflags.

Variables

This section is empty.

Functions

func AssetName

func AssetName(version, goos, goarch string) string

AssetName builds the GoReleaser archive name for the given version and target OS/arch. The version's leading "v" is stripped to match GoReleaser's name_template ("specscore_{Version}_{Os}_{Arch}"). Windows uses .zip; all other platforms use .tar.gz.

func CompareVersions

func CompareVersions(a, b string) int

CompareVersions orders two semver-ish version strings, returning -1 if a < b, 0 if they are equal, and +1 if a > b. A leading "v" is ignored. Comparison is by numeric major/minor/patch; a prerelease suffix (after "-") sorts lower than the same release without it, per semver. This is a minimal comparison sufficient for the self-update downgrade guard, not a full semver implementation.

func ManagerName

func ManagerName(m Manager) string

ManagerName returns a human-readable name for a manager, for display in the redirect message.

func ReplaceExecutable

func ReplaceExecutable(targetPath, newBinaryPath string) error

ReplaceExecutable atomically swaps the binary at newBinaryPath into targetPath. The new binary is first staged to a temp file in the same directory as targetPath (same filesystem, so os.Rename is atomic), with executable permissions (0755), then renamed over the target.

On POSIX, os.Rename within one directory atomically replaces the target — the install location is never left with a partial or truncated file: it holds either the original or the complete new binary. On Windows, a running .exe cannot be overwritten, so the existing target is first renamed aside to targetPath+".old" before the new binary is moved into place.

Any staging error before the rename returns the error and leaves targetPath untouched.

func UpgradeCommand

func UpgradeCommand(m Manager) (string, bool)

UpgradeCommand returns the exact upgrade command a user should run for a package-manager-managed install, and true when m is a recognized manager. For ManagerNone or any unknown manager it returns ("", false).

func VerifyBinaryVersion

func VerifyBinaryVersion(path, wantVersion string) error

VerifyBinaryVersion runs "<path> --version" and returns an error unless the command output contains wantVersion. It is kept separate from ReplaceExecutable so the swap and the post-swap sanity check are independently testable.

Types

type CheckResult

type CheckResult struct {
	Current string
	Latest  string
	Verdict Verdict
}

CheckResult captures the comparison between the current build and the latest stable release.

func Compare

func Compare(current, latestTag string) CheckResult

Compare determines the verdict for a current build version against the latest stable release tag. A "dev" current version is Undetermined. Leading "v" prefixes are normalized before comparison.

type Detection

type Detection struct {
	Method  InstallMethod
	Manager Manager
}

Detection is the result of classifying an executable path.

func Classify

func Classify(execPath string) Detection

Classify decides the install method purely from execPath. It is case-insensitive and treats both '/' and '\' as path separators so Windows paths can be tested on any host.

func DetectSelf

func DetectSelf() (Detection, error)

DetectSelf resolves the running executable's path (following symlinks when possible) and classifies it.

type Downloader

type Downloader struct {
	// BaseURL is the directory under which assets and the checksums file live.
	// When empty, defaultDownloadBaseURL is used.
	BaseURL string
	// Client is the HTTP client used for requests. When nil, http.DefaultClient
	// is used.
	Client *http.Client
}

Downloader fetches and verifies release assets. BaseURL and Client are injectable so tests can target an httptest.Server.

func (Downloader) DownloadAndVerify

func (d Downloader) DownloadAndVerify(ctx context.Context, version, goos, goarch string) (string, error)

DownloadAndVerify downloads the release asset matching the given version and target OS/arch, verifies its sha256 against the release checksums.txt, and — only on a successful match — extracts the specscore binary into a temp file whose path is returned. When goos/goarch are empty, runtime.GOOS/GOARCH are used.

Verification happens before any extraction. On a checksum mismatch or a missing/unfetchable checksum entry, it returns a non-zero *exitcode.Error and an empty path, having touched no executable. This function never writes to or replaces the running executable; the swap is a separate concern.

type InstallMethod

type InstallMethod int

InstallMethod classifies how the running binary was installed.

const (
	// Managed means a package manager owns the binary; self-update is not eligible.
	Managed InstallMethod = iota
	// Manual means the binary was placed by the user (release archive or go install);
	// self-replace is eligible.
	Manual
	// Ambiguous means the location does not clearly indicate either method.
	Ambiguous
)

type Manager

type Manager int

Manager identifies a package manager that owns a managed install.

const (
	// ManagerNone means no package manager was detected.
	ManagerNone Manager = iota
	// Homebrew is the macOS/Linux Homebrew package manager.
	Homebrew
	// Scoop is the Windows Scoop package manager.
	Scoop
	// WinGet is the Windows Package Manager.
	WinGet
)

type Resolver

type Resolver struct {
	// BaseURL is the releases endpoint. When empty, defaultReleasesURL is used.
	BaseURL string
	// Client is the HTTP client used for requests. When nil, http.DefaultClient
	// is used.
	Client *http.Client
}

Resolver fetches release information from GitHub. The base URL and HTTP client are injectable so tests can target an httptest.Server.

func (Resolver) LatestStableTag

func (r Resolver) LatestStableTag(ctx context.Context) (string, error)

LatestStableTag returns the tag of the newest non-prerelease, non-draft release. Releases are returned newest-first by the GitHub API; this skips prereleases and drafts and selects the first stable entry.

type Verdict

type Verdict int

Verdict is the outcome of comparing the current build against the latest stable release.

const (
	// UpToDate means the current version equals the latest stable release.
	UpToDate Verdict = iota
	// Available means a newer stable release exists.
	Available
	// Undetermined means the current version could not be established (e.g. a
	// dev build).
	Undetermined
)

func (Verdict) ExitCode

func (v Verdict) ExitCode() int

ExitCode maps a verdict to the process exit code the CLI should use. UpToDate exits 0; Available and Undetermined exit 10.

Jump to

Keyboard shortcuts

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