diff --git a/Makefile b/Makefile index 173334ceff..314d19cd27 100644 --- a/Makefile +++ b/Makefile @@ -17,10 +17,6 @@ export DOCKER_BUILD_FLAGS = .PHONY: test -.DEFAULT_GOAL := help -help: ## List targets & descriptions - @cat Makefile* | grep -E '^[a-zA-Z_-]+:.*?## .*$$' | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' - id: ## Output BUILD_ID being used @echo $(BUILD_ID) diff --git a/server/events/vcs/mocks/mock_proxy.go b/server/events/vcs/mocks/mock_proxy.go index 58a417b2d5..499e1cf4b7 100644 --- a/server/events/vcs/mocks/mock_proxy.go +++ b/server/events/vcs/mocks/mock_proxy.go @@ -74,6 +74,10 @@ func (mock *MockClientProxy) UpdateStatus(repo models.Repo, pull models.PullRequ return ret0 } +func (mock *MockClientProxy) GetTeamNamesForUser(repo models.Repo, user models.User) ([]string, error) { + return nil, nil +} + func (mock *MockClientProxy) VerifyWasCalledOnce() *VerifierClientProxy { return &VerifierClientProxy{mock, pegomock.Times(1), nil} } diff --git a/server/events/working_dir.go b/server/events/working_dir.go index 9d68020381..f9015da77b 100644 --- a/server/events/working_dir.go +++ b/server/events/working_dir.go @@ -17,9 +17,11 @@ import ( "os" "os/exec" "path/filepath" + "regexp" "strconv" "strings" + "github.com/Masterminds/semver" "github.com/cloudposse/atlantis/server/events/models" "github.com/cloudposse/atlantis/server/logging" "github.com/pkg/errors" @@ -89,6 +91,40 @@ func (w *FileWorkspace) Clone( return w.forceClone(log, cloneDir, headRepo, p) } +// GetGitVersion finds git version on the workstation +func GetGitVersion() (*semver.Version, error) { + gitVersionOutput, err := exec.Command("git", "version").CombinedOutput() + if err != nil { + return nil, err + } + r := regexp.MustCompile(`(?:git version)\s(\d+\.\d+\.\d+)`) + gitVersion := semver.MustParse(r.FindStringSubmatch(string(gitVersionOutput))[1]) + return gitVersion, nil +} + +// CreateGitCloneCommand checks git version and creates 'git clone' command with different arguments depending on git version +// https://stackoverflow.com/questions/3796927/how-to-git-clone-including-submodules/4438292#4438292 +func CreateGitCloneCommand(gitVersion *semver.Version, cloneURL string, cloneDir string) (*exec.Cmd, error) { + minimalGitVersion165, err := semver.NewConstraint(">= 1.6.5") + if err != nil { + return nil, errors.Wrap(err, "creating semver constraint for git version >= 1.6.5") + } + minimalGitVersion213, err := semver.NewConstraint(">= 2.13") + if err != nil { + return nil, errors.Wrap(err, "creating semver constraint for git version >= 2.13") + } + + var cloneCmd *exec.Cmd + if minimalGitVersion213.Check(gitVersion) { + cloneCmd = exec.Command("git", "clone", "--recurse-submodules", cloneURL, cloneDir) // #nosec + } else if minimalGitVersion165.Check(gitVersion) { + cloneCmd = exec.Command("git", "clone", "--recursive", cloneURL, cloneDir) // #nosec + } else { + cloneCmd = exec.Command("git", "clone", cloneURL, cloneDir) // #nosec + } + return cloneCmd, nil +} + func (w *FileWorkspace) forceClone(log *logging.SimpleLogger, cloneDir string, headRepo models.Repo, @@ -110,7 +146,17 @@ func (w *FileWorkspace) forceClone(log *logging.SimpleLogger, if w.TestingOverrideCloneURL != "" { cloneURL = w.TestingOverrideCloneURL } - cloneCmd := exec.Command("git", "clone", cloneURL, cloneDir) // #nosec + + gitVersion, err := GetGitVersion() + if err != nil { + return "", errors.Wrap(err, "git version") + } + + cloneCmd, err := CreateGitCloneCommand(gitVersion, cloneURL, cloneDir) + if err != nil { + return "", err + } + if output, err := cloneCmd.CombinedOutput(); err != nil { return "", errors.Wrapf(err, "cloning %s: %s", headRepo.SanitizedCloneURL, string(output)) } diff --git a/server/events/working_dir_test.go b/server/events/working_dir_test.go new file mode 100644 index 0000000000..ac909499a3 --- /dev/null +++ b/server/events/working_dir_test.go @@ -0,0 +1,21 @@ +package events_test + +import ( + "fmt" + "testing" + + "github.com/cloudposse/atlantis/server/events" + . "github.com/cloudposse/atlantis/testing" +) + +func TestCreateGitCloneCommand(t *testing.T) { + gitVersion, err := events.GetGitVersion() + Ok(t, err) + fmt.Printf("Found Git version: %s\n", gitVersion.String()) + + cloneCmd, err := events.CreateGitCloneCommand(gitVersion, "https://github.com/runatlantis/atlantis", "/tmp/runatlantis/atlantis") + Ok(t, err) + + Assert(t, cloneCmd != nil, "could not create 'git clone' command") + fmt.Printf("git clone arguments: %s\n", cloneCmd.Args) +}