selfupdate

package
v0.59.0 Latest Latest
Warning

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

Go to latest
Published: Nov 3, 2026 License: MIT Imports: 4 Imported by: 0

README

selfupdate

import "github.com/kitsunium/sdk/framework/internal/core/selfupdate"

Package selfupdate — the error-code range owned by this domain (ADR 0005 §Registry).

Package selfupdate — the sentinels every implementation of this domain returns.

The first five are the trust chain, and their ORDER is the contract: a build with no vendor key cannot install at all; a manifest with no signature is not authenticated; a signature that does not verify ends it; only then is the archive's digest compared against a manifest that is now trusted. A digest checked against an unauthenticated manifest proves nothing, which is why CodeChecksumMismatch can only be reached after CodeSignatureInvalid was not.

Package selfupdate is the contract for a binary that replaces itself: the ports it needs from its environment, and the values it reports.

The domain exists because the hard part of a self-update is not the download. It is the ORDER in which a candidate becomes trusted — a detached signature over a checksum manifest, then the archive's digest against that now-authenticated manifest, and only then anything touching the disk — and the fact that a process replacing its own executable has no second chance if it gets it wrong.

Three ports, and each is a seam a test drives rather than an abstraction for its own sake: Getter is the network, FileSystem is the disk, Copier is the stream between them. There is **no registry**: a registry's key would name a release host, and the whole trust chain is anchored to a key pinned at build time for exactly one host.

Package selfupdate — the three ports a self-update needs from its environment: the network, the disk, and the stream between them.

Package selfupdate — the values a self-update reports.

Index

Constants

const CodeAPIBodyTooLarge errs.Code = 139783

CodeAPIBodyTooLarge identifies a release-metadata response exceeding its cap.

Code 0.2.34.7

const CodeArchiveTooLarge errs.Code = 139782

CodeArchiveTooLarge identifies a release archive exceeding the size cap.

Code 0.2.34.6

const CodeBinaryNotInArchive errs.Code = 139792

CodeBinaryNotInArchive identifies a verified archive that does not contain the expected binary.

Code 0.2.34.16

const CodeCandidateNotFound errs.Code = 139788

CodeCandidateNotFound identifies a requested release candidate that does not exist.

Code 0.2.34.12

const CodeChecksumMismatch errs.Code = 139781

CodeChecksumMismatch identifies an archive whose digest did not match its authenticated manifest entry.

Code 0.2.34.5

const CodeChecksumMissing errs.Code = 139780

CodeChecksumMissing identifies an archive with no entry in the authenticated checksum manifest.

Code 0.2.34.4

const CodeDevBuild errs.Code = 139787

CodeDevBuild identifies a version check on a build with no release version to compare against.

Code 0.2.34.11

const CodeDownloadFailed errs.Code = 139786

CodeDownloadFailed identifies a download that did not complete.

Code 0.2.34.10

const CodeDraftRelease errs.Code = 139790

CodeDraftRelease identifies a draft release, which has no downloadable asset.

Code 0.2.34.14

const CodeElevationNotAuthorised errs.Code = 139794

CodeElevationNotAuthorised identifies a replacement needing privilege the operator did not opt into.

Code 0.2.34.18

const CodeInsecureRedirect errs.Code = 139784

CodeInsecureRedirect identifies a redirect leaving HTTPS, or exceeding the hop bound.

Code 0.2.34.8

const CodeInvalidTag errs.Code = 139791

CodeInvalidTag identifies a tag that is not a valid semantic version.

Code 0.2.34.15

const CodeNoVendorKey errs.Code = 139777

CodeNoVendorKey identifies an install attempted by a build that carries no vendor key, so nothing could have authenticated the release.

Code 0.2.34.1

const CodeNotPrerelease errs.Code = 139789

CodeNotPrerelease identifies a tag requested as a candidate that the host reports as a stable release.

Code 0.2.34.13

const CodeSignatureInvalid errs.Code = 139779

CodeSignatureInvalid identifies a checksum manifest whose signature did not verify against the vendor key.

Code 0.2.34.3

const CodeSignatureMissing errs.Code = 139778

CodeSignatureMissing identifies a release whose detached signature over the checksum manifest could not be fetched.

Code 0.2.34.2

const CodeUnexpectedStatus errs.Code = 139785

CodeUnexpectedStatus identifies a release host answering with a status the update path does not accept.

Code 0.2.34.9

const CodeUnknownArchive errs.Code = 139793

CodeUnknownArchive identifies an asset whose container format is not handled.

Code 0.2.34.17

Variables

var APIBodyTooLarge *errs.Error

APIBodyTooLarge is returned when a release-metadata response exceeds its cap.

Code 0.2.34.7 · reason API_BODY_TOO_LARGE · public "the release metadata is larger than this build accepts"

var ArchiveTooLarge *errs.Error

ArchiveTooLarge is returned when a release archive exceeds the size cap. The cap exists because the bytes are buffered in memory before anything has vouched for them.

Code 0.2.34.6 · reason ARCHIVE_TOO_LARGE · public "the release archive is larger than this build accepts"

var BinaryNotInArchive *errs.Error

BinaryNotInArchive is returned when a verified archive does not contain the expected binary. The archive is authentic; it is simply not what was expected, which is a packaging fault rather than an attack.

Code 0.2.34.16 · reason BINARY_NOT_IN_ARCHIVE · public "the release archive does not contain the expected binary"

var CandidateNotFound *errs.Error

CandidateNotFound is returned when a requested release candidate does not exist.

Code 0.2.34.12 · reason CANDIDATE_NOT_FOUND · public "no such release candidate"

var ChecksumMismatch *errs.Error

ChecksumMismatch is returned when the archive's digest does not match its authenticated manifest entry.

Code 0.2.34.5 · reason CHECKSUM_MISMATCH · public "the release archive does not match its checksum"

var ChecksumMissing *errs.Error

ChecksumMissing is returned when the authenticated manifest has no entry for the archive being installed.

Code 0.2.34.4 · reason CHECKSUM_MISSING · public "the release has no checksum for this platform"

var DevBuild *errs.Error

DevBuild is returned when a version check runs on a build with no release version to compare against.

Code 0.2.34.11 · reason DEV_BUILD · public "this build has no version to compare against a release"

var DownloadFailed *errs.Error

DownloadFailed is returned when a download does not complete.

Code 0.2.34.10 · reason DOWNLOAD_FAILED · public "the release could not be downloaded"

var DraftRelease *errs.Error

DraftRelease is returned for a draft release, which has no downloadable asset.

Code 0.2.34.14 · reason DRAFT_RELEASE · public "that release is still a draft"

var ElevationNotAuthorised *errs.Error

ElevationNotAuthorised is returned when replacing the binary needs privilege the operator did not opt into. Escalating without being asked is the one thing an updater must never do quietly.

Code 0.2.34.18 · reason ELEVATION_NOT_AUTHORISED · public "replacing this binary needs privilege that was not authorised"

var InsecureRedirect *errs.Error

InsecureRedirect is returned when a redirect leaves HTTPS or exceeds the hop bound. Following it would hand the archive fetch to a plaintext hop.

Code 0.2.34.8 · reason INSECURE_REDIRECT · public "the release host redirected somewhere this build will not follow"

var InvalidTag *errs.Error

InvalidTag is returned for a tag that is not a valid semantic version.

Code 0.2.34.15 · reason INVALID_TAG · public "that is not a valid version tag"

var NoVendorKey *errs.Error

NoVendorKey is returned when the running build carries no vendor key. It is a REFUSAL, not a degradation: without a key nothing could have authenticated the release, so there is no weaker check to fall back to.

Code 0.2.34.1 · reason NO_VENDOR_KEY · public "this build cannot verify a release and will not install one"

var NotPrerelease *errs.Error

NotPrerelease is returned when a tag requested as a candidate is reported as a stable release.

Code 0.2.34.13 · reason NOT_PRERELEASE · public "that tag is a stable release, not a candidate"

var SignatureInvalid *errs.Error

SignatureInvalid is returned when the checksum manifest's signature does not verify against the vendor key.

Code 0.2.34.3 · reason SIGNATURE_INVALID · public "the release signature did not verify"

var SignatureMissing *errs.Error

SignatureMissing is returned when the detached signature over the checksum manifest could not be fetched.

Code 0.2.34.2 · reason SIGNATURE_MISSING · public "the release is not signed"

var UnexpectedStatus *errs.Error

UnexpectedStatus is returned when the release host answers with a status the update path does not accept.

Code 0.2.34.9 · reason UNEXPECTED_STATUS · public "the release host answered unexpectedly"

var UnknownArchive *errs.Error

UnknownArchive is returned for an asset whose container format is not handled.

Code 0.2.34.17 · reason UNKNOWN_ARCHIVE · public "the release archive format is not supported"

type CandidateValue

CandidateValue is one release candidate: a developer channel entry that is never what a stable check returns.

All three fields are carried VERBATIM as the release host reported them. They are displayed to an operator choosing a candidate, never parsed and never compared — the ordering decision is made on Tag by semver, elsewhere.

type CandidateValue struct {
	// Tag is the release tag, e.g. "v1.9.0-rc.3".
	Tag       string
	// Name is the release's human title, which a host may leave empty.
	Name      string
	// CreatedAt is the RFC 3339 publication timestamp, as text.
	CreatedAt string
}

type Copier

Copier streams the verified archive to its temporary destination. It is a port so a test can fail the copy midway — the case where a partially written binary must never be renamed into place.

type Copier interface {
	// Copy copies from src to dst, returning the number of bytes written.
	Copy(dst io.Writer, src io.Reader) (written int64, err error)
}

func (Copier) Copy
func (Copier) Copy(dst io.Writer, src io.Reader) (written int64, err error)

Copy copies from src to dst, returning the number of bytes written.

type FileSystem

FileSystem is the disk half of replacing a running binary.

EvalSymlinks is not optional decoration: an executable reached through a symlink must be replaced at its REAL path, or the update writes over the link and the next run still executes the old binary.

type FileSystem interface {
	// Chmod changes file permissions.
	Chmod(name string, mode os.FileMode) error
	// CreateTemp creates a temporary file.
	CreateTemp(dir string, pattern string) (file *os.File, err error)
	// EvalSymlinks resolves symlinks in the given path.
	EvalSymlinks(path string) (resolved string, err error)
	// Executable returns the path of the current executable.
	Executable() (path string, err error)
	// Remove removes a file.
	Remove(name string) error
	// Rename renames a file. It is the atomic half of the replacement and must
	// happen on the same filesystem as the target.
	Rename(oldpath string, newpath string) error
}

func (FileSystem) Chmod
func (FileSystem) Chmod(name string, mode os.FileMode) error

Chmod changes file permissions.

func (FileSystem) CreateTemp
func (FileSystem) CreateTemp(dir string, pattern string) (file *os.File, err error)

CreateTemp creates a temporary file.

func (FileSystem) EvalSymlinks(path string) (resolved string, err error)

EvalSymlinks resolves symlinks in the given path.

func (FileSystem) Executable
func (FileSystem) Executable() (path string, err error)

Executable returns the path of the current executable.

func (FileSystem) Remove
func (FileSystem) Remove(name string) error

Remove removes a file.

func (FileSystem) Rename
func (FileSystem) Rename(oldpath string, newpath string) error

Rename renames a file. It is the atomic half of the replacement and must happen on the same filesystem as the target.

type Getter

Getter performs the HTTP GETs a self-update needs: the release metadata, the archive, the checksum manifest and its signature.

It is one method because that is all the domain needs, and a caller supplying a policy-carrying client (timeouts, redirect rules, proxies) is supplying it once for all four.

type Getter interface {
	// Get performs an HTTP GET request.
	Get(url string) (resp *http.Response, err error)
}

func (Getter) Get
func (Getter) Get(url string) (resp *http.Response, err error)

Get performs an HTTP GET request.

type UpdateValue

UpdateValue is the outcome of a version check or an install: whether a newer release exists, and the two versions that were compared.

Available is reported separately from a version comparison the caller could redo, because the comparison is semver-aware and a string compare of the two fields would disagree with it on a prerelease.

type UpdateValue struct {
	// CurrentVersion is the version of the running binary.
	CurrentVersion string
	// LatestVersion is the version that was found, or the empty string when
	// none was.
	LatestVersion  string
	// Available reports whether LatestVersion is newer than CurrentVersion.
	Available      bool
}

Generated from docs/api by tools/genindex.

Documentation

Overview

Package selfupdate — the error-code range owned by this domain (ADR 0005 §Registry).

Package selfupdate — the sentinels every implementation of this domain returns.

The first five are the trust chain, and their ORDER is the contract: a build with no vendor key cannot install at all; a manifest with no signature is not authenticated; a signature that does not verify ends it; only then is the archive's digest compared against a manifest that is now trusted. A digest checked against an unauthenticated manifest proves nothing, which is why CodeChecksumMismatch can only be reached after CodeSignatureInvalid was not.

Package selfupdate is the contract for a binary that replaces itself: the ports it needs from its environment, and the values it reports.

The domain exists because the hard part of a self-update is not the download. It is the ORDER in which a candidate becomes trusted — a detached signature over a checksum manifest, then the archive's digest against that now-authenticated manifest, and only then anything touching the disk — and the fact that a process replacing its own executable has no second chance if it gets it wrong.

Three ports, and each is a seam a test drives rather than an abstraction for its own sake: Getter is the network, FileSystem is the disk, Copier is the stream between them. There is **no registry**: a registry's key would name a release host, and the whole trust chain is anchored to a key pinned at build time for exactly one host.

Package selfupdate — the three ports a self-update needs from its environment: the network, the disk, and the stream between them.

Package selfupdate — the values a self-update reports.

Index

Constants

View Source
const CodeAPIBodyTooLarge errs.Code = 0x00_02_22_07 // 0.2.34.7

CodeAPIBodyTooLarge identifies a release-metadata response exceeding its cap.

View Source
const CodeArchiveTooLarge errs.Code = 0x00_02_22_06 // 0.2.34.6

CodeArchiveTooLarge identifies a release archive exceeding the size cap.

View Source
const CodeBinaryNotInArchive errs.Code = 0x00_02_22_10 // 0.2.34.16

CodeBinaryNotInArchive identifies a verified archive that does not contain the expected binary.

View Source
const CodeCandidateNotFound errs.Code = 0x00_02_22_0C // 0.2.34.12

CodeCandidateNotFound identifies a requested release candidate that does not exist.

View Source
const CodeChecksumMismatch errs.Code = 0x00_02_22_05 // 0.2.34.5

CodeChecksumMismatch identifies an archive whose digest did not match its authenticated manifest entry.

View Source
const CodeChecksumMissing errs.Code = 0x00_02_22_04 // 0.2.34.4

CodeChecksumMissing identifies an archive with no entry in the authenticated checksum manifest.

View Source
const CodeDevBuild errs.Code = 0x00_02_22_0B // 0.2.34.11

CodeDevBuild identifies a version check on a build with no release version to compare against.

View Source
const CodeDownloadFailed errs.Code = 0x00_02_22_0A // 0.2.34.10

CodeDownloadFailed identifies a download that did not complete.

View Source
const CodeDraftRelease errs.Code = 0x00_02_22_0E // 0.2.34.14

CodeDraftRelease identifies a draft release, which has no downloadable asset.

View Source
const CodeElevationNotAuthorised errs.Code = 0x00_02_22_12 // 0.2.34.18

CodeElevationNotAuthorised identifies a replacement needing privilege the operator did not opt into.

View Source
const CodeInsecureRedirect errs.Code = 0x00_02_22_08 // 0.2.34.8

CodeInsecureRedirect identifies a redirect leaving HTTPS, or exceeding the hop bound.

View Source
const CodeInvalidTag errs.Code = 0x00_02_22_0F // 0.2.34.15

CodeInvalidTag identifies a tag that is not a valid semantic version.

View Source
const CodeNoVendorKey errs.Code = 0x00_02_22_01 // 0.2.34.1

CodeNoVendorKey identifies an install attempted by a build that carries no vendor key, so nothing could have authenticated the release.

View Source
const CodeNotPrerelease errs.Code = 0x00_02_22_0D // 0.2.34.13

CodeNotPrerelease identifies a tag requested as a candidate that the host reports as a stable release.

View Source
const CodeSignatureInvalid errs.Code = 0x00_02_22_03 // 0.2.34.3

CodeSignatureInvalid identifies a checksum manifest whose signature did not verify against the vendor key.

View Source
const CodeSignatureMissing errs.Code = 0x00_02_22_02 // 0.2.34.2

CodeSignatureMissing identifies a release whose detached signature over the checksum manifest could not be fetched.

View Source
const CodeUnexpectedStatus errs.Code = 0x00_02_22_09 // 0.2.34.9

CodeUnexpectedStatus identifies a release host answering with a status the update path does not accept.

View Source
const CodeUnknownArchive errs.Code = 0x00_02_22_11 // 0.2.34.17

CodeUnknownArchive identifies an asset whose container format is not handled.

Variables

View Source
var (
	// NoVendorKey is returned when the running build carries no vendor key. It
	// is a REFUSAL, not a degradation: without a key nothing could have
	// authenticated the release, so there is no weaker check to fall back to.
	NoVendorKey = errs.Static(CodeNoVendorKey, "NO_VENDOR_KEY",
		"this build cannot verify a release and will not install one",
		"core/selfupdate: no vendor public key was linked into this build",
		0,
		0)

	// SignatureMissing is returned when the detached signature over the checksum
	// manifest could not be fetched.
	SignatureMissing = errs.Static(CodeSignatureMissing, "SIGNATURE_MISSING",
		"the release is not signed",
		"core/selfupdate: the detached signature over the checksum manifest was absent",
		0,
		0)

	// SignatureInvalid is returned when the checksum manifest's signature does
	// not verify against the vendor key.
	SignatureInvalid = errs.Static(CodeSignatureInvalid, "SIGNATURE_INVALID",
		"the release signature did not verify",
		"core/selfupdate: the manifest signature failed ed25519 verification against the vendor key",
		0,
		0)

	// ChecksumMissing is returned when the authenticated manifest has no entry
	// for the archive being installed.
	ChecksumMissing = errs.Static(CodeChecksumMissing, "CHECKSUM_MISSING",
		"the release has no checksum for this platform",
		"core/selfupdate: the authenticated manifest carries no entry for the requested asset",
		0,
		0)

	// ChecksumMismatch is returned when the archive's digest does not match its
	// authenticated manifest entry.
	ChecksumMismatch = errs.Static(CodeChecksumMismatch, "CHECKSUM_MISMATCH",
		"the release archive does not match its checksum",
		"core/selfupdate: the archive digest differs from its authenticated manifest entry",
		0,
		0)

	// ArchiveTooLarge is returned when a release archive exceeds the size cap.
	// The cap exists because the bytes are buffered in memory before anything
	// has vouched for them.
	ArchiveTooLarge = errs.Static(CodeArchiveTooLarge, "ARCHIVE_TOO_LARGE",
		"the release archive is larger than this build accepts",
		"core/selfupdate: the archive exceeded the in-memory size cap",
		0,
		0)

	// APIBodyTooLarge is returned when a release-metadata response exceeds its
	// cap.
	APIBodyTooLarge = errs.Static(CodeAPIBodyTooLarge, "API_BODY_TOO_LARGE",
		"the release metadata is larger than this build accepts",
		"core/selfupdate: the release API response exceeded its read cap",
		0,
		0)

	// InsecureRedirect is returned when a redirect leaves HTTPS or exceeds the
	// hop bound. Following it would hand the archive fetch to a plaintext hop.
	InsecureRedirect = errs.Static(CodeInsecureRedirect, "INSECURE_REDIRECT",
		"the release host redirected somewhere this build will not follow",
		"core/selfupdate: a redirect left https or exceeded the hop bound",
		0,
		0)

	// UnexpectedStatus is returned when the release host answers with a status
	// the update path does not accept.
	UnexpectedStatus = errs.Static(CodeUnexpectedStatus, "UNEXPECTED_STATUS",
		"the release host answered unexpectedly",
		"core/selfupdate: the release host returned a status the update path does not accept",
		0,
		0)

	// DownloadFailed is returned when a download does not complete.
	DownloadFailed = errs.Static(CodeDownloadFailed, "DOWNLOAD_FAILED",
		"the release could not be downloaded",
		"core/selfupdate: the release download did not complete",
		0,
		0)

	// DevBuild is returned when a version check runs on a build with no release
	// version to compare against.
	DevBuild = errs.Static(CodeDevBuild, "DEV_BUILD",
		"this build has no version to compare against a release",
		"core/selfupdate: the running build carries no release version",
		0,
		0)

	// CandidateNotFound is returned when a requested release candidate does not
	// exist.
	CandidateNotFound = errs.Static(CodeCandidateNotFound, "CANDIDATE_NOT_FOUND",
		"no such release candidate",
		"core/selfupdate: the requested candidate tag was not found on the release host",
		0,
		0)

	// NotPrerelease is returned when a tag requested as a candidate is reported
	// as a stable release.
	NotPrerelease = errs.Static(CodeNotPrerelease, "NOT_PRERELEASE",
		"that tag is a stable release, not a candidate",
		"core/selfupdate: the requested tag is not marked prerelease",
		0,
		0)

	// DraftRelease is returned for a draft release, which has no downloadable
	// asset.
	DraftRelease = errs.Static(CodeDraftRelease, "DRAFT_RELEASE",
		"that release is still a draft",
		"core/selfupdate: the requested release is a draft and exposes no asset",
		0,
		0)

	// InvalidTag is returned for a tag that is not a valid semantic version.
	InvalidTag = errs.Static(CodeInvalidTag, "INVALID_TAG",
		"that is not a valid version tag",
		"core/selfupdate: the tag is not a valid semantic version",
		0,
		0)

	// BinaryNotInArchive is returned when a verified archive does not contain
	// the expected binary. The archive is authentic; it is simply not what was
	// expected, which is a packaging fault rather than an attack.
	BinaryNotInArchive = errs.Static(CodeBinaryNotInArchive, "BINARY_NOT_IN_ARCHIVE",
		"the release archive does not contain the expected binary",
		"core/selfupdate: the verified archive holds no entry matching the binary name",
		0,
		0)

	// UnknownArchive is returned for an asset whose container format is not
	// handled.
	UnknownArchive = errs.Static(CodeUnknownArchive, "UNKNOWN_ARCHIVE",
		"the release archive format is not supported",
		"core/selfupdate: the asset is neither a tar.gz nor a zip",
		0,
		0)

	// ElevationNotAuthorised is returned when replacing the binary needs
	// privilege the operator did not opt into. Escalating without being asked is
	// the one thing an updater must never do quietly.
	ElevationNotAuthorised = errs.Static(CodeElevationNotAuthorised, "ELEVATION_NOT_AUTHORISED",
		"replacing this binary needs privilege that was not authorised",
		"core/selfupdate: the replacement required elevation and the opt-in was absent",
		0,
		0)
)

Functions

This section is empty.

Types

type CandidateValue

type CandidateValue struct {
	// Tag is the release tag, e.g. "v1.9.0-rc.3".
	Tag string
	// Name is the release's human title, which a host may leave empty.
	Name string
	// CreatedAt is the RFC 3339 publication timestamp, as text.
	CreatedAt string
}

CandidateValue is one release candidate: a developer channel entry that is never what a stable check returns.

All three fields are carried VERBATIM as the release host reported them. They are displayed to an operator choosing a candidate, never parsed and never compared — the ordering decision is made on Tag by semver, elsewhere.

type Copier

type Copier interface {
	// Copy copies from src to dst, returning the number of bytes written.
	Copy(dst io.Writer, src io.Reader) (written int64, err error)
}

Copier streams the verified archive to its temporary destination. It is a port so a test can fail the copy midway — the case where a partially written binary must never be renamed into place.

type FileSystem

type FileSystem interface {
	// Executable returns the path of the current executable.
	Executable() (path string, err error)
	// EvalSymlinks resolves symlinks in the given path.
	EvalSymlinks(path string) (resolved string, err error)
	// CreateTemp creates a temporary file.
	CreateTemp(dir, pattern string) (file *os.File, err error)
	// Chmod changes file permissions.
	Chmod(name string, mode os.FileMode) error
	// Rename renames a file. It is the atomic half of the replacement and must
	// happen on the same filesystem as the target.
	Rename(oldpath, newpath string) error
	// Remove removes a file.
	Remove(name string) error
}

FileSystem is the disk half of replacing a running binary.

EvalSymlinks is not optional decoration: an executable reached through a symlink must be replaced at its REAL path, or the update writes over the link and the next run still executes the old binary.

type Getter

type Getter interface {
	// Get performs an HTTP GET request.
	Get(url string) (resp *http.Response, err error)
}

Getter performs the HTTP GETs a self-update needs: the release metadata, the archive, the checksum manifest and its signature.

It is one method because that is all the domain needs, and a caller supplying a policy-carrying client (timeouts, redirect rules, proxies) is supplying it once for all four.

type UpdateValue

type UpdateValue struct {
	// CurrentVersion is the version of the running binary.
	CurrentVersion string
	// LatestVersion is the version that was found, or the empty string when
	// none was.
	LatestVersion string
	// Available reports whether LatestVersion is newer than CurrentVersion.
	Available bool
}

UpdateValue is the outcome of a version check or an install: whether a newer release exists, and the two versions that were compared.

Available is reported separately from a version comparison the caller could redo, because the comparison is semver-aware and a string compare of the two fields would disagree with it on a prerelease.

Jump to

Keyboard shortcuts

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