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 ¶
- func CheckPackageSpec(spec string) error
- func FailureCode(output string) ierrors.Code
- type AddOptions
- type Advisor
- type Config
- type GoManager
- func (m *GoManager) Add(ctx context.Context, o AddOptions) (manifest.Tool, error)
- func (m *GoManager) Remove(ctx context.Context, name string) (RemoveResult, error)
- func (m *GoManager) Rename(ctx context.Context, oldName, newName string, o RenameOptions) error
- func (m *GoManager) Restore(ctx context.Context, work []manifest.Tool, o RestoreOptions) error
- func (m *GoManager) Upgrade(ctx context.Context, from manifest.Tool) (manifest.Tool, error)
- type Manager
- type Recorder
- type RemoveResult
- type RenameOptions
- type RestoreOptions
- type Store
- type VersionResolver
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CheckPackageSpec ¶
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 ¶
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 ¶
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 ¶
New returns the GoManager for cfg. Build it per command: the runners and the streams belong to the command.
func (*GoManager) Add ¶
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 ¶
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) Restore ¶
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.
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 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.