go-clone/clone.go

147 lines
3.6 KiB
Go

package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
)
func clone(gopath string) (*gitpb.Repo, error) {
// if the user defined a repo, attempt to download it now
if gopath == "" {
// nothing to clone
// user probably wants to --recursive on current working dir
return nil, errors.New("gopath was blank")
}
os.Setenv("REPO_AUTO_CLONE", "true")
// pb, _ := forge.NewGoPath(gopath)
check := forge.FindAnyPath(filepath.Join(forge.GetGoSrc(), gopath))
if check != nil {
if check.IsValidDir() {
// repo already exists and is valid
return check, nil
}
}
pb, err := forge.GoClone(gopath)
if err != nil {
log.Info("clone() could not download err:", err)
return nil, err
}
if err := makeValidGoSum(pb); err != nil {
return nil, err
}
log.Info("go-clone clone() onward and upward")
return pb, nil
}
// really only does go.sum things
// so not 'really' recursive
// but that is because go.sum is supposed
// to have everything required in it
func recursiveClone(check *gitpb.Repo) error {
var good int
var bad int
badmap := make(map[string]error)
if check == nil {
return errors.New("repo was nil")
}
log.Info("STARTING RECURSIVE CLONE", check.GetGoPath())
log.Info("STARTING RECURSIVE CLONE", check.GetGoPath())
// if just cloned, parse the go.sum file for deps
if check.ParseGoSum() {
} else {
makeValidGoSum(check)
}
if check.GetGoPrimitive() {
// go primitive repos are "pure"
log.Info("repo is primitive", check.GetGoPath())
return nil
}
if check.GoDeps == nil {
log.Info("repo godeps == nil", check.GetGoPath())
return errors.New("go.sum is missing?")
}
// probably this should never be 0 because GoPrimitive should have been true otherwise
if check.GoDeps.Len() == 0 {
log.Info("repo len(godeps) == 0", check.GetGoPath())
return errors.New("go.sum never parsed?")
}
log.Info("deps for", check.GetGoPath(), "len()", check.GoDeps.Len())
deps := check.GoDeps.SortByGoPath()
for deps.Scan() {
depRepo := deps.Next()
log.Info("download:", depRepo.GetGoPath())
_, err := clone(depRepo.GetGoPath())
if err != nil {
log.Info("recursiveClone() could not download", depRepo.GetGoPath())
log.Info("err:", err)
bad += 1
badmap[depRepo.GetGoPath()] = err
} else {
log.Info("downloaded", depRepo.GetGoPath())
good += 1
}
}
log.Info("got", good, "repos", "failed on", bad, "repos")
if bad != 0 {
log.Info("clone() ERROR len(badmap)", len(badmap))
for gopath, err := range badmap {
log.Info("clone() ERROR", gopath, err)
}
if !argv.Ignore {
return errors.New("clone failed on some repos")
}
}
return nil
}
func makeValidGoSum(check *gitpb.Repo) error {
// attempt to grab the notes
check.Run([]string{"git", "fetch", "origin", "refs/notes/*:refs/notes/*"})
if check.ParseGoSum() {
return nil
}
log.Info("try running go-mod-clean")
// update go.sum and go.mod
if err := check.RunStrict([]string{"go-mod-clean"}); err != nil {
log.Info("")
log.Info("Do you have go-mod-clean? Otherwise:")
log.Info(" go install go.wit.com/apps/go-mod-clean@latest")
log.Info("")
}
if check.ParseGoSum() {
return nil
}
// if this fails, just use go mod
if err := check.ValidGoSum(); err != nil {
cmd := []string{"go", "mod", "init", check.GetGoPath()}
log.Info("try running", cmd)
if err := check.RunStrict(cmd); err != nil {
log.Info("go mod init failed", err)
}
if err := check.RunStrict([]string{"go", "mod", "tidy"}); err != nil {
log.Info("go mod tidy failed", err)
}
}
if check.ParseGoSum() {
return nil
}
return fmt.Errorf("could not make a valid go.mod")
}