Documentation
¶
Overview ¶
Package selfupdate powers `dejima update`. Dejima installs two ways, so it updates two ways (the "dual-mode" epic):
- source mode — a dev/server box with the repo checked out, installed via `make install`. Updating means `git pull` + rebuild + reinstall.
- release mode — a client that installed a tagged binary (install.sh / a release asset). Updating means fetching the latest release binary and replacing the running one.
The mode is inferred from the build version: a real semver release (stamped via -ldflags at `make release`) means release mode; "dev"/a git-describe string means a source checkout.
This file is the *read-only* foundation: detect the mode and report whether a newer release exists. The mutating steps (git pull/rebuild; download/replace/ restart) are layered on top deliberately, behind their own review.
Index ¶
- Variables
- func ApplyReleaseSelf(ctx context.Context, ver string, out io.Writer) error
- func ApplySource(ctx context.Context, dir string, execute bool, out io.Writer, run Runner) error
- func AssetName(ver, goos, goarch string) string
- func FetchBinary(ctx context.Context, ver, goos, goarch, binName, destPath string) error
- func FindCheckout(start string) (string, error)
- func LatestRelease(ctx context.Context) (string, error)
- func PrepareSource(ctx context.Context, dir string, out io.Writer, run Runner) error
- func ReplaceExecutable(newPath, target string) error
- func ResolveSourceDir() string
- func SaveInstallMeta(m InstallMeta) error
- func SourcePreflight(ctx context.Context, dir string) error
- type InstallMeta
- type Mode
- type ReleaseInfo
- type Runner
- type Status
Constants ¶
This section is empty.
Variables ¶
var ErrReleaseApplyUnsupported = errors.New("automatic apply for release installs isn't supported yet")
ErrReleaseApplyUnsupported marks the not-yet-built release download path, so the command can print manual steps instead of failing opaquely.
var TokenFallback func() string
githubToken returns a GitHub token from the environment, if any, used to lift the release-check off the unauthenticated 60/hr rate limit (→ 5000/hr). TokenFallback, when set, supplies a GitHub token for the release-check API calls if neither GITHUB_TOKEN nor GH_TOKEN is set — so a daemon (or client) that already has a connected GitHub identity authenticates its update checks (5000/hr) instead of sharing the anonymous 60/hr-per-IP limit. Wired at startup to the connected identity; kept as a hook so selfupdate needn't import the identity store (and stays usable with no token at all).
Functions ¶
func ApplyReleaseSelf ¶
ApplyReleaseSelf updates the *running* executable to ver: it downloads the matching release, verifies it, and atomically replaces this binary in place. The install dir must be writable (the Windows client lives under LOCALAPPDATA; a root-owned /usr/local/bin needs elevation — caller surfaces that error).
func ApplySource ¶
ApplySource updates a source install. It preflights (a clean dejima checkout that can fast-forward), then either prints the plan (execute=false, the default) or runs it. It never force-merges or discards local work: a dirty or diverged tree is a hard stop, not something to paper over.
func AssetName ¶
AssetName returns the release archive name for a platform, matching the names produced by `make release-binaries` (see .github/workflows/release.yml): dejima_<ver>_<os>_<arch>.tar.gz, or .zip on Windows.
func FetchBinary ¶
FetchBinary downloads the release asset for (ver, goos, goarch), verifies it against the release's SHA256SUMS, and extracts the binary named binName (e.g. "dejima", "dejima.exe", "dejimad") to destPath (0755).
func FindCheckout ¶
FindCheckout walks up from start looking for the dejima source tree (a go.mod declaring this module). Returns an error with guidance if none is found.
func LatestRelease ¶
LatestRelease returns the tag of the newest published (non-prerelease) release.
func PrepareSource ¶
PrepareSource runs every source-update step EXCEPT the final restart: preflight, fast-forward the checkout, reinstall both binaries. The restart is deliberately left to the caller because it kills the running daemon — so the daemon's self-update can do this part synchronously (and report failures to the client) and only background the restart. Returns a wrapped error naming the step that failed.
func ReplaceExecutable ¶
ReplaceExecutable atomically swaps target with the binary at newPath (same directory). On Windows a running .exe can't be overwritten, so the running one is renamed aside first (and rolled back on failure).
func ResolveSourceDir ¶ added in v0.8.21
func ResolveSourceDir() string
ResolveSourceDir locates the git checkout a source install was built from, for recording in InstallMeta. Returns "" when it genuinely cannot be found.
Tries three things in order, because the single cwd-derived lookup this replaces was the reason `service install` could silently DESTROY a working record: the meta is written whole, so a run from outside the checkout (say `sudo dejima service install --system` typed from $HOME) resolved nothing, wrote SourceDir:"" over a good value, and left the daemon unable to update itself. Preserving a previously recorded checkout is the important part.
func SaveInstallMeta ¶
func SaveInstallMeta(m InstallMeta) error
SaveInstallMeta writes the install context (0600).
Types ¶
type InstallMeta ¶
type InstallMeta struct {
// SourceDir is the git checkout a source install was built from (""for a
// release/binary install — it updates by download instead).
SourceDir string `json:"source_dir,omitempty"`
// System is true when installed as a system service (macOS system
// LaunchDaemon), so a self-restart must target the system domain.
System bool `json:"system"`
}
InstallMeta is what `dejima service install` records for later self-update.
func LoadInstallMeta ¶
func LoadInstallMeta() (InstallMeta, error)
LoadInstallMeta reads the install context. A missing file yields a zero InstallMeta (no error) — an older install that predates this metadata.
func (InstallMeta) RestartArgs ¶
func (m InstallMeta) RestartArgs() []string
RestartArgs returns the `dejima` args that restart the service in the right domain (system installs need --system).
type Mode ¶
type Mode string
Mode is how this install updates itself.
func DetectMode ¶
func DetectMode() Mode
DetectMode infers the install mode from the build version. A real semver release was produced by `make release` (a packaged client build); anything else ("dev", a git-describe string) is a working checkout.
type ReleaseInfo ¶ added in v0.8.40
ReleaseInfo is the newest published release: its tag, its notes (the curated release body — the source of the in-app "what's in this update" blurb), and the URL of its release page ("view more").
func LatestReleaseInfo ¶ added in v0.8.40
func LatestReleaseInfo(ctx context.Context) (ReleaseInfo, error)
LatestReleaseInfo returns the newest published release's tag, notes, and page URL in one request. The notes are the release body we curate on every release; the TUI shows a blurb of it in the update confirm so an operator sees WHAT the update is before applying it (with the URL to read the rest).
type Runner ¶
Runner executes a command in dir (empty = current dir), streaming its output. Injected so apply logic is testable without mutating the host.
func ExecRunner ¶
ExecRunner runs commands for real, streaming combined output to out.