Documentation
¶
Overview ¶
Package strategy is the tool-isolation strategy: which files hold a tool's go.mod and go.sum, and which strategies a tools directory already uses.
A Strategy says how tools are kept apart. A Layout pairs a strategy with a tools directory and answers where each tool's files live. Detect reads a directory on disk and reports which layouts it holds.
Index ¶
- func ValidateName(name string) error
- type Detection
- type Layout
- func (l Layout) ModFile(root, name string) (string, error)
- func (l Layout) ModFileRel(name string) (string, error)
- func (l Layout) ModulePath(prefix, name string) string
- func (l Layout) SumFile(root, name string) (string, error)
- func (l Layout) SumFileRel(name string) (string, error)
- func (l Layout) ToolsDir(root string) string
- type Strategy
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ValidateName ¶
ValidateName rejects tool names that would escape the tools directory or break file handling: empty, "." and "..", a leading "-", a path separator, whitespace and control characters.
Types ¶
type Detection ¶
type Detection struct {
// Strategy is the dominant layout ("" when the directory is absent or
// holds no recognizable layout). Priority: unified, module, split.
Strategy Strategy
// Found lists every layout present, in priority order.
Found []Strategy
}
Detection is what Detect found in a tools directory.
func Detect ¶
Detect inspects dir, an on-disk path, and reports which layouts it holds. Dot-entries are ignored and symlinks are followed: detection is read-only.
Example ¶
Detect reports every layout a directory holds; more than one is a hybrid directory with a warning to show.
package main
import (
"fmt"
"os"
"path/filepath"
"github.com/piusalfred/gotools/internal/strategy"
)
func main() {
dir, _ := os.MkdirTemp("", "strategy-example")
defer os.RemoveAll(dir)
_ = os.WriteFile(filepath.Join(dir, "gofumpt.mod"), []byte("module x\n"), 0o600)
_ = os.MkdirAll(filepath.Join(dir, "gci"), 0o755)
_ = os.WriteFile(filepath.Join(dir, "gci", "go.mod"), []byte("module y\n"), 0o600)
d := strategy.Detect(dir)
fmt.Println(d.Strategy, d.Found, d.Hybrid())
fmt.Println(d.Warning("tools", "gotools"))
}
Output: module [module split] true ⚠️ Hybrid tools directory detected in tools/: - module (subdirectories with go.mod) - split (flat .mod files) Run 'gotools migrate <strategy>' to clean up.
type Layout ¶
type Layout struct {
Strategy Strategy
Dir string // the tools directory, relative to the project root
}
Layout is a strategy applied to a tools directory.
Example ¶
A Layout answers where a tool's files live under each strategy.
package main
import (
"fmt"
"github.com/piusalfred/gotools/internal/strategy"
)
func main() {
for _, s := range []strategy.Strategy{strategy.Unified, strategy.Split, strategy.Module} {
mod, _ := strategy.Layout{Strategy: s, Dir: "./tools/"}.ModFileRel("gofumpt")
fmt.Printf("%-8s %s\n", s, mod)
}
// A name that would escape the tools directory is refused.
_, err := strategy.Layout{Strategy: strategy.Split, Dir: "tools"}.ModFileRel("../x")
fmt.Println(err)
}
Output: unified tools/go.mod split tools/gofumpt.mod module tools/gofumpt/go.mod invalid tool name (must not contain a path separator): ../x
func (Layout) ModFileRel ¶
ModFileRel is the modfile holding tool name, relative to the project root and slash-separated:
unified <dir>/go.mod split <dir>/<name>.mod module <dir>/<name>/go.mod
A name that is joined into the path is validated.
func (Layout) ModulePath ¶
ModulePath is the module path for a tool's own go.mod (name != "") or for the tools directory itself (name == ""), under prefix. The directory is cleaned, so "./tools" and "tools/" give the same path.
func (Layout) SumFileRel ¶
SumFileRel is the checksum file matching ModFileRel.