package main import ( "errors" "fmt" "os" "path/filepath" "go.wit.com/lib/gui/shell" "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.Repos.FindByGoPath(gopath) if check != nil { if check.IsValid() { // repo already exists and is valid return check, nil } } pb, err := forge.Clone(gopath) if err != nil { log.Info("clone() could not download err:", err) return nil, err } if err := makeValidGoSum(pb); err != nil { return nil, err } // double check it actually downloaded fullgitdir := filepath.Join(forge.GetGoSrc(), gopath, ".git") if !shell.IsDir(fullgitdir) { log.Info("repo cloned failed", filepath.Join(forge.GetGoSrc(), gopath)) return nil, errors.New(fullgitdir + " was not created") } log.Info("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.GoPath) log.Info("STARTING RECURSIVE CLONE", check.GoPath) if check.GoPrimitive { log.Info("repo is a primitive", check.GoPath) // go primitive repos are "pure" return nil } // if just cloned, parse the go.sum file for deps check.ParseGoSum() if check.GoDeps == nil { log.Info("repo godeps == nil", check.GoPath) 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.GoPath) return errors.New("go.sum never parsed?") } log.Info("deps for", check.GoPath, "len()", check.GoDeps.Len()) deps := check.GoDeps.SortByGoPath() for deps.Scan() { depRepo := deps.Next() log.Info("download:", depRepo.GoPath) _, err := clone(depRepo.GoPath) if err != nil { log.Info("recursiveClone() could not download", depRepo.GoPath) log.Info("err:", err) bad += 1 badmap[depRepo.GoPath] = err } else { log.Info("downloaded", depRepo.GoPath) 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 { if check.Exists("go.mod") { if err := check.SetPrimitive(); err != nil { return err } } if check.GoPrimitive { log.Info(check.GoPath, "is a golang primitive! no need to parse go.sum because there is not one!") return nil } // first try to generate go.mod & go.sum with go-mod-clean if err := check.ValidGoSum(); err != 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 this fails, just use go mod if err := check.ValidGoSum(); err != nil { cmd := []string{"go", "mod", "init", check.GoPath} log.Info("try running", cmd) if err := check.RunStrict(cmd); err != nil { log.Info("go mod init failed", err) } if check.Exists("go.mod") { if err := check.SetPrimitive(); err != nil { return err } } if check.GoPrimitive { log.Info(check.GoPath, "is a golang primitive! no need to parse go.sum because there is not one!") return nil } if err := check.RunStrict([]string{"go", "mod", "tidy"}); err != nil { log.Info("go mod tidy failed", err) } panic("fucknuts") } if err := check.ValidGoSum(); err != nil { // have to give up. can't recursive clone without go.mod file log.Info("could not generate valid go.sum file") return errors.New(fmt.Sprintf("could have been %v", err)) } check.ParseGoSum() return nil }