Documentation
¶
Overview ¶
Package binarymgr provides a reusable lifecycle for managed CLI binaries distributed through a GitLab project's Generic Package Registry. Each consumer describes its binary with a Spec and gets download, checksum verification, atomic install, scheduled update checks, and run-time pass-through orchestration in return.
Index ¶
- Variables
- func ManagedBinaryPath(spec Spec) (string, error)
- type BinaryInfo
- type EnsureResult
- type Executor
- type Extractor
- type InstallStatus
- type Manager
- func (m *Manager) CheckForUpdate(ctx context.Context, currentVersion string, lastCheckTime time.Time, ...) (UpdateCheck, error)
- func (m *Manager) EnsureInstalled(ctx context.Context, installedVersion, installedPath, autoDownload string) (*EnsureResult, error)
- func (m *Manager) Update(ctx context.Context) (*BinaryInfo, error)
- type Platform
- type Runner
- type Spec
- type UpdateCheck
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupportedPlatform = errors.New("unsupported platform")
ErrUnsupportedPlatform is returned when the running OS or architecture is not supported by the Spec.
Functions ¶
func ManagedBinaryPath ¶
ManagedBinaryPath returns the absolute path where Spec's binary lives after installation. Used by callers that need to compare against a user-configured custom path.
Types ¶
type BinaryInfo ¶
BinaryInfo describes an installed (or located) managed binary.
type EnsureResult ¶
type EnsureResult struct {
Info *BinaryInfo
// Downloaded is true when this call actually downloaded and installed
// the binary (vs. returning an existing installation or a custom path).
Downloaded bool
// AutoDownloadPreference is set to "true" when the user opted into
// automatic future downloads during the prompt. Empty otherwise.
AutoDownloadPreference string
}
EnsureResult is what EnsureInstalled returns: the resolved binary plus metadata the runner needs to react to.
type Executor ¶
Executor runs the resolved binary with the given args. The binarymgr package leaves this to consumers because the right strategy is platform-specific (syscall.Exec on Unix, subprocess on Windows) and may also need to inject distribution-specific environment variables.
type Extractor ¶
Extractor pulls the executable out of a downloaded asset and writes it to destDir. It returns the path to the resulting binary file.
func TarGzExtractor ¶
TarGzExtractor returns an Extractor that opens a .tar.gz archive, locates the entry whose basename matches binaryName, and writes it to destDir as an executable file. Symlinks and hardlinks are skipped. Entries whose resolved path escapes destDir are rejected (zip-slip).
func ZipExtractor ¶ added in v1.101.0
ZipExtractor returns an Extractor that opens a .zip archive, locates the entry whose basename matches binaryName, and writes it to destDir as an executable file. Entries whose resolved path escapes destDir are rejected (zip-slip). Directories and non-regular entries are skipped.
type InstallStatus ¶ added in v1.118.0
InstallStatus describes the binary Run would exec without a download.
func InstalledBinary ¶ added in v1.118.0
func InstalledBinary(cfg config.Config, spec Spec) (InstallStatus, error)
InstalledBinary resolves the binary the way Run does, but never prompts, downloads, or logs. Config read errors are returned together with a best-effort status so the caller picks the fallback.
type Manager ¶
type Manager struct {
// contains filtered or unexported fields
}
Manager handles the lifecycle (install, update, validate) of a single managed binary described by Spec.
func NewManager ¶
NewManager constructs a Manager for spec. Network requests use an unauthenticated client because package downloads are public.
func (*Manager) CheckForUpdate ¶
func (m *Manager) CheckForUpdate(ctx context.Context, currentVersion string, lastCheckTime time.Time, forceCheck bool) (UpdateCheck, error)
CheckForUpdate reports whether a newer compatible version exists. If the latest upstream version exceeds Spec.MaxCompatibleMajor, HasUpdate is false and NewMajorVersion is set so callers can surface the gating to the user.
func (*Manager) EnsureInstalled ¶
func (m *Manager) EnsureInstalled(ctx context.Context, installedVersion, installedPath, autoDownload string) (*EnsureResult, error)
EnsureInstalled returns a usable binary path, prompting the user to download if necessary. installedPath/installedVersion come from saved config. If installedPath points outside the managed install directory it is treated as a user-provided custom binary and returned without download.
type Platform ¶
Platform is the resolved (OS, arch) pair for the running host. arch is already normalized to the upstream naming used by Spec.AssetName.
type Runner ¶
type Runner struct {
IO *iostreams.IOStreams
Cfg config.Config
Spec Spec
Manager *Manager
Executor Executor
// Update / Install / Yes mirror the glab-owned flags after the
// caller has parsed them out of the cobra args. Args holds the
// remaining pass-through args destined for the managed binary.
Update bool
Install bool
Yes bool
Args []string
// UpdateCommand is the glab subcommand chain shown to users in the
// "Run 'glab X --update'" hint (e.g. "duo cli", "orbit local").
// Defaults to Spec.ConfigPrefix if empty.
UpdateCommand string
}
Runner orchestrates the per-invocation lifecycle: ensure the binary is installed, prompt for run consent, save metadata, schedule a background update check, then hand off to Executor.
func (*Runner) HandleInstall ¶
HandleInstall installs (or refreshes) the managed binary without running it. If the user has configured a custom path, the path is reported and nothing is downloaded.
func (*Runner) HandleUpdate ¶
HandleUpdate forces an update check and applies any newer compatible version. If nothing is installed yet, it falls back to a fresh install.
func (*Runner) Run ¶
Run executes the default flow: ensure installed, prompt for consent (when needed), and exec the binary with Args.
func (*Runner) SaveBinaryInfo ¶
func (r *Runner) SaveBinaryInfo(info *BinaryInfo) error
SaveBinaryInfo writes path/version/checksum to config and persists.
func (*Runner) ShouldForceUpdateCheck ¶
ShouldForceUpdateCheck returns true when the spec's force-update env var is "true". Useful for tests and CI that want to bypass the 24h cache.
type Spec ¶
type Spec struct {
// DisplayName appears in user-facing prompts and log lines
// (e.g. "GitLab Duo CLI", "Orbit local CLI").
DisplayName string
// ProjectID is the GitLab project ID that hosts the generic package.
ProjectID string
// PackageName is the generic-package name (e.g. "duo-cli", "orbit-cli").
PackageName string
// ConfigPrefix is the config-key namespace. Keys are derived as
// <prefix>_binary_path, _binary_version, _binary_checksum,
// _last_update_check, _auto_run, _auto_download.
ConfigPrefix string
// EnvVarPrefix is the env-var namespace. Variables are derived as
// <prefix>_BINARY_PATH, _CHECK_UPDATE.
EnvVarPrefix string
// MaxCompatibleMajor caps automatic updates to this major version.
// 0 disables the cap (every newer version is considered compatible).
MaxCompatibleMajor int
// MinVersion forces a re-download when the installed version is below it; empty disables the floor.
MinVersion string
// SupportedOS lists the GOOS values the binary is published for.
SupportedOS []string
// NormalizeArch converts (GOOS, GOARCH) into the upstream arch name
// used in asset filenames (e.g. amd64 -> "x64" for duo, "x86_64"
// for orbit). Should return ErrUnsupportedPlatform-wrapped errors
// for unsupported combinations.
NormalizeArch func(goos, goarch string) (string, error)
// AssetName returns the upstream asset filename for a (os, arch) pair
// (e.g. "duo-darwin-arm64", "orbit-cli-darwin-aarch64.tar.gz").
AssetName func(os, arch string) string
// InstalledName returns the local filename of the installed binary
// (e.g. "duo", "duo.exe", "orbit"). The install directory is shared
// across managed binaries (<config-dir>/bin).
InstalledName func(os string) string
// Extract optionally transforms the downloaded asset into a binary on
// disk. nil means the downloaded file IS the binary. TarGzExtractor is
// the typical choice for tarball-distributed binaries.
Extract Extractor
}
Spec describes a single managed binary. Everything that varies between consumers (project, naming, supported platforms, optional tarball extraction) lives here; the Manager and Runner contain no consumer-specific strings.
type UpdateCheck ¶
type UpdateCheck struct {
HasUpdate bool
LatestVersion string
NewMajorVersion string // set when latest exceeds Spec.MaxCompatibleMajor
NewCheckTime time.Time
}
UpdateCheck is the result of CheckForUpdate. NewCheckTime is non-zero when the call actually contacted the registry; callers should persist it.