diff --git a/cmd/protobuild/cmd.go b/cmd/protobuild/cmd.go index d2767b4..b408cc9 100644 --- a/cmd/protobuild/cmd.go +++ b/cmd/protobuild/cmd.go @@ -30,9 +30,6 @@ import ( "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/pluginpb" yaml "gopkg.in/yaml.v3" - - _ "github.com/samber/lo" - _ "golang.org/x/mod/module" ) var ( @@ -334,8 +331,8 @@ func Main() *cli.Command { var changed bool - // 解析go.mod并获取所有pkg版本 - versions := modutil.LoadVersions() + // 通过 go mod graph 获取每个 pkg 最大版本 + versions := modutil.LoadVersionGraph() for i, dep := range globalCfg.Depends { pathVersion := strings.SplitN(dep.Url, "@", 2) if len(pathVersion) == 2 { @@ -357,7 +354,7 @@ func Main() *cli.Command { v := strutil.FirstFnNotEmpty(func() string { return versions[url] }, func() string { - return generic.DePtr(dep.Version) + return generic.FromPtr(dep.Version) }, func() string { // go.mod中version不存在, 并且protobuf.yaml也没有指定 // go pkg缓存 diff --git a/docs/docs.go b/docs/docs.go index cc8e61e..3b3f1e0 100644 --- a/docs/docs.go +++ b/docs/docs.go @@ -5,3 +5,8 @@ package docs // https://github.com/bufbuild/protocompile // https://github.com/mitchellh/protoc-gen-go-json // https://github.com/foxygoat/protog/tree/master/httprule + +import ( + _ "github.com/samber/lo" + _ "golang.org/x/mod/module" +) diff --git a/internal/modutil/util.go b/internal/modutil/util.go index 74bc758..920e48b 100644 --- a/internal/modutil/util.go +++ b/internal/modutil/util.go @@ -4,9 +4,15 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" + mapset "github.com/deckarep/golang-set/v2" + ver "github.com/hashicorp/go-version" "github.com/pubgo/funk/assert" "github.com/pubgo/funk/pathutil" + "github.com/pubgo/funk/v2/result" + "github.com/pubgo/protobuild/internal/shutil" + "github.com/samber/lo" "golang.org/x/mod/modfile" ) @@ -28,6 +34,35 @@ func GoModPath() string { return getFileByRecursion("go.mod", pwd) } +func LoadVersionGraph() map[string]string { + modList := strings.Split(result.Wrap(shutil.GoModGraph()).Must(), "\n") + modSet := mapset.NewSet[string]() + for _, m := range modList { + for _, v := range strings.Split(m, " ") { + modSet.Add(strings.TrimSpace(v)) + } + } + + var modMap = make(map[string][]*ver.Version) + modSet.Each(func(s string) bool { + ver2 := strings.Split(s, "@") + if len(ver2) != 2 { + return false + } + + if !strings.HasPrefix(ver2[1], "v") { + return false + } + + modMap[ver2[0]] = append(modMap[ver2[0]], ver.Must(ver.NewSemver(ver2[1]))) + return false + }) + + return lo.MapValues(modMap, func(versions []*ver.Version, path string) string { + return "v" + maxVersion(versions).String() + }) +} + func LoadVersions() map[string]string { path := GoModPath() assert.Assert(path == "", "go.mod not exists") @@ -51,3 +86,7 @@ func LoadVersions() map[string]string { return versions } + +func maxVersion(versions []*ver.Version) *ver.Version { + return lo.MaxBy(versions, func(a *ver.Version, b *ver.Version) bool { return a.GreaterThan(b) }) +} diff --git a/internal/modutil/util_test.go b/internal/modutil/util_test.go new file mode 100644 index 0000000..68345f8 --- /dev/null +++ b/internal/modutil/util_test.go @@ -0,0 +1,47 @@ +package modutil + +import ( + mapset "github.com/deckarep/golang-set/v2" + ver "github.com/hashicorp/go-version" + "github.com/pubgo/funk/pretty" + "github.com/pubgo/funk/v2/result" + "github.com/pubgo/protobuild/internal/shutil" + "github.com/samber/lo" + "strings" + "testing" +) + +func TestName(t *testing.T) { + pretty.Println(LoadVersions()) + + modList := strings.Split(result.Wrap(shutil.GoModGraph()).Must(), "\n") + modSet := mapset.NewSet[string]() + for _, m := range modList { + for _, v := range strings.Split(m, " ") { + modSet.Add(strings.TrimSpace(v)) + } + } + + var modMap = make(map[string][]*ver.Version) + modSet.Each(func(s string) bool { + ver2 := strings.Split(s, "@") + if len(ver2) != 2 { + return false + } + + if !strings.HasPrefix(ver2[1], "v") { + return false + } + + modMap[ver2[0]] = append(modMap[ver2[0]], ver.Must(ver.NewSemver(ver2[1]))) + return false + }) + + for k, v := range modMap { + pretty.Println(k, maxVersion(v).String(), minVersion(v).String()) + } +} + +func minVersion(versions []*ver.Version) *ver.Version { + return lo.MaxBy(versions, func(a *ver.Version, b *ver.Version) bool { return !a.GreaterThan(b) }) +}