Documentation
¶
Overview ¶
Package modparser reads and edits go.mod files on golang.org/x/mod/modfile.
Parser is the seam to the go.mod grammar, with XParser as the adapter on the Go team's own parser. A parsed File reports the facts a tool manager needs (the tool directives and the versions that provide them) and makes the edits it needs (drop tools, rename the module), leaving everything else in the file as it was.
Index ¶
- func InferBinaryName(pkg string) string
- func ModulePath(dir string) string
- type File
- func (m *File) BinaryNameFor(toolName string) string
- func (m *File) DropTools(pkgs ...string) error
- func (m *File) Format() ([]byte, error)
- func (m *File) ModuleFor(pkg string) (Require, bool)
- func (m *File) Scan() []Spec
- func (m *File) SetModule(modPath string) error
- func (m *File) StripTools() error
- func (m *File) VersionFor(pkg string) string
- type Parser
- type Require
- type Spec
- type XParser
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func InferBinaryName ¶
InferBinaryName converts a package path (no @version) into the expected binary name: drop a trailing /vN element, then use <name> of /cmd/<name>, else the last element. A name that merely starts with v and digits, such as "v2ray", is kept.
Example ¶
package main
import (
"fmt"
"github.com/piusalfred/gotools/internal/modparser"
)
func main() {
for _, pkg := range []string{
"golang.org/x/tools/cmd/goimports",
"github.com/goreleaser/goreleaser/v2",
"github.com/x/v2ray",
} {
fmt.Println(modparser.InferBinaryName(pkg))
}
}
Output: goimports goreleaser v2ray
func ModulePath ¶
ModulePath returns the module path of the go.mod in dir, or "" when there is none or it declares no module.
Types ¶
type File ¶
type File struct {
Module string // module path, "" when there is no module directive
Go string // go directive version, "" when absent
Tools []string // tool directive package paths, in file order
Requires []Require
// contains filtered or unexported fields
}
File is a parsed go.mod. Edits change the parsed value, which then reports the new state; Format renders it. Get one from a Parser.
func (*File) BinaryNameFor ¶
BinaryNameFor resolves a tool alias to its binary name using the first tool directive in m, falling back to toolName.
func (*File) DropTools ¶
DropTools removes the tool directives for pkgs and leaves every other directive alone. A package that has no directive is ignored.
Example ¶
DropTools changes the parsed value and Format renders it; every other directive stays as it was.
package main
import (
"fmt"
"github.com/piusalfred/gotools/internal/modparser"
)
const goMod = `module example.com/tools
go 1.24
tool (
golang.org/x/tools/cmd/goimports
github.com/acme/lint/v2/cmd/lint
)
require (
golang.org/x/tools v0.30.0
github.com/acme/lint/v2 v2.1.0
)
`
func main() {
f, _ := modparser.XParser{}.Parse([]byte(goMod))
_ = f.DropTools("golang.org/x/tools/cmd/goimports")
fmt.Println(f.Tools)
out, _ := f.Format()
fmt.Print(string(out))
}
Output: [github.com/acme/lint/v2/cmd/lint] module example.com/tools go 1.24 tool github.com/acme/lint/v2/cmd/lint require ( golang.org/x/tools v0.30.0 github.com/acme/lint/v2 v2.1.0 )
func (*File) ModuleFor ¶
ModuleFor returns the require entry providing pkg, trying progressively shorter path prefixes (longest wins, as in Go).
func (*File) StripTools ¶
StripTools removes every tool directive.
func (*File) VersionFor ¶
VersionFor returns the required version providing pkg, or "".
type Parser ¶
type Parser interface {
// Parse parses go.mod contents.
Parse(src []byte) (*File, error)
// Read reads and parses the go.mod-format file at name. A missing file is
// an error that satisfies errors.Is(err, fs.ErrNotExist).
Read(name string) (*File, error)
// Validate reports every tool directive in f that is not an import path
// (including one go would read as a flag), joined into one error; nil
// means it is fine. The grammar is Parse's job: a bad go version or a
// malformed directive never gets this far.
Validate(f *File) error
}
Parser reads go.mod files. Its errors are Environment errors from package errors, with the underlying error reachable through errors.Is and errors.As.
Example ¶
Parse a go.mod, check its tool directives and list the tools it pins.
package main
import (
"fmt"
"github.com/piusalfred/gotools/internal/modparser"
)
const goMod = `module example.com/tools
go 1.24
tool (
golang.org/x/tools/cmd/goimports
github.com/acme/lint/v2/cmd/lint
)
require (
golang.org/x/tools v0.30.0
github.com/acme/lint/v2 v2.1.0
)
`
func main() {
var p modparser.Parser = modparser.XParser{}
f, err := p.Parse([]byte(goMod))
if err != nil {
fmt.Println(err)
return
}
fmt.Println("valid:", p.Validate(f) == nil)
for _, spec := range f.Scan() {
fmt.Println(spec)
}
}
Output: valid: true goimports golang.org/x/tools/cmd/goimports@v0.30.0 lint github.com/acme/lint/v2/cmd/lint@v2.1.0
type Spec ¶
type Spec struct {
Name string
Package string
Version string // "latest" when the go.mod carries no pin
}
Spec is a tool directive resolved to a binary name and pinned package.