selfupdate

package
v0.25.0 Latest Latest
Warning

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

Go to latest
Published: Oct 3, 2026 License: MIT Imports: 21 Imported by: 0

Documentation

Overview

Package selfupdate replaces the running binary with a newer release.

Fetch the release asset for this GOOS/GOARCH, verify its SHA-256 against the checksums the release ships, and rename it over the current executable. Nothing is executed before it is verified, and a failed verification leaves the running binary untouched.

On Unix the dashboard notices the replacement on its own: internal/selfreload watches the executable and re-execs into whatever is there now, so an update applied from another terminal takes effect without anyone quitting. Windows cannot exec over a running image, so the dashboard exits and asks for a restart instead.

One concern per file: release.go is the release API and everything off the network, checksum.go the verification of a fetched asset against the release checksums, install.go the filesystem half that puts a verified binary in place.

Index

Constants

View Source
const DefaultRepo = "maci0/toktop"

DefaultRepo is the GitHub repository releases are fetched from.

View Source
const TokenEnv = "GITHUB_TOKEN"

TokenEnv is the optional environment variable authenticating the GitHub API calls `toktop update` makes, past the anonymous rate limit.

Variables

This section is empty.

Functions

func Apply

func Apply(ctx context.Context, rel *Release) (string, error)

Apply downloads, verifies, and installs the release over the running executable. It returns the path that was replaced.

The new binary is written next to the current one (same filesystem, so the rename is atomic) and only renamed after its checksum matches. A failed verification leaves the running binary untouched. If the destination already matches the release checksum, the asset is not fetched or replaced.

func AssetName

func AssetName(version string) string

AssetName is the binary this platform needs from a release. It must match the names `make release` writes into dist/, or self-update finds nothing.

func ChecksumFor

func ChecksumFor(listing, name string) (string, bool)

ChecksumFor finds one file's expected hash in a `sha256sum` style listing ("<hex> <name>", with an optional binary-mode asterisk).

func ChecksumListing

func ChecksumListing(archive []byte) (string, error)

ChecksumListing pulls checksums.txt out of the tar.gz the release ships it in. Entries are matched by base name, so a wrapper directory around the file does not matter; everything else in the archive is skipped.

func TrustedReleaseURL added in v0.16.0

func TrustedReleaseURL(raw string) bool

TrustedReleaseURL reports whether raw is a GitHub URL over https. Every release download and redirect hop is held to it, and so is the release page `toktop update --check` prints for a shell expansion: that page is never fetched, but it is release data landing in the caller's shell.

A URL that survives that second job carries no byte a shell would read as anything but itself. url.Parse only refuses C0 and DEL, and the space it admits ends the word: a release page spelled "https://github.com/o/r/releases/tag/v1 x$(id)" parses, names a trusted host, and reaches the operator as two words with a command substitution in the second. Every character a release URL is built from is kept, and anything else is refused; none of the refused bytes appear in a real GitHub URL, so nothing legitimate stops working.

func ValidateRepo added in v0.6.0

func ValidateRepo(repo string) error

ValidateRepo reports whether repo is a GitHub owner/name, the only shape interpolated into the releases API path. Anything else is path traversal, a query string, or log injection into the error that names the URL.

Types

type Release

type Release struct {
	TagName string `json:"tag_name"`
	HTMLURL string `json:"html_url"`
	Assets  []struct {
		Name string `json:"name"`
		URL  string `json:"browser_download_url"`
	} `json:"assets"`
}

Release is the subset of a GitHub release that matters here. The asset members are the only ones decoded: size and content_type are left out rather than carried unread, so a value spelled as a string or a float by some proxy cannot fail the whole decode and take the release down with it.

func Check

func Check(ctx context.Context, repo string) (*Release, error)

Check queries the latest release. It is never called on the startup path: a version check must not stand between the user and the dashboard.

func (*Release) NewerThan

func (r *Release) NewerThan(current string) bool

NewerThan reports whether the release is a different version from current. Comparison is deliberately exact rather than semver-aware: releases are the source of truth, and a "downgrade" published on purpose should be applied.

func (*Release) Version

func (r *Release) Version() string

Version is the release version without a leading "v".

Jump to

Keyboard shortcuts

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