From a9a62fe9761fa11a81f1f341efe7510151e712c4 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Thu, 8 Oct 2015 17:40:38 +0100 Subject: [PATCH] Add utility functions for testing git version --- git/git.go | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ git/git_test.go | 13 ++++++++++++ 2 files changed, 66 insertions(+) diff --git a/git/git.go b/git/git.go index c28160c0..5178a1eb 100644 --- a/git/git.go +++ b/git/git.go @@ -8,6 +8,7 @@ import ( "os" "os/exec" "regexp" + "strconv" "strings" "time" @@ -183,6 +184,17 @@ func (c *gitConfig) Version() (string, error) { return simpleExec("git", "version") } +// IsVersionAtLeast returns whether the git version is the one specified or higher +// argument is plain version string separated by '.' e.g. "2.3.1" but can omit minor/patch +func (c *gitConfig) IsGitVersionAtLeast(ver string) bool { + gitver, err := c.Version() + if err != nil { + tracerx.Printf("Error getting git version: %v", err) + return false + } + return IsVersionAtLeast(gitver, ver) +} + // simpleExec is a small wrapper around os/exec.Command. func simpleExec(name string, args ...string) (string, error) { tracerx.Printf("run_command: '%s' %s", name, strings.Join(args, " ")) @@ -340,3 +352,44 @@ func GetCommitSummary(commit string) (*CommitSummary, error) { } } +// IsVersionAtLeast compares 2 version strings (ok to be prefixed with 'git version', ignores) +func IsVersionAtLeast(actualVersion, desiredVersion string) bool { + // Capture 1-3 version digits, optionally prefixed with 'git version' and possibly + // with suffixes which we'll ignore (e.g. unstable builds, MinGW versions) + verregex := regexp.MustCompile(`(?:git version\s+)?(\d+)(?:.(\d+))?(?:.(\d+))?.*`) + + var atleast uint64 + // Support up to 1000 in major/minor/patch digits + const majorscale = 1000 * 1000 + const minorscale = 1000 + + if match := verregex.FindStringSubmatch(desiredVersion); match != nil { + // Ignore errors as regex won't match anything other than digits + major, _ := strconv.Atoi(match[1]) + atleast += uint64(major * majorscale) + if len(match) > 2 { + minor, _ := strconv.Atoi(match[2]) + atleast += uint64(minor * minorscale) + } + if len(match) > 3 { + patch, _ := strconv.Atoi(match[3]) + atleast += uint64(patch) + } + } + + var actual uint64 + if match := verregex.FindStringSubmatch(actualVersion); match != nil { + major, _ := strconv.Atoi(match[1]) + actual += uint64(major * majorscale) + if len(match) > 2 { + minor, _ := strconv.Atoi(match[2]) + actual += uint64(minor * minorscale) + } + if len(match) > 3 { + patch, _ := strconv.Atoi(match[3]) + actual += uint64(patch) + } + } + + return actual >= atleast +} diff --git a/git/git_test.go b/git/git_test.go index bbec2a67..55fb971a 100644 --- a/git/git_test.go +++ b/git/git_test.go @@ -184,3 +184,16 @@ func TestResolveEmptyCurrentRef(t *testing.T) { _, err := CurrentRef() assert.NotEqual(t, nil, err) } +func TestVersionCompare(t *testing.T) { + + assert.Equal(t, true, IsVersionAtLeast("2.6.0", "2.6.0")) + assert.Equal(t, true, IsVersionAtLeast("2.6.0", "2.6")) + assert.Equal(t, true, IsVersionAtLeast("2.6.0", "2")) + assert.Equal(t, true, IsVersionAtLeast("2.6.10", "2.6.5")) + assert.Equal(t, true, IsVersionAtLeast("2.8.1", "2.7.2")) + + assert.Equal(t, false, IsVersionAtLeast("1.6.0", "2")) + assert.Equal(t, false, IsVersionAtLeast("2.5.0", "2.6")) + assert.Equal(t, false, IsVersionAtLeast("2.5.0", "2.5.1")) + assert.Equal(t, false, IsVersionAtLeast("2.5.2", "2.5.10")) +}