From 7b2c0762d4cacb428328236b3b097cce7b9af4f1 Mon Sep 17 00:00:00 2001 From: storyicon Date: Sun, 1 Aug 2021 17:11:54 +0800 Subject: [PATCH] ref(git): replace git's native -sort with a thrid-party function Signed-off-by: storyicon --- go.mod | 7 ++++ go.sum | 15 +++++++- pkg/component/pluginmanager/git.go | 27 ++------------ pkg/component/pluginmanager/manager.go | 32 +--------------- .../pluginmanager/pluginmanager_test.go | 7 +--- pkg/util/util.go | 32 +++++++++++++++- pkg/util/util_test.go | 37 ++++++++++++++++++- 7 files changed, 95 insertions(+), 62 deletions(-) diff --git a/go.mod b/go.mod index de91d65..2e5db01 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,14 @@ go 1.16 require ( github.com/AlecAivazis/survey/v2 v2.2.14 github.com/bmatcuk/doublestar v1.3.4 + github.com/coreos/go-semver v0.3.0 github.com/dsnet/compress v0.0.1 // indirect github.com/fatih/color v1.12.0 github.com/frankban/quicktest v1.13.0 // indirect + github.com/gogo/protobuf v1.3.2 + github.com/golang/protobuf v1.5.2 github.com/golang/snappy v0.0.4 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 github.com/hashicorp/go-multierror v1.0.0 github.com/json-iterator/go v1.1.11 github.com/mattn/go-isatty v0.0.13 // indirect @@ -27,6 +31,9 @@ require ( golang.org/x/mod v0.4.2 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c // indirect golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b // indirect + google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced + google.golang.org/grpc v1.38.0 + google.golang.org/protobuf v1.26.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b ) diff --git a/go.sum b/go.sum index 3cf7057..07eb423 100644 --- a/go.sum +++ b/go.sum @@ -74,6 +74,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -112,8 +113,11 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v0.0.0-20210429001901-424d2337a529 h1:2voWjNECnrZRbfwXxHB1/j8wa6xdKn85B5NzgVL/pTU= +github.com/golang/glog v0.0.0-20210429001901-424d2337a529/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -157,8 +161,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -179,7 +184,10 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0 h1:ajue7SzQMywqRjg2fK7dcpc0QhFGpTR2plWfV4EZWR4= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.5.0/go.mod h1:r1hZAcvfFXuYmcKyCJI9wlyOPIZUJl6FCB8Cpca/NLE= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= @@ -479,6 +487,7 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210615190721-d04028783cf1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -618,6 +627,7 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -693,6 +703,8 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced h1:c5geK1iMU3cDKtFrCVQIcjR3W+JOZMuhIyICMCTbtus= +google.golang.org/genproto v0.0.0-20210617175327-b9e0b3197ced/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -712,6 +724,7 @@ google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA5 google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.38.0 h1:/9BgsAsa5nWe26HqOlvlgJnqBuktYOLCgjCPqsa56W0= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/pkg/component/pluginmanager/git.go b/pkg/component/pluginmanager/git.go index 39abef1..31516da 100644 --- a/pkg/component/pluginmanager/git.go +++ b/pkg/component/pluginmanager/git.go @@ -24,6 +24,7 @@ import ( "strings" "github.com/mholt/archiver" + "github.com/storyicon/powerproto/pkg/util" "github.com/storyicon/powerproto/pkg/util/command" "github.com/storyicon/powerproto/pkg/util/logger" @@ -53,31 +54,10 @@ func GetGitLatestCommitId(ctx context.Context, log logger.Logger, repo string) ( return f[0], nil } -// ListGitCommitIds is used to list git commit ids -func ListGitCommitIds(ctx context.Context, log logger.Logger, repo string) ([]string, error) { - data, err := command.Execute(ctx, log, "", "git", []string{ - "ls-remote", repo, - }, nil) - if err != nil { - return nil, &ErrGitList{ - ErrCommandExec: err.(*command.ErrCommandExec), - } - } - var commitIds []string - for _, line := range strings.Split(string(data), "\n") { - f := strings.Fields(line) - if len(f) != 2 { - continue - } - commitIds = append(commitIds, f[0]) - } - return commitIds, nil -} - // ListGitTags is used to list the git tags of specified repository func ListGitTags(ctx context.Context, log logger.Logger, repo string) ([]string, error) { data, err := command.Execute(ctx, log, "", "git", []string{ - "ls-remote", "--tags", "--refs", "--sort", "version:refname", repo, + "ls-remote", "--tags", "--refs", repo, }, nil) if err != nil { return nil, &ErrGitList{ @@ -94,7 +74,8 @@ func ListGitTags(ctx context.Context, log logger.Logger, repo string) ([]string, tags = append(tags, strings.TrimPrefix(f[1], "refs/tags/")) } } - return tags, nil + malformed, wellFormed := util.SortSemanticVersion(tags) + return append(malformed, wellFormed...), nil } // GithubArchive is github archive diff --git a/pkg/component/pluginmanager/manager.go b/pkg/component/pluginmanager/manager.go index fc9c2c6..e447827 100644 --- a/pkg/component/pluginmanager/manager.go +++ b/pkg/component/pluginmanager/manager.go @@ -45,8 +45,6 @@ type PluginManager interface { GetGitRepoLatestVersion(ctx context.Context, uri string) (string, error) // InstallGitRepo is used to install google apis InstallGitRepo(ctx context.Context, uri string, commitId string) (local string, err error) - // ListGitRepoVersions is used to list protoc version - ListGitRepoVersions(ctx context.Context, uri string) ([]string, error) // IsGitRepoInstalled is used to check whether the protoc is installed IsGitRepoInstalled(ctx context.Context, uri string, commitId string) (bool, string, error) // GitRepoPath returns the googleapis path @@ -143,14 +141,7 @@ func (b *BasicPluginManager) InstallPlugin(ctx context.Context, path string, ver // GetGitRepoLatestVersion is used to get the latest version of google apis func (b *BasicPluginManager) GetGitRepoLatestVersion(ctx context.Context, url string) (string, error) { - versions, err := b.ListGitRepoVersions(ctx, url) - if err != nil { - return "", err - } - if len(versions) == 0 { - return "", errors.New("no version list") - } - return versions[len(versions)-1], nil + return GetGitLatestCommitId(ctx, b.Logger, url) } // InstallGitRepo is used to install google apis @@ -180,27 +171,6 @@ func (b *BasicPluginManager) InstallGitRepo(ctx context.Context, uri string, com return local, nil } -// ListGitRepoVersions is used to list protoc version -func (b *BasicPluginManager) ListGitRepoVersions(ctx context.Context, uri string) ([]string, error) { - ctx, cancel := context.WithTimeout(ctx, defaultExecuteTimeout) - defer cancel() - - b.versionsLock.RLock() - versions, ok := b.versions[uri] - b.versionsLock.RUnlock() - if ok { - return versions, nil - } - versions, err := ListGitCommitIds(ctx, b.Logger, uri) - if err != nil { - return nil, err - } - b.versionsLock.Lock() - b.versions[uri] = versions - b.versionsLock.Unlock() - return versions, nil -} - // IsGitRepoInstalled is used to check whether the protoc is installed func (b *BasicPluginManager) IsGitRepoInstalled(ctx context.Context, uri string, commitId string) (bool, string, error) { codePath, err := PathForGitReposCode(b.storageDir, uri, commitId) diff --git a/pkg/component/pluginmanager/pluginmanager_test.go b/pkg/component/pluginmanager/pluginmanager_test.go index dad75ba..d914883 100644 --- a/pkg/component/pluginmanager/pluginmanager_test.go +++ b/pkg/component/pluginmanager/pluginmanager_test.go @@ -25,7 +25,7 @@ import ( "github.com/storyicon/powerproto/pkg/util/logger" ) -var _ = Describe("Pluginmanager", func() { +var _ = Describe("PluginManager", func() { cfg := pluginmanager.NewConfig() cfg.StorageDir, _ = filepath.Abs("./tests") @@ -72,12 +72,9 @@ var _ = Describe("Pluginmanager", func() { }) It("should able to install git repos", func() { const uri = "https://github.com/gogo/protobuf" - versions, err := manager.ListGitRepoVersions(context.TODO(), uri) - Expect(err).To(BeNil()) - Expect(len(versions) > 0).To(BeTrue()) latestVersion, err := manager.GetGitRepoLatestVersion(context.TODO(), uri) Expect(err).To(BeNil()) - Expect(latestVersion).To(Equal(versions[len(versions)-1])) + Expect(len(latestVersion) > 0).To(Equal(true)) local, err := manager.InstallGitRepo(context.TODO(), uri, latestVersion) Expect(err).To(BeNil()) diff --git a/pkg/util/util.go b/pkg/util/util.go index 823e5e6..cd958a0 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -20,11 +20,41 @@ import ( "path/filepath" "regexp" "runtime" + "sort" "strings" "syscall" + + "github.com/coreos/go-semver/semver" ) -// DeduplicateSlice is used to deduplicate slice items stably +// SortSemanticVersion is used to sort semantic version +func SortSemanticVersion(items []string) ([]string, []string) { + versionMap := make(map[*semver.Version]string, len(items)) + versions := make(semver.Versions, 0, len(items)) + var malformed []string + for _, item := range items { + s := item + if strings.HasPrefix(s, "v") { + s = item[1:] + } + version, err := semver.NewVersion(s) + if err != nil { + malformed = append(malformed, item) + continue + } + versionMap[version] = item + versions = append(versions, version) + } + sort.Sort(versions) + var data []string + for _, version := range versions { + data = append(data, versionMap[version]) + } + sort.Strings(malformed) + return malformed, data +} + +// DeduplicateSliceStably is used to deduplicate slice items stably func DeduplicateSliceStably(items []string) []string { data := make([]string, 0, len(items)) deduplicate := map[string]struct{}{} diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 53d82be..cdc341f 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -84,4 +84,39 @@ func TestDeduplicateSliceStably(t *testing.T) { } }) } -} \ No newline at end of file +} + +func TestSortSemanticVersion(t *testing.T) { + type args struct { + items []string + } + tests := []struct { + name string + args args + want []string + want1 []string + }{ + { + args: args{ + items: []string{ + "v3.0.0-beta-3.1", + "v3.0.0-alpha-2", + "3.15.0-rc1", "conformance-build-tag", "v2.4.1", + }, + }, + want: []string{"conformance-build-tag"}, + want1: []string{"v2.4.1", "v3.0.0-alpha-2", "v3.0.0-beta-3.1", "3.15.0-rc1"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, got1 := SortSemanticVersion(tt.args.items) + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("SortSemanticVersion() got = %v, want %v", got, tt.want) + } + if !reflect.DeepEqual(got1, tt.want1) { + t.Errorf("SortSemanticVersion() got1 = %v, want %v", got1, tt.want1) + } + }) + } +}