From bc11caff94896c8c3f9a5c970a77470ed9beb83a Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Sat, 5 Sep 2020 18:42:58 +0200 Subject: [Vendor] Switch go-version lib (#12719) * vendor: switch from "mcuadros/go-version" to "hashicorp/go-version" * Adapt P1 * simplify * fix lint * adapt * fix lint & rm old code * no deadlock * rm RWMutex and check GoVersion only 1-time * Copyright header Co-authored-by: techknowlogick --- modules/git/command.go | 5 +-- modules/git/commit.go | 5 +-- modules/git/git.go | 87 ++++++++++++++++++++++++++++++++---------- modules/git/repo_attribute.go | 6 +-- modules/git/repo_commit.go | 3 +- modules/git/repo_tag.go | 3 -- modules/git/repo_tree.go | 8 ++-- modules/repofiles/temp_repo.go | 12 +++--- modules/repository/init.go | 7 ++-- modules/setting/git.go | 10 ++--- modules/setting/setting.go | 5 +-- 11 files changed, 90 insertions(+), 61 deletions(-) (limited to 'modules') diff --git a/modules/git/command.go b/modules/git/command.go index 2a00a0a203..e0170b1723 100644 --- a/modules/git/command.go +++ b/modules/git/command.go @@ -1,3 +1,4 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. // Copyright 2015 The Gogs Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. @@ -11,12 +12,10 @@ import ( "io" "os" "os/exec" - "runtime" "strings" "time" "code.gitea.io/gitea/modules/process" - "github.com/mcuadros/go-version" ) var ( @@ -132,7 +131,7 @@ func (c *Command) RunInDirTimeoutEnvFullPipelineFunc(env []string, timeout time. } // TODO: verify if this is still needed in golang 1.15 - if version.Compare(runtime.Version(), "go1.15", "<") { + if goVersionLessThan115 { cmd.Env = append(cmd.Env, "GODEBUG=asyncpreemptoff=1") } cmd.Dir = dir diff --git a/modules/git/commit.go b/modules/git/commit.go index 2ae35c9f58..6d2bc2b02c 100644 --- a/modules/git/commit.go +++ b/modules/git/commit.go @@ -21,7 +21,6 @@ import ( "strings" "github.com/go-git/go-git/v5/plumbing/object" - "github.com/mcuadros/go-version" ) // Commit represents a git commit. @@ -470,7 +469,7 @@ func (c *Commit) GetSubModule(entryname string) (*SubModule, error) { // GetBranchName gets the closest branch name (as returned by 'git name-rev --name-only') func (c *Commit) GetBranchName() (string, error) { - binVersion, err := BinVersion() + err := LoadGitVersion() if err != nil { return "", fmt.Errorf("Git version missing: %v", err) } @@ -478,7 +477,7 @@ func (c *Commit) GetBranchName() (string, error) { args := []string{ "name-rev", } - if version.Compare(binVersion, "2.13.0", ">=") { + if CheckGitVersionConstraint(">= 2.13.0") == nil { args = append(args, "--exclude", "refs/tags/*") } args = append(args, "--name-only", "--no-undefined", c.ID.String()) diff --git a/modules/git/git.go b/modules/git/git.go index 1061bdb0d5..a9ff923cc5 100644 --- a/modules/git/git.go +++ b/modules/git/git.go @@ -15,14 +15,9 @@ import ( "code.gitea.io/gitea/modules/process" - "github.com/mcuadros/go-version" + "github.com/hashicorp/go-version" ) -// Version return this package's current version -func Version() string { - return "0.4.2" -} - var ( // Debug enables verbose logging on everything. // This should be false in case Gogs starts in SSH mode. @@ -39,7 +34,10 @@ var ( // DefaultContext is the default context to run git commands in DefaultContext = context.Background() - gitVersion string + gitVersion *version.Version + + // will be checked on Init + goVersionLessThan115 = true ) func log(format string, args ...interface{}) { @@ -55,31 +53,43 @@ func log(format string, args ...interface{}) { } } -// BinVersion returns current Git version from shell. -func BinVersion() (string, error) { - if len(gitVersion) > 0 { - return gitVersion, nil +// LocalVersion returns current Git version from shell. +func LocalVersion() (*version.Version, error) { + if err := LoadGitVersion(); err != nil { + return nil, err + } + return gitVersion, nil +} + +// LoadGitVersion returns current Git version from shell. +func LoadGitVersion() error { + // doesn't need RWMutex because its exec by Init() + if gitVersion != nil { + return nil } stdout, err := NewCommand("version").Run() if err != nil { - return "", err + return err } fields := strings.Fields(stdout) if len(fields) < 3 { - return "", fmt.Errorf("not enough output: %s", stdout) + return fmt.Errorf("not enough output: %s", stdout) } + var versionString string + // Handle special case on Windows. i := strings.Index(fields[2], "windows") if i >= 1 { - gitVersion = fields[2][:i-1] - return gitVersion, nil + versionString = fields[2][:i-1] + } else { + versionString = fields[2] } - gitVersion = fields[2] - return gitVersion, nil + gitVersion, err = version.NewVersion(versionString) + return err } // SetExecutablePath changes the path of git executable and checks the file permission and version. @@ -94,11 +104,17 @@ func SetExecutablePath(path string) error { } GitExecutable = absPath - gitVersion, err := BinVersion() + err = LoadGitVersion() if err != nil { return fmt.Errorf("Git version missing: %v", err) } - if version.Compare(gitVersion, GitVersionRequired, "<") { + + versionRequired, err := version.NewVersion(GitVersionRequired) + if err != nil { + return err + } + + if gitVersion.LessThan(versionRequired) { return fmt.Errorf("Git version not supported. Requires version > %v", GitVersionRequired) } @@ -108,6 +124,20 @@ func SetExecutablePath(path string) error { // Init initializes git module func Init(ctx context.Context) error { DefaultContext = ctx + + // Save current git version on init to gitVersion otherwise it would require an RWMutex + if err := LoadGitVersion(); err != nil { + return err + } + + // Save if the go version used to compile gitea is greater or equal 1.15 + runtimeVersion, err := version.NewVersion(strings.TrimPrefix(runtime.Version(), "go")) + if err != nil { + return err + } + version115, _ := version.NewVersion("1.15") + goVersionLessThan115 = runtimeVersion.LessThan(version115) + // Git requires setting user.name and user.email in order to commit changes - if they're not set just add some defaults for configKey, defaultValue := range map[string]string{"user.name": "Gitea", "user.email": "gitea@fake.local"} { if err := checkAndSetConfig(configKey, defaultValue, false); err != nil { @@ -120,13 +150,13 @@ func Init(ctx context.Context) error { return err } - if version.Compare(gitVersion, "2.10", ">=") { + if CheckGitVersionConstraint(">= 2.10") == nil { if err := checkAndSetConfig("receive.advertisePushOptions", "true", true); err != nil { return err } } - if version.Compare(gitVersion, "2.18", ">=") { + if CheckGitVersionConstraint(">= 2.18") == nil { if err := checkAndSetConfig("core.commitGraph", "true", true); err != nil { return err } @@ -143,6 +173,21 @@ func Init(ctx context.Context) error { return nil } +// CheckGitVersionConstraint check version constrain against local installed git version +func CheckGitVersionConstraint(constraint string) error { + if err := LoadGitVersion(); err != nil { + return err + } + check, err := version.NewConstraint(constraint) + if err != nil { + return err + } + if !check.Check(gitVersion) { + return fmt.Errorf("installed git binary %s does not satisfy version constraint %s", gitVersion.Original(), constraint) + } + return nil +} + func checkAndSetConfig(key, defaultValue string, forceToDefault bool) error { stdout, stderr, err := process.GetManager().Exec("git.Init(get setting)", GitExecutable, "config", "--get", key) if err != nil { diff --git a/modules/git/repo_attribute.go b/modules/git/repo_attribute.go index c10c96f558..7522b0dc82 100644 --- a/modules/git/repo_attribute.go +++ b/modules/git/repo_attribute.go @@ -7,8 +7,6 @@ package git import ( "bytes" "fmt" - - "github.com/mcuadros/go-version" ) // CheckAttributeOpts represents the possible options to CheckAttribute @@ -21,7 +19,7 @@ type CheckAttributeOpts struct { // CheckAttribute return the Blame object of file func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[string]string, error) { - binVersion, err := BinVersion() + err := LoadGitVersion() if err != nil { return nil, fmt.Errorf("Git version missing: %v", err) } @@ -42,7 +40,7 @@ func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[ } // git check-attr --cached first appears in git 1.7.8 - if opts.CachedOnly && version.Compare(binVersion, "1.7.8", ">=") { + if opts.CachedOnly && CheckGitVersionConstraint(">= 1.7.8") == nil { cmdArgs = append(cmdArgs, "--cached") } diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go index 4f04b2d363..45745c8088 100644 --- a/modules/git/repo_commit.go +++ b/modules/git/repo_commit.go @@ -14,7 +14,6 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" - "github.com/mcuadros/go-version" ) // GetRefCommitID returns the last commit ID string of given reference (branch or tag). @@ -470,7 +469,7 @@ func (repo *Repository) getCommitsBeforeLimit(id SHA1, num int) (*list.List, err } func (repo *Repository) getBranches(commit *Commit, limit int) ([]string, error) { - if version.Compare(gitVersion, "2.7.0", ">=") { + if CheckGitVersionConstraint(">= 2.7.0") == nil { stdout, err := NewCommand("for-each-ref", "--count="+strconv.Itoa(limit), "--format=%(refname:strip=2)", "--contains", commit.ID.String(), BranchPrefix).RunInDir(repo.Path) if err != nil { return nil, err diff --git a/modules/git/repo_tag.go b/modules/git/repo_tag.go index 7780e3477d..376a699502 100644 --- a/modules/git/repo_tag.go +++ b/modules/git/repo_tag.go @@ -10,7 +10,6 @@ import ( "strings" "github.com/go-git/go-git/v5/plumbing" - "github.com/mcuadros/go-version" ) // TagPrefix tags prefix path on the repository @@ -239,8 +238,6 @@ func (repo *Repository) GetTags() ([]string, error) { return nil }) - version.Sort(tagNames) - // Reverse order for i := 0; i < len(tagNames)/2; i++ { j := len(tagNames) - i - 1 diff --git a/modules/git/repo_tree.go b/modules/git/repo_tree.go index 8f91f4efac..a662aaab4f 100644 --- a/modules/git/repo_tree.go +++ b/modules/git/repo_tree.go @@ -11,8 +11,6 @@ import ( "os" "strings" "time" - - "github.com/mcuadros/go-version" ) func (repo *Repository) getTree(id SHA1) (*Tree, error) { @@ -65,7 +63,7 @@ type CommitTreeOpts struct { // CommitTree creates a commit from a given tree id for the user with provided message func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOpts) (SHA1, error) { - binVersion, err := BinVersion() + err := LoadGitVersion() if err != nil { return SHA1{}, err } @@ -91,11 +89,11 @@ func (repo *Repository) CommitTree(sig *Signature, tree *Tree, opts CommitTreeOp _, _ = messageBytes.WriteString(opts.Message) _, _ = messageBytes.WriteString("\n") - if version.Compare(binVersion, "1.7.9", ">=") && (opts.KeyID != "" || opts.AlwaysSign) { + if CheckGitVersionConstraint(">= 1.7.9") == nil && (opts.KeyID != "" || opts.AlwaysSign) { cmd.AddArguments(fmt.Sprintf("-S%s", opts.KeyID)) } - if version.Compare(binVersion, "2.0.0", ">=") && opts.NoGPGSign { + if CheckGitVersionConstraint(">= 2.0.0") == nil && opts.NoGPGSign { cmd.AddArguments("--no-gpg-sign") } diff --git a/modules/repofiles/temp_repo.go b/modules/repofiles/temp_repo.go index 2b03db8b4a..ec671a9322 100644 --- a/modules/repofiles/temp_repo.go +++ b/modules/repofiles/temp_repo.go @@ -19,8 +19,6 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/services/gitdiff" - - "github.com/mcuadros/go-version" ) // TemporaryUploadRepository is a type to wrap our upload repositories as a shallow clone @@ -196,7 +194,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *models authorSig := author.NewGitSig() committerSig := committer.NewGitSig() - binVersion, err := git.BinVersion() + err := git.LoadGitVersion() if err != nil { return "", fmt.Errorf("Unable to get git version: %v", err) } @@ -218,11 +216,11 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *models args := []string{"commit-tree", treeHash, "-p", "HEAD"} // Determine if we should sign - if version.Compare(binVersion, "1.7.9", ">=") { + if git.CheckGitVersionConstraint(">= 1.7.9") == nil { sign, keyID, _ := t.repo.SignCRUDAction(author, t.basePath, "HEAD") if sign { args = append(args, "-S"+keyID) - } else if version.Compare(binVersion, "2.0.0", ">=") { + } else if git.CheckGitVersionConstraint(">= 2.0.0") == nil { args = append(args, "--no-gpg-sign") } } @@ -309,7 +307,7 @@ func (t *TemporaryUploadRepository) DiffIndex() (*gitdiff.Diff, error) { // CheckAttribute checks the given attribute of the provided files func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...string) (map[string]map[string]string, error) { - binVersion, err := git.BinVersion() + err := git.LoadGitVersion() if err != nil { log.Error("Error retrieving git version: %v", err) return nil, err @@ -321,7 +319,7 @@ func (t *TemporaryUploadRepository) CheckAttribute(attribute string, args ...str cmdArgs := []string{"check-attr", "-z", attribute} // git check-attr --cached first appears in git 1.7.8 - if version.Compare(binVersion, "1.7.8", ">=") { + if git.CheckGitVersionConstraint(">= 1.7.8") == nil { cmdArgs = append(cmdArgs, "--cached") } cmdArgs = append(cmdArgs, "--") diff --git a/modules/repository/init.go b/modules/repository/init.go index 8c8827c511..c2038e18d4 100644 --- a/modules/repository/init.go +++ b/modules/repository/init.go @@ -19,7 +19,6 @@ import ( "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" - "github.com/mcuadros/go-version" "github.com/unknwon/com" ) @@ -122,7 +121,7 @@ func initRepoCommit(tmpPath string, repo *models.Repository, u *models.User, def return fmt.Errorf("git add --all: %v", err) } - binVersion, err := git.BinVersion() + err = git.LoadGitVersion() if err != nil { return fmt.Errorf("Unable to get git version: %v", err) } @@ -132,11 +131,11 @@ func initRepoCommit(tmpPath string, repo *models.Repository, u *models.User, def "-m", "Initial commit", } - if version.Compare(binVersion, "1.7.9", ">=") { + if git.CheckGitVersionConstraint(">= 1.7.9") == nil { sign, keyID, _ := models.SignInitialCommit(tmpPath, u) if sign { args = append(args, "-S"+keyID) - } else if version.Compare(binVersion, "2.0.0", ">=") { + } else if git.CheckGitVersionConstraint(">= 2.0.0") == nil { args = append(args, "--no-gpg-sign") } } diff --git a/modules/setting/git.go b/modules/setting/git.go index f83758f387..9136ea7f17 100644 --- a/modules/setting/git.go +++ b/modules/setting/git.go @@ -9,8 +9,6 @@ import ( "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" - - version "github.com/mcuadros/go-version" ) var ( @@ -71,20 +69,20 @@ func newGit() { } git.DefaultCommandExecutionTimeout = time.Duration(Git.Timeout.Default) * time.Second - binVersion, err := git.BinVersion() + version, err := git.LocalVersion() if err != nil { log.Fatal("Error retrieving git version: %v", err) } - if version.Compare(binVersion, "2.9", ">=") { + if git.CheckGitVersionConstraint(">= 2.9") == nil { // Explicitly disable credential helper, otherwise Git credentials might leak git.GlobalCommandArgs = append(git.GlobalCommandArgs, "-c", "credential.helper=") } var format = "Git Version: %s" - var args = []interface{}{binVersion} + var args = []interface{}{version.Original()} // Since git wire protocol has been released from git v2.18 - if Git.EnableAutoGitWireProtocol && version.Compare(binVersion, "2.18", ">=") { + if Git.EnableAutoGitWireProtocol && git.CheckGitVersionConstraint(">= 2.18") == nil { git.GlobalCommandArgs = append(git.GlobalCommandArgs, "-c", "protocol.version=2") format += ", Wire Protocol %s Enabled" args = append(args, "Version 2") // for focus color diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 5b8aefdaa4..8449851efb 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -28,7 +28,6 @@ import ( "code.gitea.io/gitea/modules/user" shellquote "github.com/kballard/go-shellquote" - version "github.com/mcuadros/go-version" "github.com/unknwon/com" ini "gopkg.in/ini.v1" "strk.kbt.io/projects/go/libravatar" @@ -479,12 +478,12 @@ func CheckLFSVersion() { //Disable LFS client hooks if installed for the current OS user //Needs at least git v2.1.2 - binVersion, err := git.BinVersion() + err := git.LoadGitVersion() if err != nil { log.Fatal("Error retrieving git version: %v", err) } - if !version.Compare(binVersion, "2.1.2", ">=") { + if git.CheckGitVersionConstraint(">= 2.1.2") != nil { LFS.StartServer = false log.Error("LFS server support needs at least Git v2.1.2") } else { -- cgit v1.2.3