forgepb/cleanGoSum.go

182 lines
4.8 KiB
Go

package forgepb
import (
"errors"
"fmt"
"os"
"path/filepath"
"sort"
"strings"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
)
// This will recreate your go.sum and go.mod files
// checks to see if every 'master' git branch version
// matches the go.sum file
func (f *Forge) CleanGoDepsCheckOk(check *gitpb.Repo) error {
if check == nil {
log.Info("boo, check == nil")
return errors.New("*repo == nil")
}
// re-create go.sum and go.mod
if _, err := check.RedoGoMod(); err != nil {
return err
}
// if go.mod still does not exist. maybe this isn't a golang repo?
if !check.Exists("go.mod") {
return errors.New("go.mod can not be created in " + check.GoPath)
}
check.GoDeps = nil
// this assumes that go mod init and go mod tidy worked
// if they did, then the go.mod file might be the only
// file here. if so, this is called a 'primitive' golang package here
// this means, it's totally self contained and requires only the language go
// the name 'primitive' doesn't mean they are simple; these packages are usually awesome!
if ok, _ := check.IsPrimitive(); ok {
return nil
}
// parse the go.sum file
if ok, err := check.ParseGoSum(); !ok {
log.Info("CleanGoDepsCheckOk() error", err)
return err
}
// this probably shouldn't happen and this check should be removed or logged
if check.GoDepsLen() == 0 {
// this is a primitive go lang library (or an interesting binary?)
check.GoPrimitive = true
return nil
}
// simple trim
if err := f.TrimGoSum(check); err != nil {
return err
}
var err error = nil
log.Printf("current repo %s go dependancy count: %d", check.GetGoPath(), check.GoDepsLen())
deps := check.GoDeps.SortByGoPath()
for deps.Scan() {
depRepo := deps.Next()
found := f.Repos.FindByGoPath(depRepo.GetGoPath())
if found == nil {
if f.checkOverride(depRepo.GetGoPath()) {
// skip this gopath because it's probably broken forever
continue
}
log.Info("not found:", depRepo.GetGoPath())
err = errors.New("not found: " + depRepo.GetGoPath())
continue
}
// log.Info("found dep", depRepo.GetGoPath())
if depRepo.GetVersion() != found.GetMasterVersion() {
check := f.Repos.FindByGoPath(depRepo.GoPath)
var ends string
if check.CheckDirty() {
ends = "(dirty) "
}
if f.Config.IsReadOnly(check.GoPath) {
ends += "(ignoring read-only) "
log.Printf("%-48s ok error .%s. vs .%s. %s", depRepo.GetGoPath(),
depRepo.GetVersion(), found.GetMasterVersion(), ends)
} else {
if f.checkOverride(depRepo.GetGoPath()) {
ends += "(override) "
log.Printf("%-48s ok error .%s. vs .%s. %s", depRepo.GetGoPath(),
depRepo.GetVersion(), found.GetMasterVersion(), ends)
// skip this gopath because it's probably broken forever
continue
} else {
log.Printf("%-48s error %10s vs %10s %s", depRepo.GetGoPath(),
depRepo.GetVersion(), found.GetMasterVersion(), ends)
errs := fmt.Sprintf("%s error %s vs %s %s", depRepo.GetGoPath(),
depRepo.GetVersion(), found.GetMasterVersion(), ends)
err = errors.New(errs)
}
}
}
}
return err
}
func (f *Forge) TrimGoSum(check *gitpb.Repo) error {
var stuff map[string]string
stuff = make(map[string]string)
var modver map[string]string
modver = make(map[string]string)
var good map[string]bool
good = make(map[string]bool)
if check == nil {
log.Info("boo, check == nil")
return errors.New("*repo == nil")
}
filename := filepath.Join(filepath.Join(check.FullPath, "go.sum"))
data, err := os.ReadFile(filename)
if err != nil {
return err
}
for _, line := range strings.Split(string(data), "\n") {
parts := strings.Fields(line)
if len(parts) < 3 {
log.Info("BAD:", line)
continue
}
gopath := parts[0]
version := parts[1]
hash := parts[2]
if strings.HasSuffix(version, "/go.mod") {
if _, ok := stuff[gopath]; ok {
log.Info("MATCHED: gopath:", gopath, "version:", version)
modver[gopath] = version + " " + hash
good[gopath] = true
} else {
log.Info("GARBAGE: gopath:", gopath, "version:", version)
}
} else {
log.Info("GOOD : gopath:", gopath, "version:", version)
stuff[gopath] = version + " " + hash
}
}
keys := make([]string, 0, len(stuff))
for k := range stuff {
keys = append(keys, k)
}
// rewrite the go.sum file
newfilename := filepath.Join(filepath.Join(check.FullPath, "go.sum"))
newf, err := os.OpenFile(newfilename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return err
}
defer newf.Close()
sort.Strings(keys)
for _, gopath := range keys {
if good[gopath] {
fmt.Fprintf(newf, "%s %s\n", gopath, stuff[gopath])
fmt.Fprintf(newf, "%s %s\n", gopath, modver[gopath])
check := f.Repos.FindByGoPath(gopath)
if check == nil {
log.Info("gopath does not really exist:", gopath)
}
}
}
// fmt.Fprintln(newf, "test")
return nil
}