diff --git a/go.mod b/go.mod index fcb5ec8..2e84c94 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.22.0 require ( github.com/stretchr/testify v1.10.0 golang.org/x/mod v0.22.0 + golang.org/x/tools v0.27.0 ) require ( diff --git a/go.sum b/go.sum index 0f28562..905e8e7 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOf github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4= golang.org/x/mod v0.22.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/module.go b/module.go index 4cb3653..715edc9 100644 --- a/module.go +++ b/module.go @@ -7,8 +7,10 @@ import ( "fmt" "os" "os/exec" + "path/filepath" "golang.org/x/mod/modfile" + "golang.org/x/tools/go/analysis" ) type modInfo struct { @@ -20,26 +22,49 @@ type modInfo struct { } // GetModuleFile gets module file. +// It's better to use [GetGoModFile] instead of this function. func GetModuleFile() (*modfile.File, error) { + goMod, err := getModulePath() + if err != nil { + return nil, err + } + + if goMod == "" { + return nil, errors.New("working directory is not part of a module") + } + + return parseGoMod(goMod) +} + +// GetGoModFile gets module file. +func GetGoModFile(pass *analysis.Pass) (*modfile.File, error) { + if pass.Module != nil && pass.Module.Path != "" { + return parseGoMod(pass.Module.Path) + } + + return GetModuleFile() +} + +func getModulePath() (string, error) { // https://github.com/golang/go/issues/44753#issuecomment-790089020 cmd := exec.Command("go", "list", "-m", "-json") raw, err := cmd.Output() if err != nil { - return nil, fmt.Errorf("command go list: %w: %s", err, string(raw)) + return "", fmt.Errorf("command go list: %w: %s", err, string(raw)) } var v modInfo err = json.NewDecoder(bytes.NewBuffer(raw)).Decode(&v) if err != nil { - return nil, fmt.Errorf("unmarshaling error: %w: %s", err, string(raw)) + return "", fmt.Errorf("unmarshaling error: %w: %s", err, string(raw)) } - if v.GoMod == "" { - return nil, errors.New("working directory is not part of a module") - } + return v.GoMod, nil +} - raw, err = os.ReadFile(v.GoMod) +func parseGoMod(goMod string) (*modfile.File, error) { + raw, err := os.ReadFile(filepath.Clean(goMod)) if err != nil { return nil, fmt.Errorf("reading go.mod file: %w", err) }