Help us shape the future of Go! Take the 2026 Go Developer Survey

tools

package
v0.16.0-rc2 Latest Latest
Warning

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

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 23 Imported by: 0

Documentation

Overview

Package tools manages the host binaries the obol CLI shells out to (kubectl, helm, k3d, helmfile, k9s) plus the helm-diff plugin.

It provides three things:

  • an embedded, checksum-pinned manifest (manifest.yaml) of the versions obol expects, kept in lockstep with obolup.sh;
  • a resolver (Path / Resolve) that picks the binary to run in the order OBOL_<TOOL> env override → obol-managed bin dir → compatible $PATH copy;
  • an installer that downloads, verifies sha256 (fail closed), extracts and atomically installs managed copies into the obol bin dir.

This is what lets an `obol` installed by a package manager (Homebrew cask, deb/rpm) bootstrap its own toolchain without obolup.sh.

Index

Constants

View Source
const (
	StateOK       = "ok"
	StateOutdated = "outdated"
	StateNewer    = "newer"
	StateMissing  = "missing"
	StateUnknown  = "unknown" // present but version could not be read
)

Tool states reported by Status.

View Source
const (
	CompatSkew1 = "skew1" // same major, minor within ±1 of the pin
	CompatMinor = "minor" // same major, minor >= the pin's minor
	CompatAny   = "any"   // any version
)

Compat policies for accepting a $PATH binary instead of a managed copy.

View Source
const (
	KindBinary     = "binary"
	KindHelmPlugin = "helm-plugin"
)

Tool kinds.

View Source
const (
	FormatRaw   = "raw"
	FormatTarGz = "tar.gz"
	FormatZip   = "zip"
)

Archive formats.

View Source
const MissingHint = "run 'obol upgrade' to install missing tools"

MissingHint is the user-facing remedy for a missing tool.

Variables

This section is empty.

Functions

func CompareVersions

func CompareVersions(a, b string) int

CompareVersions returns -1, 0 or 1. Unparseable versions sort lowest.

func CompatRange

func CompatRange(policy, want string) string

CompatRange describes the versions policy accepts for pin want, for user-facing notes (e.g. "v4.x >= 4.3" when a $PATH helm 3 is skipped). Returns "" for CompatAny or an unparseable pin.

func Compatible

func Compatible(policy, want, have string) bool

Compatible reports whether version `have` satisfies policy for pin `want`.

skew1: same major, |minor(have) - minor(want)| <= 1   (kubectl skew policy)
minor: same major, minor(have) >= minor(want)          (helm 4.x, k3d 5.x, helmfile 1.x)
any:   always

func EnsureUI

func EnsureUI(ctx context.Context, u *ui.UI, binDir string, opts EnsureOptions) error

EnsureUI runs Ensure and prints progress. Used by `obol stack init/up` (missing required tools only) and `obol upgrade` (all tools, Upgrade).

func EnvVar

func EnvVar(name string) string

EnvVar is the override variable for a binary tool, e.g. OBOL_KUBECTL.

func MissingError

func MissingError(name string) error

MissingError formats the standard "tool not found" error.

func ParseVersion

func ParseVersion(pattern, out string) (string, error)

ParseVersion extracts the first x.y.z from out using pattern (whose first capture group is the version) or a generic semver pattern.

func Path

func Path(binDir, name string) string

Path resolves a binary tool and returns the path to exec. It never fails: when nothing usable exists it returns <binDir>/<name>, so callers keep their existing "not found"/exec error paths. Use Resolve for details.

func ProbeVersion

func ProbeVersion(t Tool, path string) (string, error)

ProbeVersion runs the tool's version command and extracts x.y.z. Results are cached per (path, size, mtime) for the life of the process.

Types

type Asset

type Asset struct {
	URL    string `yaml:"url"`
	SHA256 string `yaml:"sha256"`
	Member string `yaml:"member,omitempty"`
}

Asset is one downloadable artifact for a single os/arch.

type EnsureOptions

type EnsureOptions struct {
	// Names limits the tools considered (default: all manifest tools).
	Names []string
	// Upgrade also replaces outdated obol-managed copies. Without it only
	// missing tools are installed. Tools resolved from $PATH or an OBOL_<TOOL>
	// override are never modified, and newer managed copies are never
	// downgraded.
	Upgrade bool
	// OnInstall is called before each download, OnDone after each attempt.
	OnInstall func(s Status)
	OnDone    func(r Result)
}

EnsureOptions controls Ensure.

type Installer

type Installer struct {
	BinDir   string
	Manifest *Manifest
	Client   *http.Client
	GOOS     string
	GOARCH   string
	// PluginsDir overrides `helm env HELM_PLUGINS` discovery (tests).
	PluginsDir string
}

Installer downloads, verifies and installs manifest tools into BinDir.

func NewInstaller

func NewInstaller(binDir string) *Installer

NewInstaller returns an installer for the host platform using the embedded manifest.

func (*Installer) Ensure

func (in *Installer) Ensure(ctx context.Context, opts EnsureOptions) ([]Result, error)

Ensure installs missing (and with Upgrade, outdated managed) tools. It keeps going after a failure and returns the joined errors.

func (*Installer) HelmPluginsDir

func (in *Installer) HelmPluginsDir() (string, error)

HelmPluginsDir returns the plugin directory helm uses (`helm env HELM_PLUGINS`), honouring HELM_PLUGINS / HELM_DATA_HOME like helm does. This is the same directory obolup.sh's `helm plugin install` writes to.

func (*Installer) Install

func (in *Installer) Install(ctx context.Context, name string) error

Install downloads and installs the pinned version of name, replacing any managed copy. It never touches binaries outside BinDir (helm plugins go to helm's plugin dir).

func (*Installer) Status

func (in *Installer) Status() []Status

Status reports every manifest tool.

type Manifest

type Manifest struct {
	Tools []Tool `yaml:"tools"`
}

Manifest is the parsed manifest.yaml.

func Default

func Default() *Manifest

Default returns the embedded manifest. It panics only if the embedded file is malformed, which TestEmbeddedManifestValid guards against.

func ParseManifest

func ParseManifest(data []byte) (*Manifest, error)

ParseManifest parses and validates manifest YAML.

func (*Manifest) Get

func (m *Manifest) Get(name string) (Tool, bool)

Get returns the named tool.

func (*Manifest) Names

func (m *Manifest) Names() []string

Names returns all tool names in manifest order.

func (*Manifest) RequiredNames

func (m *Manifest) RequiredNames(skip ...string) []string

RequiredNames returns the tools `obol stack init/up` auto-installs. skip lets callers drop backend-specific tools (k3d on the k3s backend).

type PluginInfo

type PluginInfo struct {
	Dir     string
	Name    string
	Version string
}

PluginInfo describes an installed helm plugin.

func FindPlugins

func FindPlugins(dir, name string) []PluginInfo

FindPlugins lists plugins in dir whose plugin.yaml name equals name.

type Resolution

type Resolution struct {
	Name   string
	Path   string // binary to exec; for SourceMissing, the managed path it would be installed to
	Source Source
	// Version is filled when the resolver had to probe it ($PATH candidates).
	Version string
	// Rejected/RejectedVersion describe a $PATH binary skipped as incompatible.
	Rejected        string
	RejectedVersion string
}

Resolution is the outcome of resolving one binary tool.

func Resolve

func Resolve(binDir, name string) Resolution

Resolve resolves a binary tool in order:

  1. OBOL_<TOOL> env override (used as-is, no version check);
  2. <binDir>/<name> if it is an executable file (obol-managed);
  3. the first <name> on $PATH whose version is compatible with the manifest pin (see the compat policies in manifest.yaml).

func (Resolution) Found

func (r Resolution) Found() bool

Found reports whether a usable binary was resolved.

type Result

type Result struct {
	Name      string
	From      string // previous managed version, "" if newly installed
	To        string
	Installed bool
	Err       error
}

Result records what Ensure did for one tool.

type Source

type Source string

Source says where a resolved tool came from.

const (
	SourceEnv     Source = "env"     // OBOL_<TOOL> override
	SourceManaged Source = "managed" // obol bin dir (installed by obol or obolup.sh)
	SourcePath    Source = "path"    // compatible binary on $PATH
	SourceMissing Source = "missing" // nothing usable found
)

type Status

type Status struct {
	Name      string `json:"name"`
	Wanted    string `json:"wanted"`
	Installed string `json:"installed,omitempty"`
	Path      string `json:"path,omitempty"`
	Source    Source `json:"source"`
	State     string `json:"state"`
	Required  bool   `json:"required"`
	Note      string `json:"note,omitempty"`
}

Status is the check-only view of one tool, for `obol update`.

func (Status) NeedsAction

func (s Status) NeedsAction() bool

NeedsAction reports whether `obol upgrade` would change this tool. Only obol-managed copies (or missing tools) are ever touched.

type Tool

type Tool struct {
	Name         string           `yaml:"name"`
	Version      string           `yaml:"version"`
	ObolupVar    string           `yaml:"obolupVar"`
	Required     bool             `yaml:"required"`
	Kind         string           `yaml:"kind,omitempty"`
	PluginName   string           `yaml:"pluginName,omitempty"`
	Compat       string           `yaml:"compat,omitempty"`
	VersionArgs  []string         `yaml:"versionArgs,omitempty"`
	VersionRegex string           `yaml:"versionRegex,omitempty"`
	Format       string           `yaml:"format"`
	Assets       map[string]Asset `yaml:"assets"`
}

Tool is one manifest entry.

func (Tool) AssetFor

func (t Tool) AssetFor(goos, goarch string) (Asset, error)

AssetFor returns the asset for goos/goarch with {version} expanded.

func (Tool) IsPlugin

func (t Tool) IsPlugin() bool

IsPlugin reports whether the tool is a helm plugin rather than a binary.

Jump to

Keyboard shortcuts

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