175 lines
3.2 KiB
Go
175 lines
3.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"regexp"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
var latestGoVersion string
|
|
|
|
func main() {
|
|
latestGoVersion = getLatestGoVersionFromWebsite()
|
|
|
|
const workers = 5
|
|
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(workers)
|
|
|
|
files := make(chan string)
|
|
|
|
for i := 0; i < workers; i++ {
|
|
go func() {
|
|
for file := range files {
|
|
dir := filepath.Dir(file)
|
|
if dir == "." {
|
|
continue
|
|
}
|
|
|
|
fmt.Println("update of", file, "@", dir)
|
|
|
|
if err := replaceGoInDockerCompose(dir); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if err := updateDeps(dir, file); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
if err := updateWatermill(dir, file); err != nil {
|
|
panic(fmt.Sprintf("failed to update %s: %s", file, err))
|
|
}
|
|
|
|
if err := goModTidy(dir, file); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
wg.Done()
|
|
}()
|
|
}
|
|
|
|
for _, file := range getGomods() {
|
|
files <- file
|
|
}
|
|
close(files)
|
|
|
|
wg.Wait()
|
|
}
|
|
|
|
func getGomods() []string {
|
|
var fileList []string
|
|
|
|
err := filepath.Walk(".", func(path string, f os.FileInfo, err error) error {
|
|
if strings.Contains(path, "go.mod") {
|
|
fileList = append(fileList, path)
|
|
}
|
|
return nil
|
|
})
|
|
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return fileList
|
|
}
|
|
|
|
func getLatestGoVersionFromWebsite() string {
|
|
resp, err := http.Get("https://go.dev/VERSION?m=text")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
out, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
version := strings.Split(string(out), "\n")[0]
|
|
version = strings.TrimPrefix(version, "go")
|
|
|
|
// we only want the major.minor version
|
|
version = strings.Split(version, ".")[0] + "." + strings.Split(version, ".")[1]
|
|
|
|
return version
|
|
}
|
|
|
|
func goModTidy(dir string, file string) error {
|
|
cmd := []string{"go", "mod", "tidy", "-go=" + latestGoVersion}
|
|
|
|
fmt.Println("\nrunning", cmd, "in", dir)
|
|
|
|
cmd2 := exec.Command(cmd[0], cmd[1:]...)
|
|
cmd2.Dir = dir
|
|
cmd2.Stderr = os.Stderr
|
|
cmd2.Stdout = os.Stdout
|
|
|
|
return cmd2.Run()
|
|
}
|
|
|
|
// replaceGoInDockerCompose replaces the go version in the Dockerfile
|
|
// using Go (not sed)
|
|
func replaceGoInDockerCompose(dir string) error {
|
|
dockerComposeFile := filepath.Join(dir, "docker-compose.yml")
|
|
|
|
b, err := os.ReadFile(dockerComposeFile)
|
|
// return if not exist
|
|
if os.IsNotExist(err) {
|
|
return nil
|
|
}
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pattern := `golang:1\.[0-9]+(?:\.[0-9]+)?`
|
|
re, err := regexp.Compile(pattern)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to compile regex: %w", err)
|
|
}
|
|
|
|
newContent := re.ReplaceAllString(string(b), "golang:"+latestGoVersion)
|
|
|
|
err = os.WriteFile(dockerComposeFile, []byte(newContent), 0644)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to write updated docker-compose.yml: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func updateWatermill(dir string, file string) error {
|
|
c := []string{"go", "get", "-u", "github.com/ThreeDotsLabs/watermill@latest"}
|
|
|
|
fmt.Println("\nrunning", c, "in", dir)
|
|
|
|
cmd := exec.Command(c[0], c[1:]...)
|
|
cmd.Dir = dir
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Stdout = os.Stdout
|
|
err := cmd.Run()
|
|
|
|
return err
|
|
}
|
|
|
|
func updateDeps(dir string, file string) error {
|
|
c := []string{"go", "get", "-u", "./..."}
|
|
|
|
fmt.Println("\nrunning", c, "in", dir)
|
|
|
|
cmd := exec.Command(c[0], c[1:]...)
|
|
cmd.Dir = dir
|
|
cmd.Stderr = os.Stderr
|
|
cmd.Stdout = os.Stdout
|
|
err := cmd.Run()
|
|
|
|
return err
|
|
}
|