gitpb/goDep.parseGoSum.go

198 lines
4.8 KiB
Go

package gitpb
// does processing on the go.mod and go.sum files
import (
"bufio"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"go.wit.com/lib/gui/shell"
"go.wit.com/log"
)
// reads and parses the go.sum file
// does not change anything
func (repo *Repo) ParseGoSum() bool {
// empty out what was there before
repo.GoDeps = nil
// check of the repo is a primitive
// that means, there is not a go.sum file
// because the package is completely self contained!
if err := repo.setPrimitive(); err != nil {
// temporarily enabled this. this is really noisy
// log.Info("gitpb.ParseGoSum()", err)
return false
}
if repo.GetGoPrimitive() {
// log.Info("This repo is primitive!")
return true
}
tmp := filepath.Join(repo.FullPath, "go.sum")
gosum, err := os.Open(tmp)
defer gosum.Close()
if err != nil {
log.Info("gitpb.ParseGoSum() missing go.sum. Some error happened with go mod init & tidy", err)
return false
}
scanner := bufio.NewScanner(gosum)
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,
}
if repo.GoDeps == nil {
repo.GoDeps = new(GoDeps)
}
repo.GoDeps.AppendByGoPath(&new1)
} else {
log.Info("gitpb.ParseGoSum() go.sum parse error invalid:", line)
return false
}
}
if err := scanner.Err(); err != nil {
repo.GoDeps = nil
log.Info("gitpb.ParseGoSum()", err)
return false
}
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())
}