1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
|
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"
)
// sent via -ldflags
var VERSION string
var BUILDTIME string
var pp *arg.Parser
var forge *forgepb.Forge
var check *gitpb.Repo
func main() {
log.Info("go-clean version", VERSION, "built on", BUILDTIME)
pp = arg.MustParse(&argv)
// 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()
// 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)
}
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"})
}
// re-create go.sum and go.mod
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
}
}
return nil
}
func okExit(thing string) {
log.Info(thing, "ok")
log.Info("Finished go-clean on", check.GetGoPath(), "ok")
os.Exit(0)
}
func badExit(err error) {
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)
}
}
|