Documentation
¶
Overview ¶
Package selfupdate replaces a running program with a newer release of itself: it finds the newest release of one binary stream, downloads that platform's archive, verifies it against the release's checksums.txt, and swaps the program and its companion executables in place.
It is mechanism only. Which repository, which tag prefix, which files to install, when to check and whether to ask first are the caller's decisions, so any command-line program released the way docsync is (archives named <binary>_<version>_<os>_<arch>.tar.gz, .zip on Windows, beside a checksums.txt of sha256 sums) can use it. It imports no command framework and keeps no state of its own: the throttle file in State lives wherever the caller says.
Index ¶
Constants ¶
const ChecksumsFile = "checksums.txt"
ChecksumsFile is the asset every release carries, one "<sha256> <asset>" line per archive.
Variables ¶
var ( // ErrNoRelease means the source has no published release in the stream. ErrNoRelease = errors.New("no release found") // ErrChecksum means the archive does not match the sum the release // published for it; nothing is installed. ErrChecksum = errors.New("checksum verification failed") // ErrNotInArchive means the archive lacks the program being updated. ErrNotInArchive = errors.New("not in the release archive") )
Errors.
Functions ¶
Types ¶
type GitHub ¶
type GitHub struct {
// Repo is "owner/name".
Repo string
// TagPrefix selects the stream in a repository that releases several
// things: "ds/" for tags "ds/v0.1.7". Empty for plain "v0.1.7" tags.
TagPrefix string
// Token, when set, authenticates API calls, which otherwise share a
// limit of 60 an hour per address.
Token string
// Client is the HTTP client; nil is http.DefaultClient.
Client *http.Client
// Web and API are the server roots; empty means github.com.
Web, API string
}
GitHub is a Source for one tag-prefixed stream of a GitHub repository's releases.
func (GitHub) Latest ¶
Latest asks the /releases/latest redirect first: it has no rate limit and names only a published, non-prerelease release. In a repository with several streams it names whichever was marked latest, so when that is not this stream the release list is read instead, which is rate limited.
type Install ¶
type Install struct {
Source Source
Release Release
// Asset is the archive to fetch, usually AssetName(...).
Asset string
// Dir is the directory the files are installed in, normally the one
// holding the running program.
Dir string
// Main is the program's file name inside the archive. It must be there.
Main string
// Want reports which other archive entries to install beside Main (the
// program's plugins). Nil installs Main alone.
Want func(name string) bool
}
Install is one update: which release, which archive, where to.
type Release ¶
type Release struct {
// Tag is the git tag, with the stream's prefix: "ds/v0.1.7".
Tag string `json:"tag"`
// Version is the tag without the prefix: "v0.1.7".
Version string `json:"version"`
// URL is the release's web page, where its notes are.
URL string `json:"url"`
}
Release is one published release of a binary stream.
type Result ¶
type Result struct {
// Bytes is the archive's size.
Bytes int64 `json:"bytes"`
// Installed names the files written into Dir, Main first.
Installed []string `json:"installed"`
}
Result is what an Install did.
type Source ¶
type Source interface {
// Latest is the newest published release of the stream.
Latest(ctx context.Context) (Release, error)
// Release names a version of the stream without contacting anything;
// a version that was never released fails at Download.
Release(version string) Release
// Download opens one asset of a release.
Download(ctx context.Context, rel Release, asset string) (io.ReadCloser, error)
}
Source finds and fetches releases. GitHub is the implementation; a program released elsewhere supplies its own.
type State ¶
type State struct {
CheckedAt time.Time `json:"checked_at"`
Latest string `json:"latest,omitempty"`
Failed string `json:"failed,omitempty"`
}
State is what a caller remembers between runs to check at most once per interval: when it last asked, what it was told, and which version it already failed to install (so a read-only install directory is not re-downloaded on every run).
func LoadState ¶
LoadState reads a state file. A missing or unreadable file is the zero State, which is due at once: the worst a lost file costs is one check.