summaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'main.go')
-rw-r--r--main.go158
1 files changed, 135 insertions, 23 deletions
diff --git a/main.go b/main.go
index 8e5d501..8b3c85e 100644
--- a/main.go
+++ b/main.go
@@ -1,9 +1,14 @@
package main
import (
+ "errors"
+ "fmt"
"os"
+ "path/filepath"
+ "strings"
"go.wit.com/dev/alexflint/arg"
+ "go.wit.com/lib/gui/shell"
"go.wit.com/lib/protobuf/forgepb"
"go.wit.com/lib/protobuf/gitpb"
"go.wit.com/log"
@@ -21,46 +26,153 @@ func main() {
log.Info("go-clean version", VERSION, "built on", BUILDTIME)
pp = arg.MustParse(&argv)
- // for very new users or users unfamilar with the command line, this may help them
- if argv.Repo == "help" || argv.Repo == "?" {
- pp.WriteHelp(os.Stdout)
- os.Exit(0)
- }
- if argv.Repo == "version" {
- log.Info(argv.Version())
- os.Exit(0)
- }
-
// load the ~/.config/forge/ config
// this lets you configure repos you have read/write access too
forge = forgepb.Init()
+ // rescan just in case (?) todo: decide what forge should default too
+ forge.ScanGoSrc()
- check = forge.Repos.FindByGoPath(argv.Repo)
+ // figure out what directory we are running in
+ check = findPwdRepo()
if check == nil {
- log.Info("need to go-clone", argv.Repo)
- return
+ log.Info("this directory isn't in a golang project (not in ~/go/src nor a go.work file)")
+ os.Exit(-1)
+ }
+ log.Info("starting go-clean for", check.GoPath)
+ log.Info("go src dir is set to", forge.GetGoSrc())
+
+ if argv.Recursive {
+ if forge.IsGoWork() {
+ var warning []string
+ warning = append(warning, "go-clean --recursive may not work unless you are in ~/go/src")
+ warning = append(warning, "you can continue anyway, but it hasn't been tested as much.")
+ simpleStdin(true, warning)
+ }
+ var warning []string
+ warning = append(warning, "go-clean will recreate go.mod and go.sum")
+ warning = append(warning, "because you have selected --recursive")
+ warning = append(warning, "this will redo _every_ repo. This is probably fine.")
+ warning = append(warning, fmt.Sprintf("You have %d total repositories in %s", forge.Repos.Len(), forge.GetGoSrc()))
+ warning = append(warning, "")
+ warning = append(warning, "However, this will also do:")
+ warning = append(warning, "")
+ warning = append(warning, "rm -rf ~/go/pkg/")
+ warning = append(warning, "rm -rf ~/.config/go-build/")
+ warning = append(warning, "")
+ warning = append(warning, "Which is also probably fine, but will clear all your build cache and go mod cache")
+ warning = append(warning, "")
+ simpleStdin(false, warning)
+ purgeGoCaches()
+ } else {
+ simpleStdin(true, []string{"go-clean will recreate go.mod and go.sum"})
}
- log.Info("already have", argv.Repo)
- log.Info("go src dir", forge.GetGoSrc())
// re-create go.sum and go.mod
- check.RedoGoMod()
- deps := check.GoDeps.SortByGoPath()
- for deps.Scan() {
- depRepo := deps.Next()
- log.Info("check has dep:", depRepo.GoPath)
+ if _, err := check.RedoGoMod(); err != nil {
+ badExit(err)
+ }
+
+ /*
+ // re-process go deps
+ deps := check.GoDeps.SortByGoPath()
+ for deps.Scan() {
+ depRepo := deps.Next()
+ log.Info("check has dep:", depRepo.GoPath)
+ }
+ */
+ // check go.sum file
+ if forge.FinalGoDepsCheckOk(check) {
+ log.Info("forge.FinalGoDepsCheck() worked :", check.GoPath)
+ okExit(check.GoPath + " go.sum seems clean")
+ }
+ log.Info("forge.FinalGoDepsCheck() failed. boo. :", check.GoPath)
+ badExit(errors.New(check.GoPath + " go.sum is not perfect"))
+}
+
+func findPwdRepo() *gitpb.Repo {
+ var check *gitpb.Repo
+ // attempt to use the working directory
+ // this is probably what happens most of the time
+ pwd, _ := os.Getwd()
+ if strings.HasPrefix(pwd, forge.GetGoSrc()) {
+ gopath := strings.TrimPrefix(pwd, forge.GetGoSrc())
+ gopath = strings.Trim(gopath, "/")
+ log.Info("findRepo() trying gopath", gopath)
+ check = forge.Repos.FindByGoPath(gopath)
+ if check != nil {
+ log.Info("findRepo() worked", check.GoPath)
+ return check
+ }
}
- okExit("skipping build of " + argv.Repo)
+ return nil
}
func okExit(thing string) {
log.Info(thing, "ok")
- log.Info("Finished clone on", check.GetGoPath(), "ok")
+ log.Info("Finished go-clean on", check.GetGoPath(), "ok")
os.Exit(0)
}
func badExit(err error) {
- log.Info("Total repositories:", forge.Repos.Len())
log.Info("Finished go-clean with error", err, forge.GetGoSrc())
os.Exit(-1)
}
+
+func purgeGoCaches() {
+ homedir, err := os.UserHomeDir()
+ if err != nil {
+ badExit(err)
+ }
+ pkgdir := filepath.Join(homedir, "go/pkg")
+ var cmd []string
+ cmd = []string{"chmod", "700", "-R", pkgdir}
+ runStrict("", cmd)
+ cmd = []string{"rm", "-rf", pkgdir}
+ runStrict("", cmd)
+ builddir := filepath.Join(homedir, ".cache/go-build")
+ cmd = []string{"rm", "-rf", builddir}
+ runStrict("", cmd)
+
+ // this can't have really happened
+ // echo this still failed in:
+ // echo "Linux hpdev2.grid.wit.com 6.9.8-rt-amd64 #1 SMP PREEMPT_RT Debian 6.9.8-1 (2024-07-07) x86_64 GNU/Linux"
+ // echo and I had to drop the caches after building go install binaries quickly and running them
+ // echo "as an os.Exec() between binaries"
+ // echo sysctl -w vm.drop_caches=3
+}
+
+func runStrict(wd string, cmd []string) {
+ var err error
+ if wd != "" {
+ if err = os.Chdir(wd); err != nil {
+ log.Info("cd", "wd", "failed", err)
+ badExit(err)
+ }
+ }
+ log.Info(wd, "running:", wd, cmd)
+ // result := shell.Run(cmd)
+ result := shell.RunRealtime(cmd)
+ if result.Error != nil {
+ log.Info("cmd failed", wd, cmd, err)
+ for i, line := range result.Stdout {
+ log.Info("STDOUT:", i, line)
+ }
+ for i, line := range result.Stderr {
+ log.Info("STDERR:", i, line)
+ }
+ badExit(err)
+ }
+ if result.Exit != 0 {
+ log.Info("cmd failed", wd, cmd, err)
+ for i, line := range result.Stdout {
+ log.Info("STDOUT:", i, line)
+ }
+ for i, line := range result.Stderr {
+ log.Info("STDERR:", i, line)
+ }
+ badExit(errors.New(fmt.Sprintf("cmd failed with %d", result.Exit)))
+ }
+ for i, line := range result.Stdout {
+ log.Info(i, line)
+ }
+}