gomod/gomod.go

101 lines
2.3 KiB
Go

package gomod
import (
"context"
"fmt"
"os"
"os/exec"
"regexp"
"strings"
"github.com/google/go-github/v53/github"
"golang.org/x/mod/modfile"
)
var githubRegexp = regexp.MustCompile(`github.com/(.*)/(.*)`)
func command(url string) error {
cmd := exec.Command("go", "get", "-u", url)
if _, err := cmd.CombinedOutput(); err != nil {
return err
}
return nil
}
func AllModUpgrade() {
modFileData, err := os.ReadFile("go.mod")
if err != nil {
fmt.Printf("read go.mod file failed: %v\n", err)
return
}
modFile, err := modfile.Parse("go.mod", modFileData, nil)
if err != nil {
fmt.Printf("parse go.mod file failed: %v\n", err)
return
}
for _, mod := range modFile.Require {
if mod.Indirect {
continue
}
fmt.Printf("go get -u %s\n", mod.Mod.String())
if err := command(mod.Mod.String()); err != nil {
fmt.Printf("upgrade %s failed: %v\n", mod.Mod.String(), err)
continue
}
fmt.Printf("upgrade %s success\n", mod.Mod.String())
}
}
func SingleModUpgrade(url string) {
version := url + "@latest"
if strings.Contains(url, "github.com") {
commitID, err := getCommitID(url)
if err == nil {
version = url + "@" + commitID[:8]
}
}
if err := command(version); err != nil {
fmt.Printf("upgrade %s failed: %v\n", version, err)
return
}
fmt.Printf("upgrade %s success\n", version)
}
func parseUrl(url string) (owner, repo string) {
res := githubRegexp.FindAllStringSubmatch(url, -1)
if len(res) != 1 {
panic(fmt.Sprintf("%s url no match github url rule: %s", url, githubRegexp.String()))
}
if len(res[0]) != 3 {
panic(fmt.Sprintf("%s url no match github url rule: %s", url, githubRegexp.String()))
}
return res[0][1], res[0][2]
}
func getCommitID(url string) (string, error) {
owner, repo := parseUrl(url)
client := github.NewClient(nil)
ctx := context.Background()
tags, _, err := client.Repositories.ListTags(ctx, owner, repo, &github.ListOptions{
Page: 0,
PerPage: 1,
})
if len(tags) == 0 && err != nil {
fmt.Printf("get tag info failed: %v, start get commit id", err)
}
commits, _, err := client.Repositories.ListCommits(ctx, owner, repo, &github.CommitsListOptions{
ListOptions: github.ListOptions{
Page: 0,
PerPage: 1,
},
})
if err != nil {
return "", err
}
if len(commits) == 0 {
return "", fmt.Errorf("get commit info empty")
}
return *commits[0].SHA, nil
}