Documentation
¶
Overview ¶
Package cliinstall carries the fleet's compiled-in catalog of installable CLIs (cli-install#req:catalog-compiled-in): a stable id per CLI, its release identity in the github.com/strongo/cli-helpers/selfupdate Config shape, its Homebrew cask coordinates, and the host -> target relevance texts a fleet CLI shows when it lists or explains its siblings.
Identity lives here, once ¶
Every per-CLI identity constructor — repository, tag prefix, managers, supported platforms, asset and checksum naming, version-probe arguments — lives in this package as an Entry, never in selfupdate itself (cli-install#req:catalog-identity-single-source). A host builds its own self-update Config from its own Entry.Config, so its self-update and every other host's "install <that cli>" resolve releases identically. This couples a CLI's release naming to a cli-helpers release: a CLI that changes its GoReleaser archive or checksum naming must first update its catalog entry here.
What this package does not do ¶
cliinstall carries data and validates it against recorded snapshots (see the gen subpackage and TestCatalog*); it does not locate installed binaries, plan a destination, or install anything. Those are later pieces of the cli-install Feature, built on top of this catalog.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Entry ¶
type Entry struct {
// ID is the catalog id, equal to the binary name
// (cli-install#req:host-identity-from-catalog).
ID string
// Homepage is the CLI's canonical homepage URL.
Homepage string
// Description is a one-line description shown in a listing row.
Description string
// Details is a longer description of at most a few short paragraphs,
// shown before a confirmation prompt
// (cli-install#req:details-before-install).
Details string
// Repository is "owner/repo" on GitHub that publishes this CLI's
// releases — see selfupdate.Config.Repository.
Repository string
// TagPrefix selects this binary's releases within Repository when that
// repository publishes more than one product's releases — see
// selfupdate.Config.TagPrefix.
TagPrefix string
// Managers are the package managers that might own this binary's
// install, exactly as this CLI's own self-update declares them — see
// selfupdate.Config.Managers.
Managers []selfupdate.Manager
// SupportedPlatforms restricts install and self-replace to the
// GOOS/GOARCH pairs this CLI's release actually publishes — see
// selfupdate.Config.SupportedPlatforms.
SupportedPlatforms []selfupdate.Platform
// VersionProbeArgs are the arguments run against a newly installed copy
// to confirm its version. A zero value leaves selfupdate.Config's own
// default ({"--version"}) in effect.
VersionProbeArgs []string
// UndeterminedVersions lists the CurrentVersion values that mean "this
// build cannot say its own version". A zero value leaves
// selfupdate.Config's own default ({"dev"}) in effect.
UndeterminedVersions []string
// AssetName names this CLI's release archive for one version/platform
// combination. Nil leaves selfupdate.Config's GoReleaser-shaped default
// in effect, which every catalog entry's archive naming matches.
AssetName func(binary, version, goos, goarch string) string
// ChecksumsName names this CLI's release checksums file for one
// version. Nil leaves selfupdate.Config's GoReleaser-shaped default
// ("<binary>_<version>_checksums.txt") in effect; some CLIs publish a
// single flat "checksums.txt" instead and override this.
ChecksumsName func(binary, version string) string
// CaskToken is the argument to `brew install --cask`, tap-qualified
// (e.g. "sneat-dev/tap/wb"). Empty means this CLI publishes no
// Homebrew cask.
CaskToken string
// CaskOS lists the GOOS values ("darwin", "linux") CaskToken's cask
// supports. Empty when CaskToken is empty.
CaskOS []string
// LegacyVersionSignatures optionally lists bare `--version` output
// patterns that identify an old build of this CLI, for the
// status-probe-order fallback step
// (cli-install#req:status-probe-order). Empty when no such pattern is
// declared for this CLI.
LegacyVersionSignatures []string
}
Entry is one compiled-in catalog record: a fleet CLI's stable identity, its release identity in the Self-Update Library's Config shape, its Homebrew cask coordinates, and the descriptive text a host shows a user before installing it (cli-install#req:catalog-entry-identity).
func ByID ¶
ByID returns the catalog entry for id and whether it was found (cli-install#req:host-identity-from-catalog).
func Entries ¶
func Entries() []Entry
Entries returns every catalog entry, sorted by id, as a defensive copy — mutating the returned slice or its elements' slice/func fields never affects the compiled-in catalog.
func (Entry) Config ¶
func (e Entry) Config(currentVersion string) selfupdate.Config
Config returns e's release identity as a selfupdate.Config for a build currently reporting currentVersion (cli-install#req:catalog-identity- single-source). It reproduces e's fields exactly; a caller that needs something only its own self-update requires (an AfterUpdate hook, for instance, which is a cobracmd.CommandOptions field, not a Config one) adds it outside this method.
type Env ¶ added in v0.16.0
type Env struct {
// PathDirs returns the current PATH's directories, in order. It need
// not exclude relative entries itself — Probe filters those
// defensively — but DefaultEnv's implementation does anyway, since a
// relative entry is never meaningful to report as a directory that
// was searched.
PathDirs func() []string
// HostDir returns the running host CLI's own executable directory
// (cli-install#req:status-locate). Returning a non-nil error is
// treated as "no host directory to search", not a fatal Probe error.
HostDir func() (string, error)
// IsExecutable reports whether path names an executable regular file
// — "not merely a file of that name" (cli-install#req:status-locate).
IsExecutable func(path string) bool
// EvalSymlinks resolves path's symlinks for classification
// (cli-install#req:status-locate). May be left nil, in which case
// classification uses only the unresolved path.
EvalSymlinks func(path string) (string, error)
// Run executes path with args directly, without a shell, with empty
// stdin, "NO_COLOR=1" set, and returns the combined stdout+stderr —
// so a probed binary's error or usage text is still available for
// Status.Output when a step doesn't recognize the subcommand. Run
// MUST honor ctx's deadline by killing the process when it expires
// (cli-install#req:status-probe-bounded) and MUST NOT itself retry,
// write any file, or make a network request.
Run func(ctx context.Context, path string, args []string) ([]byte, error)
}
Env carries every side-effecting dependency Probe uses: PATH and process execution, filesystem access, and symlink resolution (cli-install#req:no-network-in-tests: "PATH and environment, executable probing... MUST be injectable"). A caller that wants Probe to see the real host passes DefaultEnv(); a test passes a fake, purpose-built Env and never touches a real installed binary or a real PATH.
Every field is required — DefaultEnv sets all of them, and Probe calls them unconditionally, so an Env built by hand must do the same or the missing field's nil func value panics on first use, the same as calling any other nil func.
func DefaultEnv ¶ added in v0.16.0
func DefaultEnv() Env
DefaultEnv returns an Env wired to the real host: the real "PATH" environment variable, the real running executable's directory, real filesystem and symlink checks, and real (network-free, no-shell) process execution. It is the Env a production `install`/`version`-probing command wires in; tests use a purpose-built Env instead.
type ProbeOptions ¶ added in v0.16.0
type ProbeOptions struct {
// Concurrency is how many targets are located and probed at once.
// Zero defaults to 4.
Concurrency int
// Budget is the per-target time budget covering every probe step.
// Zero defaults to 3 seconds.
Budget time.Duration
}
ProbeOptions tunes Probe's concurrency and per-target time budget. The zero value is production-correct per cli-install#req:status-probe- bounded (a 3 second per-target budget, at least four targets probed concurrently); tests override both fields to stay fast and deterministic without faking Env.Run's own timeout behavior.
type Relevance ¶
type Relevance struct {
// Target is the relevant CLI's catalog id.
Target string
// Text is the relevance text written for this exact host/target pair.
Text string
}
Relevance is one host -> target row of the catalog's relevance matrix (cli-install#req:relevance-matrix): why a user of the host would want the target.
type State ¶ added in v0.16.0
type State int
State is a located target's install state (cli-install#req:status-probe-order, cli-install#req:list-relevant).
const ( // NotInstalled means no executable named after the target's id (with // the platform suffix) was found on PATH, in the host directory, or in // dir. NotInstalled State = iota // Installed means a located copy's identity was confirmed by one of // the three status-probe-order steps. Installed // Unrecognized means a copy was located but no probe step confirmed // this target's identity — never trusted or reported as installed // (cli-install#req:unrecognized-copy-not-trusted). Unrecognized )
type Status ¶ added in v0.16.0
type Status struct {
// ID is the catalog id this Status describes.
ID string
// State is this target's install state.
State State
// Path is the primary reported copy: the first PATH match, or — when
// no copy is on PATH — the first copy found in the host directory or
// dir (cli-install#req:status-locate). Empty when State is
// NotInstalled.
Path string
// OnPath reports whether Path itself was found on an absolute PATH
// entry. False means Path was found only in the host directory or
// dir, in which case Warnings carries a not-on-PATH warning.
OnPath bool
// OtherPaths lists every other located copy of this target, in the
// order they were found (cli-install#req:status-locate: "additional
// copies... count in text, full paths in JSON").
OtherPaths []string
// Method classifies Path's install method, checking both Path itself
// and its symlink-resolved form against every manager declared
// anywhere in the compiled catalog, preferring managed
// (cli-install#req:status-locate). Meaningful only when State is
// Installed or Unrecognized.
Method selfupdate.InstallMethod
// Manager identifies the owning package manager when Method is
// selfupdate.Managed; nil otherwise.
Manager *selfupdate.Manager
// Version, Commit, Date and DateSource are read from whichever step
// VersionSource names. Commit and Date are "" when unknown; a raw
// "none" or "unknown" token from a text probe is normalized to ""
// (cli-install#req:status-probe-order). Meaningful only when State is
// Installed.
Version string
Commit string
Date string
DateSource string
// VersionSource names the step that produced Version/Commit/Date/
// DateSource.
VersionSource VersionSource
// Output is the trimmed combined output of the last probe step that
// produced any, kept for display when State is Unrecognized
// (cli-install#req:status-probe-order: "reported with its path and
// the output that was seen").
Output string
// Warnings are human-readable, non-fatal notes: a not-on-PATH warning
// when OnPath is false, or a timeout warning when this target's probe
// budget was exhausted.
Warnings []string
}
Status is one target's located and probed install state — the type task-4's planner and task-5's output writers consume. It is produced entirely offline and read-only by Probe (cli-install#req:list-offline- read-only).
func Probe ¶ added in v0.16.0
Probe locates and identifies every entry in targets — searching absolute PATH entries, the host executable's directory, and dir (empty when no --dir was given) — and returns one Status per target, in targets' own order (cli-install#req:status-locate, cli-install#req:status-probe-order, cli-install#req:status-probe-bounded). It makes no network requests and writes, moves or deletes nothing (cli-install#req:list-offline-read- only); every side-effecting operation goes through env, so tests need exec no real installed binary.
type VersionSource ¶ added in v0.16.0
type VersionSource int
VersionSource identifies which status-probe-order step produced a Status's Version/Commit/Date/DateSource fields. Meaningful only when State is Installed.
const ( // VersionSourceNone means no step produced version information — // State is not Installed. VersionSourceNone VersionSource = iota // VersionSourceJSON means step 1, `version --json`, succeeded. VersionSourceJSON // VersionSourceText means step 2, plain `version` text, succeeded. VersionSourceText // VersionSourceFlag means step 3, `--version` matching a declared // legacy signature, succeeded. VersionSourceFlag )
func (VersionSource) String ¶ added in v0.16.0
func (v VersionSource) String() string
String renders VersionSource as the stable token REQ: machine-readable- output's "version_source" JSON field carries.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Command gen records, under cliinstall/testdata/snapshots/, a snapshot of each catalog CLI's real published release asset list and (where one exists) its real Homebrew cask file.
|
Command gen records, under cliinstall/testdata/snapshots/, a snapshot of each catalog CLI's real published release asset list and (where one exists) its real Homebrew cask file. |