github.com/mongodb/grip@v0.0.0-20240213223901-f906268d82b9/cmd/verify-mod-tidy/verify-mod-tidy.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "context" 6 "flag" 7 "fmt" 8 "os" 9 "os/exec" 10 "time" 11 12 "github.com/pkg/errors" 13 ) 14 15 const ( 16 goModFile = "go.mod" 17 goSumFile = "go.sum" 18 ) 19 20 // verify-mod-tidy verifies that `go mod tidy` has been run to clean up the 21 // go.mod and go.sum files. 22 func main() { 23 var ( 24 goBin string 25 timeout time.Duration 26 ) 27 28 flag.DurationVar(&timeout, "timeout", 0, "timeout for verifying modules are tidy") 29 flag.StringVar(&goBin, "goBin", "go", "path to go binary to use for mod tidy check") 30 flag.Parse() 31 32 ctx := context.Background() 33 if timeout != 0 { 34 var cancel context.CancelFunc 35 ctx, cancel = context.WithTimeout(ctx, timeout) 36 defer cancel() 37 } 38 39 oldGoMod, oldGoSum, err := readModuleFiles() 40 if err != nil { 41 fmt.Fprintln(os.Stderr, err) 42 os.Exit(1) 43 } 44 45 if err := runModTidy(ctx, goBin); err != nil { 46 fmt.Fprintln(os.Stderr, err) 47 os.Exit(1) 48 } 49 50 newGoMod, newGoSum, err := readModuleFiles() 51 if err != nil { 52 fmt.Fprintln(os.Stderr, err) 53 os.Exit(1) 54 } 55 56 if !bytes.Equal(oldGoMod, newGoMod) || !bytes.Equal(oldGoSum, newGoSum) { 57 fmt.Fprintf(os.Stderr, "%s and/or %s are not tidy - please run `go mod tidy`.\n", goModFile, goSumFile) 58 writeModuleFiles(oldGoMod, oldGoSum) 59 os.Exit(1) 60 } 61 } 62 63 // readModuleFiles reads the contents of the go module files. 64 func readModuleFiles() (goMod []byte, goSum []byte, err error) { 65 goMod, err = os.ReadFile(goModFile) 66 if err != nil { 67 return nil, nil, errors.Wrapf(err, "reading file '%s'", goModFile) 68 } 69 goSum, err = os.ReadFile(goSumFile) 70 if err != nil { 71 return nil, nil, errors.Wrapf(err, "reading file '%s'", goSumFile) 72 } 73 return goMod, goSum, nil 74 } 75 76 // writeModuleFiles writes the contents of the go module files. 77 func writeModuleFiles(goMod, goSum []byte) { 78 if err := os.WriteFile(goModFile, goMod, 0600); err != nil { 79 fmt.Fprintln(os.Stderr, err) 80 } 81 if err := os.WriteFile(goSumFile, goSum, 0600); err != nil { 82 fmt.Fprintln(os.Stderr, err) 83 } 84 } 85 86 // runModTidy runs the `go mod tidy` command with the given go binary. 87 func runModTidy(ctx context.Context, goBin string) error { 88 cmd := exec.CommandContext(ctx, goBin, "mod", "tidy") 89 cmd.Stdout = os.Stdout 90 cmd.Stderr = os.Stderr 91 return errors.Wrap(cmd.Run(), "mod tidy") 92 }