feat: strong search go module version

This commit is contained in:
xuthus5 2023-07-22 16:00:31 +08:00
parent 777d270520
commit 9f004fb00d
Signed by: xuthus5
GPG Key ID: A23CF9620CBB55F9
6 changed files with 156 additions and 32 deletions

68
git-ls-remote.go Normal file
View File

@ -0,0 +1,68 @@
package gomod
import (
"fmt"
"os/exec"
"regexp"
"strings"
)
var (
lsRemote _lsRemote
tagRegexp = regexp.MustCompile(`refs/tags/(.*)`)
headRegexp = regexp.MustCompile(`refs/heads/(master|main)`)
)
type _lsRemote struct {
url string
output string
}
func (lr *_lsRemote) setUrl(url string) *_lsRemote {
if !strings.HasPrefix(url, "https") {
url = "https://" + url
}
lr.url = url
return lr
}
func (lr *_lsRemote) command() error {
cmd := exec.Command("git", "ls-remote", "--heads", "--tags", lr.url)
output, err := cmd.CombinedOutput()
if err != nil {
return err
}
lr.output = string(output)
return nil
}
func (lr *_lsRemote) getLatestTagOrCommitID() (string, error) {
if err := lr.command(); err != nil {
return "", err
}
lr.output = strings.Trim(lr.output, "\n ")
commits := strings.Split(lr.output, "\n")
if len(commits) == 0 {
return "", fmt.Errorf("get commit log empty")
}
commit := commits[len(commits)-1]
if strings.Contains(commit, "refs/heads/") {
matches := headRegexp.FindStringSubmatch(commit)
if len(matches) != 2 {
return "", fmt.Errorf("%s no match rule: %s", commit, headRegexp.String())
}
return strings.Trim(strings.ReplaceAll(commit, matches[0], ""), " \n\t\r"), nil
}
if strings.Contains(commit, "refs/tags/") {
matches := tagRegexp.FindStringSubmatch(commit)
if len(matches) != 2 {
return "", fmt.Errorf("%s no match rule: %s", commit, tagRegexp.String())
}
return matches[1], nil
}
return "", fmt.Errorf("%s no match heads and tags rule", commit)
}

17
git-ls-remote_test.go Normal file
View File

@ -0,0 +1,17 @@
package gomod
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestNormalUrlGetTag(t *testing.T) {
output, err := lsRemote.setUrl("https://gitter.top/coco/bootstrap").getLatestTagOrCommitID()
assert.NoError(t, err)
t.Log(output)
output, err = lsRemote.setUrl("https://github.com/spf13/cobra").getLatestTagOrCommitID()
assert.NoError(t, err)
t.Log(output)
}

10
go.mod
View File

@ -3,24 +3,28 @@ module gitter.top/apps/gomod
go 1.20
require (
github.com/google/go-github/v53 v53.0.0
github.com/google/go-github/v53 v53.2.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
gitter.top/common/lormatter v0.0.0-20230630185243-1bb8638cf785
github.com/stretchr/testify v1.7.0
gitter.top/common/lormatter v0.0.0-20230722045844-3f2987f9dd0e
golang.org/x/mod v0.10.0
)
require (
github.com/ProtonMail/go-crypto v0.0.0-20230528122434-6f98819771a1 // indirect
github.com/cloudflare/circl v1.3.3 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.7.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/oauth2 v0.8.0 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/sys v0.10.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

12
go.sum
View File

@ -17,8 +17,8 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-github/v53 v53.0.0 h1:T1RyHbSnpHYnoF0ZYKiIPSgPtuJ8G6vgc0MKodXsQDQ=
github.com/google/go-github/v53 v53.0.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao=
github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI=
github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
@ -39,8 +39,8 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
gitter.top/common/lormatter v0.0.0-20230630185243-1bb8638cf785 h1:hgeKDXRze6Cew4Wu/6PdNkTS/XYFeaNQNiT/Sjo4/Z4=
gitter.top/common/lormatter v0.0.0-20230630185243-1bb8638cf785/go.mod h1:/Zue/gLVDDSvCCRJKytEfpX0LP/JHkIeDzwVE5cA254=
gitter.top/common/lormatter v0.0.0-20230722045844-3f2987f9dd0e h1:R/PQxgliGNSKBKIXReaZWShyiPqUjwRbd+1j0+H7APo=
gitter.top/common/lormatter v0.0.0-20230722045844-3f2987f9dd0e/go.mod h1:/Zue/gLVDDSvCCRJKytEfpX0LP/JHkIeDzwVE5cA254=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
@ -75,8 +75,8 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=

View File

@ -3,24 +3,48 @@ package gomod
import (
"context"
"fmt"
"github.com/sirupsen/logrus"
"os"
"os/exec"
"regexp"
"strings"
"github.com/google/go-github/v53/github"
"github.com/sirupsen/logrus"
"golang.org/x/mod/modfile"
)
const (
defaultVersion = "latest"
)
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
func upgrade(url string) (newUrl string, err error) {
var version = defaultVersion
if strings.Contains(url, "github.com") {
commitID, err := getCommitID(url)
if err != nil {
logrus.WithField("url", url).Warnf("get github commit id failed, use default version: %v", err)
} else {
version = commitID
}
}
return nil
if version == defaultVersion {
v, err := lsRemote.setUrl(url).getLatestTagOrCommitID()
if err != nil {
logrus.WithField("url", url).Warnf("get git ls-remote info failed, use default version: %v", err)
} else {
version = v
}
}
versionUrl := url + "@" + version
cmd := exec.Command("go", "get", "-u", versionUrl)
if _, err := cmd.CombinedOutput(); err != nil {
return "", err
}
return versionUrl, nil
}
func AllModUpgrade() {
@ -34,33 +58,26 @@ func AllModUpgrade() {
logrus.Errorf("parse go.mod file failed: %v", err)
return
}
for _, mod := range modFile.Require {
if mod.Indirect {
continue
}
logrus.Infof("go get -u %s", mod.Mod.String())
if err := command(mod.Mod.String()); err != nil {
logrus.Errorf("upgrade %s failed: %v", mod.Mod.String(), err)
versionUrl, err := upgrade(mod.Mod.String())
if err != nil {
logrus.WithField("url", mod.Mod.String()).Errorf("upgrade failed: %v", err)
continue
}
logrus.Infof("upgrade %s success", mod.Mod.String())
logrus.WithField("url", versionUrl).Infof("upgrade success")
}
}
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 {
logrus.Errorf("upgrade %s failed: %v", version, err)
versionUrl, err := upgrade(url)
if err != nil {
logrus.WithField("url", url).Errorf("upgrade failed: %v", err)
return
}
logrus.Infof("upgrade %s success", version)
logrus.WithField("url", versionUrl).Infof("upgrade success")
}
func parseUrl(url string) (owner, repo string) {
@ -82,9 +99,13 @@ func getCommitID(url string) (string, error) {
Page: 0,
PerPage: 1,
})
if len(tags) == 0 && err != nil {
logrus.Warnf("get tag info failed: %v, start get commit id", err)
if err != nil {
logrus.WithField("url", url).Warnf("get tag info failed: %v, start get commit id", err)
}
if len(tags) != 0 {
return tags[0].GetName(), nil
}
// get latest commit id
commits, _, err := client.Repositories.ListCommits(ctx, owner, repo, &github.CommitsListOptions{
ListOptions: github.ListOptions{
Page: 0,
@ -92,6 +113,7 @@ func getCommitID(url string) (string, error) {
},
})
if err != nil {
logrus.WithField("url", url).Errorf("get latest commit failed: %v", err)
return "", err
}
if len(commits) == 0 {

13
gomod_test.go Normal file
View File

@ -0,0 +1,13 @@
package gomod
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetTag(t *testing.T) {
value, err := getCommitID("https://github.com/spf13/cobra")
assert.NoError(t, err)
t.Log(value)
}