From 6f66340d824b396d45a1cf955b8fa3dd9f4607ac Mon Sep 17 00:00:00 2001 From: Jeff Carr Date: Fri, 7 Feb 2025 09:49:08 -0600 Subject: [PATCH] general parsing routines for go-mod-clean --- goDep.parseGoSum.go | 126 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/goDep.parseGoSum.go b/goDep.parseGoSum.go index 14bc319..0c647d2 100644 --- a/goDep.parseGoSum.go +++ b/goDep.parseGoSum.go @@ -4,10 +4,13 @@ package gitpb import ( "bufio" + "errors" + "fmt" "os" "path/filepath" "strings" + "go.wit.com/lib/gui/shell" "go.wit.com/log" ) @@ -69,3 +72,126 @@ func (repo *Repo) ParseGoSum() bool { } return true } + +// attempt to parse go.* files in a directory +func GoSumParseDir(moddir string) (*GoDeps, error) { + isprim, err := computePrimitiveNew(moddir) + if err == nil { + // "go mod init" failed + return nil, err + } + if isprim { + // might be a GO primitive. no go.sum file + return nil, nil + } + // go.sum exists. parse the go.sum file + return parseGoSumNew(moddir) +} + +// Detect a 'Primitive' package. Sets the isPrimitive flag +// will return true if the repo is truly not dependent on _anything_ else +// like spew or lib/widget +// it assumes 'go mod init' and 'go mod tidy' ran without error +func computePrimitiveNew(moddir string) (bool, error) { + // go mod init & go mod tidy ran without errors + log.Log(INFO, "isPrimitiveGoMod()", moddir) + gomod, err := os.Open(filepath.Join(moddir, "go.mod")) + if err != nil { + log.Log(INFO, "missing go.mod", moddir) + return false, err + } + defer gomod.Close() + + if shell.Exists(filepath.Join(moddir, "go.sum")) { + return false, nil + } + + scanner := bufio.NewScanner(gomod) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + + parts := strings.Fields(line) + log.Log(INFO, " gomod:", parts) + if len(parts) >= 1 { + log.Log(INFO, " gomod: part[0] =", parts[0]) + if parts[0] == "require" { + log.Log(INFO, " should return false here") + return false, errors.New("go.mod file is not primitive") + } + /* + if parts[0] == "go" { + if parts[1] != "1.21" { + log.Log(WARN, "go not set to 1.21 for", repo.GetGoPath()) + // return false, errors.New("go not set to 1.21 for " + repo.GetGoPath()) + } + } + */ + } + } + return true, nil +} + +func parseGoSumNew(moddir string) (*GoDeps, error) { + godeps := new(GoDeps) + + tmp, err := os.Open(filepath.Join(moddir, "go.sum")) + defer tmp.Close() + if err != nil { + log.Info("gitpb.ParseGoSum() missing go.sum. Some error happened with go mod init & tidy", err) + return nil, err + } + + scanner := bufio.NewScanner(tmp) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) + + parts := strings.Split(line, " ") + if len(parts) == 3 { + godep := strings.TrimSpace(parts[0]) + version := strings.TrimSpace(parts[1]) + if strings.HasSuffix(version, "/go.mod") { + version = strings.TrimSuffix(version, "/go.mod") + } + new1 := GoDep{ + GoPath: godep, + Version: version, + } + godeps.AppendByGoPath(&new1) + } else { + return nil, fmt.Errorf("gitpb.ParseGoSum() go.sum parse error invalid: %s", line) + } + } + + if err := scanner.Err(); err != nil { + godeps = nil + return nil, err + } + return godeps, nil +} + +func (repo *Repo) GoSumFromPkgDir() (*GoDeps, error) { + homedir, err := os.UserHomeDir() + if err != nil { + return nil, err + } + rver := repo.GetLastTag() + if rver == "" { + return nil, errors.New("could not get master version") + } + goget := repo.GetGoPath() + "@" + rver + moddir := filepath.Join(homedir, "go/pkg/mod", repo.GetGoPath()+"@"+rver) + + if !shell.IsDir(moddir) { + cmd := []string{"go", "get", goget} + repo.RunVerboseOnError(cmd) + } + + if !shell.IsDir(moddir) { + return nil, errors.New("missing go/pkg/mod. Run: go get " + goget) + } + return GoSumParseDir(moddir) +} + +func (repo *Repo) GoSumFromRepo() (*GoDeps, error) { + return GoSumParseDir(repo.GetFullPath()) +}