updatecheck

package
v1.4.14 Latest Latest
Warning

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

Go to latest
Published: Oct 12, 2026 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package updatecheck is the opt-in, once-per-24h "newer nself exists" hint.

Nothing here runs unless NSELF_UPDATE_CHECK=1 (VMI: nothing is sent by default). A background goroutine refreshes a small cache from ping's GET /version at most once per 24 h; the hint itself reads only the cache and never touches the network. Contract: cap:cli.version-nudge.

Index

Constants

View Source
const Budget = 250 * time.Millisecond

Budget is the whole-request limit of one refresh.

View Source
const EnvOptIn = "NSELF_UPDATE_CHECK"

EnvOptIn is the opt-in switch: the value "1" turns the feature on.

View Source
const Interval = 24 * time.Hour

Interval is the minimum time between refreshes and between hints.

View Source
const VersionURL = "https://ping.nself.org/version"

VersionURL is ping's release-channel endpoint (contract:ping.release-channel).

Variables

This section is empty.

Functions

func Allowed

func Allowed(g Guards) bool

Allowed reports whether the feature may run at all: opted in, not JSON mode, no CI marker, stderr is a terminal. Without the opt-in nothing else is read.

func DefaultPath

func DefaultPath() string

DefaultPath returns ~/.nself/cache/update-check.json, or "" when the home directory cannot be resolved (the feature is then off).

func Hint

func Hint(g Guards) (string, bool)

Hint returns the one-line hint when it is due: allowed, the cached latest is a valid release newer than Current, and no hint was printed within Interval. It reads only the cache and records HintedAt before returning the line; if that record cannot be saved no line is returned, so it never repeats.

func MaybeStartRefresh

func MaybeStartRefresh(g Guards) <-chan struct{}

MaybeStartRefresh starts the background refresh when the feature is allowed and the cache is older than Interval. It never blocks: the returned channel closes when the refresh finishes (nil when none started), and production callers ignore it, so the goroutine is simply abandoned at process exit. A failed refresh keeps the old Latest and records CheckedAt and LastError.

func NewClient

func NewClient() *http.Client

NewClient returns the refresh client: Budget timeout through the httptimeout funnel, compression off so no Accept-Encoding header is sent. The request then carries only Host and User-Agent.

func Refresh

func Refresh(ctx context.Context, client *http.Client, url string) (string, error)

Refresh asks url for the latest released CLI version and returns it normalised (no leading "v"). An empty, invalid or non-2xx answer is an error. The only request header besides Host is User-Agent: nself/<version>.

func Save

func Save(path string, c Cache) error

Save writes the cache atomically (temp file in the same directory, then rename) with mode 0600 inside a 0700 directory.

Types

type Cache

type Cache struct {
	CheckedAt time.Time `json:"checked_at"`
	Latest    string    `json:"latest"`
	LastError string    `json:"last_error,omitempty"`
	HintedAt  time.Time `json:"hinted_at"`

	AttemptedAt time.Time `json:"attempted_at"`
}

Cache is the on-disk state at ~/.nself/cache/update-check.json.

CheckedAt is the time of the last refresh attempt (success or failure), so a stale cache is visible to `nself doctor`. LastError is empty after a good refresh. HintedAt is the time the hint was last printed. AttemptedAt is the time a refresh was last started, written before the request goes out, so a refresh cut short by process exit still counts for the retry backoff.

func Load

func Load(path string) Cache

Load reads the cache. A missing, unreadable or corrupt file yields the zero Cache: the next Save replaces it.

type Guards

type Guards struct {
	JSON    bool
	TTY     func() bool
	Env     func(string) string
	Now     func() time.Time
	Path    string
	Current string
	URL     string
	Client  *http.Client
}

Guards carries everything the feature reads from the outside world, so tests inject a clock, a TTY answer, an environment and a server.

JSON is the recorded JSON mode of the invocation. TTY reports whether stderr is a terminal. Path is the cache file, Current the running version, URL the endpoint and Client the HTTP client (nil means NewClient).

Jump to

Keyboard shortcuts

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