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 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 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-local").
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
// 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-local-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.