82 lines
2.1 KiB
Go
82 lines
2.1 KiB
Go
|
package git
|
||
|
|
||
|
import (
|
||
|
"regexp"
|
||
|
"strconv"
|
||
|
"sync"
|
||
|
|
||
|
"github.com/git-lfs/git-lfs/subprocess"
|
||
|
"github.com/rubyist/tracerx"
|
||
|
)
|
||
|
|
||
|
var (
|
||
|
gitVersion *string
|
||
|
gitVersionMu sync.Mutex
|
||
|
)
|
||
|
|
||
|
func Version() (string, error) {
|
||
|
gitVersionMu.Lock()
|
||
|
defer gitVersionMu.Unlock()
|
||
|
|
||
|
if gitVersion == nil {
|
||
|
v, err := subprocess.SimpleExec("git", "version")
|
||
|
gitVersion = &v
|
||
|
return v, err
|
||
|
}
|
||
|
|
||
|
return *gitVersion, nil
|
||
|
}
|
||
|
|
||
|
// 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 IsGitVersionAtLeast(ver string) bool {
|
||
|
gitver, err := Version()
|
||
|
if err != nil {
|
||
|
tracerx.Printf("Error getting git version: %v", err)
|
||
|
return false
|
||
|
}
|
||
|
return IsVersionAtLeast(gitver, ver)
|
||
|
}
|
||
|
|
||
|
// 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
|
||
|
}
|