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

tools

package
v0.7.0 Latest Latest
Warning

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

Go to latest
Published: Oct 27, 2026 License: MIT Imports: 19 Imported by: 0

Documentation

Overview

Package tools changes which tools a project manages.

A Manager owns each change as one transaction over the tools directory and the manifest, for every strategy: a failure puts the files back and leaves the manifest as it was. GoManager is the Manager that drives the go command. Everything it needs from outside, the go runner, the manifest store, the go.mod parser, the fingerprint and the output streams, is injected through Config, so tests drive it with fakes and no go.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckPackageSpec

func CheckPackageSpec(spec string) error

CheckPackageSpec rejects a `pkg[@version]` that is not an import path, or that `go get` would read as one of its own flags. It guards values from the command line and from the committed manifest alike.

Example

A package from the command line or the manifest is checked before it can reach go.

package main

import (
	"fmt"

	"github.com/piusalfred/gotools/internal/tools"
)

func main() {
	fmt.Println(tools.CheckPackageSpec("mvdan.cc/gofumpt@v0.9.2"))
	fmt.Println(tools.CheckPackageSpec("-modfile=evil"))

}
Output:
<nil>
Invalid package "-modfile=evil": must not start with '-'

func FailureCode

func FailureCode(output string) ierrors.Code

FailureCode classifies go's output: network problems are Network errors so CI can retry with backoff, bad package paths or versions are Usage errors, anything else is Generic.

Example

What go printed decides the exit code, so CI can retry network failures.

package main

import (
	"fmt"

	ierrors "github.com/piusalfred/gotools/internal/errors"
	"github.com/piusalfred/gotools/internal/tools"
)

func main() {
	fmt.Println(tools.FailureCode("dial tcp: lookup proxy.golang.org: no such host") == ierrors.Network)
	fmt.Println(tools.FailureCode("invalid module version syntax") == ierrors.Usage)

}
Output:
true
true

Types

type AddOptions

type AddOptions struct {
	Name string
	Pkg  string // package path, optionally @version
	// NoFlush leaves the manifest alone and only returns the tool, for
	// callers (parallel sync, migrate) that merge and write it once at the end.
	NoFlush bool
	// Quiet drops the "Installing" and "Installed" lines and the @latest
	// pinning hint, for callers (upgrade) that report in their own words.
	// Warnings on the error stream are never suppressed.
	Quiet bool
	// RejectTwin refuses a tool that is already managed under another name
	// at the same version (any version in the unified strategy). Only an
	// explicit install asks for it: sync, migrate and init must still be able
	// to restore a manifest that already has such entries.
	RejectTwin bool
}

AddOptions describes one tool to add.

type Advisor

type Advisor interface {
	Warnings(ctx context.Context, dir, modulePath string) []string
}

Advisor reports Go settings that weaken module verification for a module. Its warnings are advisory: they never fail an install.

type Config

type Config struct {
	Root     string          // the project root
	Layout   strategy.Layout // the strategy and tools directory
	Prefix   string          // the module path prefix for tool modules
	Store    Store
	Versions VersionResolver
	ModFiles modparser.Parser // modparser.XParser when nil
	Go       gocmd.Runner
	Network  gocmd.Runner // for network-bound calls; Go when nil
	Recorder Recorder     // no fingerprint is recorded when nil
	Advisor  Advisor      // no advice when nil
	Out, Err io.Writer    // discarded when nil
	Program  string       // the command name used in hints
}

Config is what a GoManager works on and with.

type GoManager

type GoManager struct {
	// contains filtered or unexported fields
}

GoManager is the Manager that drives the go command: modfiles are edited through the parser and `go get -tool`, and what it prints goes to Config.Out and Config.Err.

func New

func New(cfg Config) *GoManager

New returns the GoManager for cfg. Build it per command: the runners and the streams belong to the command.

func (*GoManager) Add

func (m *GoManager) Add(ctx context.Context, o AddOptions) (tool manifest.Tool, err error)

Add adds one tool to the tools directory and, unless NoFlush, to the manifest. Every failure restores the modfile and sum exactly as they were and removes the module directory only if it ended up empty, and a tool that fails to build leaves nothing behind that the manifest does not know about.

func (*GoManager) Remove

func (m *GoManager) Remove(ctx context.Context, name string) (RemoveResult, error)

Remove deletes the tool's files for the project's strategy and drops it from the manifest, writing the manifest before it returns. A name that is neither on disk nor in the manifest is not an error here: the result says so and the caller decides. The manifest is written per tool, so a failure on tool N leaves tools 1..N-1 removed from both the disk and the manifest.

func (*GoManager) Rename

func (m *GoManager) Rename(ctx context.Context, oldName, newName string, o RenameOptions) error

Rename validates and performs one rename. The caller holds the lock.

func (*GoManager) Restore

func (m *GoManager) Restore(ctx context.Context, work []manifest.Tool, o RestoreOptions) error

Restore reinstalls work serially, or concurrently for split and module, where each tool has its own modfile. Unified shares one go.mod, so it stays serial.

A parallel run is all-or-nothing for the manifest: it is merged and written once, only if every job succeeded. Each job rolls back its own files on failure; jobs that finished before another failed keep their modfiles, and the next sync sees them as drift and reinstalls.

func (*GoManager) Upgrade

func (m *GoManager) Upgrade(ctx context.Context, from manifest.Tool) (manifest.Tool, error)

Upgrade reinstalls from at @latest and records the result, quietly: the caller reports in its own words. The returned tool carries the resolved version, which equals from.Version when it was already the latest.

type Manager

type Manager interface {
	// Add installs one tool and records it in the manifest (unless
	// o.NoFlush). It is all-or-nothing.
	Add(ctx context.Context, o AddOptions) (manifest.Tool, error)
	// Remove deletes one tool's files and manifest entry.
	Remove(ctx context.Context, name string) (RemoveResult, error)
	// Rename renames a tool's files and manifest entry, undoing every step if
	// a later one fails.
	Rename(ctx context.Context, oldName, newName string, o RenameOptions) error
	// Upgrade moves one tool to @latest and records it.
	Upgrade(ctx context.Context, from manifest.Tool) (manifest.Tool, error)
	// Restore reinstalls tools at the versions the manifest pins,
	// concurrently where the strategy allows.
	Restore(ctx context.Context, tools []manifest.Tool, o RestoreOptions) error
}

Manager changes which tools a project manages. The caller holds the project lock and has refused offline mode where an operation needs the network.

type Recorder

type Recorder interface {
	Record(ctx context.Context) error
}

Recorder records the sync fingerprint once disk and manifest agree.

type RemoveResult

type RemoveResult struct {
	OnDisk     bool // files on disk served the tool, and were removed
	InManifest bool // the manifest listed the tool, and no longer does
}

RemoveResult says what Remove found for a name.

type RenameOptions

type RenameOptions struct {
	// DryRun runs every precondition check and reports the rename without
	// touching disk.
	DryRun bool
}

RenameOptions configures Rename.

type RestoreOptions

type RestoreOptions struct {
	// Jobs is how many tools install at once (split and module only). Values
	// below 2 install one after the other.
	Jobs int
}

RestoreOptions configures Restore.

type Store

type Store interface {
	// Manifest is the in-memory manifest. Operations change it and call Flush.
	Manifest() *manifest.Manifest
	// Flush writes the manifest to disk.
	Flush() error
}

Store is the project's manifest and the way to persist it.

type VersionResolver

type VersionResolver interface {
	Resolve(ctx context.Context) (string, error)
}

VersionResolver resolves the Go version a new tool's modfile declares.

Jump to

Keyboard shortcuts

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