diff --git a/Makefile b/Makefile index cc409dd..986396d 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ VERSION = $(shell git describe --tags) BUILDTIME = $(shell date +%Y.%m.%d_%H%M) -run: goimports install +run: install go-mod-clean --version vet: @@ -22,7 +22,7 @@ build-windows: GOOS=windows GOARCH=amd64 GO111MODULE=off go build -v go-mod-clean.exe \ -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" -install: +install: goimports GO111MODULE=off go install \ -ldflags "-X main.VERSION=${VERSION} -X main.BUILDTIME=${BUILDTIME} -X gui.GUIVERSION=${VERSION}" @@ -34,3 +34,6 @@ goimports: clean: -rm -f go-mod-clean go.* + +all: install + go-mod-clean --all --auto diff --git a/exit.go b/exit.go new file mode 100644 index 0000000..4664fda --- /dev/null +++ b/exit.go @@ -0,0 +1,24 @@ +package main + +import ( + "os" + + "go.wit.com/lib/protobuf/gitpb" + "go.wit.com/log" +) + +func okExit(check *gitpb.Repo, msg string) { + log.Info("exit() go-mod-clean on", check.GetGoPath(), "ok") + log.DaemonMode(true) + log.Info(msg) + os.Exit(0) +} + +func badExit(check *gitpb.Repo, err error) { + log.DaemonMode(true) + log.Info("go-mod-clean failed: ", err, forge.GetGoSrc()) + if check != nil { + eraseGoMod(check) + } + os.Exit(-1) +} diff --git a/main.go b/main.go index 5371daf..8febccd 100644 --- a/main.go +++ b/main.go @@ -17,9 +17,12 @@ var BUILDTIME string var pp *arg.Parser var forge *forgepb.Forge -var check *gitpb.Repo + +// var check *gitpb.Repo +var configSave bool func main() { + var check *gitpb.Repo log.Info("go-mod-clean version", VERSION, "built on", BUILDTIME) pp = arg.MustParse(&argv) @@ -27,66 +30,35 @@ func main() { // this lets you configure repos you have read/write access too forge = forgepb.Init() - // figure out what directory we are running in - check = findPwdRepo() - if check == nil { - log.Info("this directory isn't in a golang project (not in ~/go/src nor a go.work file)") - os.Exit(-1) - } - - if err := check.ValidGoSum(); err == nil { - okExit("go.mod and go.sum are already valid") - } - - // skip restore if --force - if !argv.Force { - cname := check.GetCurrentBranchName() - // try to restore from the git metadata - if err := check.AutogenRestore(cname); err != nil { - // ignore errors here + if argv.All { + // run this on every single repo + // do this before publishing new golang versions + all := forge.Repos.SortByGoPath() + for all.Scan() { + check = all.Next() + if err := doMain(check); err != nil { + badExit(check, err) + } } - if err := check.ValidGoSum(); err == nil { - okExit("go.mod and go.sum were restored ok") + } else { + // figure out what directory we are running in + check := findPwdRepo() + if check == nil { + log.Info("this directory isn't in a golang project (not in ~/go/src nor a go.work file)") + os.Exit(-1) + } + + if err := doMain(check); err != nil { + badExit(check, err) } } - if check.GetMasterBranchName() != check.GetCurrentBranchName() { - log.Info("") - log.Info("You can only run go-mod-clean on a git master branch.") - log.Info("Publishing go.mod & go.sum files must come from from git version tag") - log.Info("Anything else doesn't make sense.") - log.Info("") - badExit(errors.New("not git master branch")) - } - - // re-create go.sum and go.mod - if _, err := redoGoMod(check); err != nil { - badExit(err) - } - - if argv.Trim { - // try to trim junk - if err := trimGoSum(check); err != nil { - badExit(err) - } - } - - // check go.sum file - if err := cleanGoDepsCheckOk(check); err != nil { - log.Info("forge.FinalGoDepsCheck() failed. boo. :", check.GoPath) - badExit(err) - } - - // put the files in the notes section in git - // this way, git commits are not messed up - // with this autogenerated code - if err := saveAsMetadata(check); err != nil { - log.Info("save go.mod as git metadata failed", check.GoPath, err) - badExit(err) + if configSave { + forge.ConfigSave() } log.Info("forge.FinalGoDepsCheck() worked :", check.GoPath) - okExit(check.GoPath + " go.sum seems clean") + okExit(check, "go.sum seems clean") } func findPwdRepo() *gitpb.Repo { @@ -107,29 +79,85 @@ func findPwdRepo() *gitpb.Repo { return nil } -func okExit(msg string) { - log.Info("exit() go-mod-clean on", check.GetGoPath(), "ok") - log.DaemonMode(true) - log.Info(msg) - os.Exit(0) -} - -func badExit(err error) { - log.DaemonMode(true) - log.Info("go-mod-clean failed: ", err, forge.GetGoSrc()) - os.Exit(-1) -} - func saveAsMetadata(repo *gitpb.Repo) error { - cname := check.GetCurrentBranchName() - if check.GoPrimitive { - if err := check.AutogenSave([]string{"go.mod"}, cname, true); err != nil { + cname := repo.GetCurrentBranchName() + if repo.GoPrimitive { + if err := repo.AutogenSave([]string{"go.mod"}, cname, true); err != nil { return err } } else { - if err := check.AutogenSave([]string{"go.mod", "go.sum"}, cname, true); err != nil { + if err := repo.AutogenSave([]string{"go.mod", "go.sum"}, cname, true); err != nil { return err } } return nil } + +func doMain(repo *gitpb.Repo) error { + if !repo.IsValid() { + log.Info(repo.GoPath, "is invalid. fix your repos.pb file with 'forge' first") + log.Info("") + log.Info("go install go.wit.com/apps/forge@latest") + log.Info("") + return errors.New(repo.GoPath + " is invalid. fix your repository list with 'forge' first") + } else { + log.Info(repo.GoPath, "is valid according to forge") + } + if err := repo.ValidGoSum(); err == nil { + log.Info(repo.GoPath, "go.mod and go.sum are already valid") + return nil + } + + // skip restore if --force + if !argv.Force { + cname := repo.GetCurrentBranchName() + // try to restore from the git metadata + if err := repo.AutogenRestore(cname); err != nil { + // ignore errors here + } + if err := repo.ValidGoSum(); err == nil { + log.Info(repo.GoPath, "go.mod and go.sum were restored ok") + configSave = true + return nil + } + } + + if repo.GetMasterBranchName() != repo.GetCurrentBranchName() { + log.Info("") + log.Info("You can only run go-mod-clean on a git master branch.") + log.Info("Publishing go.mod & go.sum files must come from from git version tag") + log.Info("Anything else doesn't make sense.") + log.Info("") + return errors.New(repo.GoPath + " not in the git master branch") + } + + // re-create go.sum and go.mod + if err := redoGoMod(repo); err != nil { + return err + } + + if argv.Trim { + // try to trim junk + if err := trimGoSum(repo); err != nil { + return err + } + } + + // check go.sum file + if err := cleanGoDepsCheckOk(repo); err != nil { + log.Info("forge.FinalGoDepsCheck() failed. boo. :", repo.GoPath) + return err + } + + // put the files in the notes section in git + // this way, git commits are not messed up + // with this autogenerated code + if err := saveAsMetadata(repo); err != nil { + log.Info("save go.mod as git metadata failed", repo.GoPath, err) + return err + } + + // everything worked! + configSave = true + return nil +} diff --git a/redoGoMod.go b/redoGoMod.go index f25a3b4..3af8663 100644 --- a/redoGoMod.go +++ b/redoGoMod.go @@ -30,26 +30,26 @@ func setGoVersion(repo *gitpb.Repo, version string) error { } // wrapper around 'go mod init' and 'go mod tidy' -func redoGoMod(repo *gitpb.Repo) (bool, error) { +func redoGoMod(repo *gitpb.Repo) error { // unset the go development ENV var to generate release files os.Unsetenv("GO111MODULE") if err := repo.StrictRun([]string{"rm", "-f", "go.mod", "go.sum"}); err != nil { log.Warn("rm go.mod go.sum failed", err) - return false, err + return err } if err := repo.StrictRun([]string{"go", "mod", "init", repo.GoPath}); err != nil { log.Warn("go mod init failed", err) - return false, err + return err } if err := repo.StrictRun([]string{"go", "mod", "tidy"}); err != nil { log.Warn("go mod tidy failed", err) - return false, err + return err } // most things should build with golang after 1.20 // todo: allow this to be set somewhere if err := setGoVersion(repo, "1.20"); err != nil { log.Warn(repo.GoPath, "go mod edit failed", err) - return false, err + return err } repo.GoDeps = nil @@ -57,29 +57,31 @@ func redoGoMod(repo *gitpb.Repo) (bool, error) { // if there is not a go.sum file, it better be a primitive golang project if !repo.Exists("go.sum") { - // this should never happen - return false, errors.New("MakeRedomod() logic failed") - + // todo. fix this logic ok, err := repo.IsPrimitive() if err != nil { // this means this repo does not depend on any other package log.Info("PRIMATIVE repo error:", repo.GoPath, "err =", err) - return false, err + return err } if ok { // this means the repo is primitive so there is no go.sum repo.GoPrimitive = true - return true, nil + repo.GoDeps = new(gitpb.GoDeps) + return nil } } - repo.GoDeps = new(gitpb.GoDeps) if !repo.Exists("go.sum") { // this should never happen - return false, errors.New("MakeRedomod() logic failed") + data, _ := repo.ReadFile("go.mod") + log.Info(string(data)) + return errors.New("missing go.sum file on non-primitive go.mod") } + repo.GoDeps = new(gitpb.GoDeps) // return the attempt to parse go.sum - return repo.ParseGoSum() + _, err := repo.ParseGoSum() + return err } diff --git a/run.go b/run.go index 2dcb53b..ac20c0a 100644 --- a/run.go +++ b/run.go @@ -13,7 +13,7 @@ import ( func purgeGoCaches() { homedir, err := os.UserHomeDir() if err != nil { - badExit(err) + badExit(nil, err) } pkgdir := filepath.Join(homedir, "go/pkg") var cmd []string @@ -38,7 +38,7 @@ func runStrict(wd string, cmd []string) { if wd != "" { if err = os.Chdir(wd); err != nil { log.Info("cd", "wd", "failed", err) - badExit(err) + badExit(nil, err) } } log.Info(wd, "running:", wd, cmd) @@ -52,7 +52,7 @@ func runStrict(wd string, cmd []string) { for i, line := range result.Stderr { log.Info("STDERR:", i, line) } - badExit(err) + badExit(nil, err) } if result.Exit != 0 { log.Info("cmd failed", wd, cmd, err) @@ -62,7 +62,7 @@ func runStrict(wd string, cmd []string) { for i, line := range result.Stderr { log.Info("STDERR:", i, line) } - badExit(errors.New(fmt.Sprintf("cmd failed with %d", result.Exit))) + badExit(nil, errors.New(fmt.Sprintf("cmd failed with %d", result.Exit))) } for i, line := range result.Stdout { log.Info(i, line) diff --git a/stdin.go b/stdin.go index de81e3a..a28e3fa 100644 --- a/stdin.go +++ b/stdin.go @@ -41,15 +41,15 @@ func simpleStdin(b bool, s []string) { return case "n": log.Info("got n") - badExit(err) + badExit(nil, err) case "": if b { return } else { - badExit(err) + badExit(nil, err) } default: - badExit(err) + badExit(nil, err) } } }