github.com/bshelton229/agent@v3.5.4+incompatible/bootstrap/git.go (about)

     1  package bootstrap
     2  
     3  import (
     4  	"fmt"
     5  	"net/url"
     6  	"path/filepath"
     7  	"regexp"
     8  	"strings"
     9  
    10  	"github.com/buildkite/agent/bootstrap/shell"
    11  	"github.com/buildkite/shellwords"
    12  )
    13  
    14  func gitClone(sh *shell.Shell, gitCloneFlags, repository, dir string) error {
    15  	individualCloneFlags, err := shellwords.Split(gitCloneFlags)
    16  	if err != nil {
    17  		return err
    18  	}
    19  
    20  	commandArgs := []string{"clone"}
    21  	commandArgs = append(commandArgs, individualCloneFlags...)
    22  	commandArgs = append(commandArgs, "--", repository, ".")
    23  
    24  	if err = sh.Run("git", commandArgs...); err != nil {
    25  		return err
    26  	}
    27  
    28  	return nil
    29  }
    30  
    31  func gitClean(sh *shell.Shell, gitCleanFlags string) error {
    32  	individualCleanFlags, err := shellwords.Split(gitCleanFlags)
    33  	if err != nil {
    34  		return err
    35  	}
    36  
    37  	commandArgs := []string{"clean"}
    38  	commandArgs = append(commandArgs, individualCleanFlags...)
    39  
    40  	if err = sh.Run("git", commandArgs...); err != nil {
    41  		return err
    42  	}
    43  
    44  	return nil
    45  }
    46  
    47  func gitCleanSubmodules(sh *shell.Shell, gitCleanFlags string) error {
    48  	individualCleanFlags, err := shellwords.Split(gitCleanFlags)
    49  	if err != nil {
    50  		return err
    51  	}
    52  
    53  	commandArgs := append([]string{"submodule", "foreach", "--recursive", "git", "clean"}, individualCleanFlags...)
    54  
    55  	if err = sh.Run("git", commandArgs...); err != nil {
    56  		return err
    57  	}
    58  
    59  	return nil
    60  }
    61  
    62  func gitFetch(sh *shell.Shell, gitFetchFlags, repository string, refSpec ...string) error {
    63  	individualFetchFlags, err := shellwords.Split(gitFetchFlags)
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	commandArgs := []string{"fetch"}
    69  	commandArgs = append(commandArgs, individualFetchFlags...)
    70  	commandArgs = append(commandArgs, repository)
    71  
    72  	for _, r := range refSpec {
    73  		individualRefSpecs, err := shellwords.Split(r)
    74  		if err != nil {
    75  			return err
    76  		}
    77  		commandArgs = append(commandArgs, individualRefSpecs...)
    78  	}
    79  
    80  	if err = sh.Run("git", commandArgs...); err != nil {
    81  		return err
    82  	}
    83  
    84  	return nil
    85  }
    86  
    87  func gitEnumerateSubmoduleURLs(sh *shell.Shell) ([]string, error) {
    88  	urls := []string{}
    89  
    90  	// The output of this command looks like:
    91  	// Entering 'vendor/docs'
    92  	// git@github.com:buildkite/docs.git
    93  	// Entering 'vendor/frontend'
    94  	// git@github.com:buildkite/frontend.git
    95  	// Entering 'vendor/frontend/vendor/emojis'
    96  	// git@github.com:buildkite/emojis.git
    97  	output, err := sh.RunAndCapture(
    98  		"git", "submodule", "foreach", "--recursive", "git", "ls-remote", "--get-url")
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  
   103  	// splits into "Entering" "'vendor/blah'" "git@github.com:blah/.."
   104  	// this should work for windows and unix line endings
   105  	for idx, val := range strings.Fields(output) {
   106  		// every third element to get the git@github.com:blah bit
   107  		if idx%3 == 2 {
   108  			urls = append(urls, val)
   109  		}
   110  	}
   111  
   112  	return urls, nil
   113  }
   114  
   115  func gitRevParseInWorkingDirectory(sh *shell.Shell, workingDirectory string, extraRevParseArgs ...string) (string, error) {
   116  	gitDirectory := filepath.Join(workingDirectory, ".git")
   117  
   118  	revParseArgs := []string{"--git-dir", gitDirectory, "--work-tree", workingDirectory, "rev-parse"}
   119  	revParseArgs = append(revParseArgs, extraRevParseArgs...)
   120  
   121  	return sh.RunAndCapture("git", revParseArgs...)
   122  }
   123  
   124  var (
   125  	hasSchemePattern  = regexp.MustCompile("^[^:]+://")
   126  	scpLikeURLPattern = regexp.MustCompile("^([^@]+@)?([^:]{2,}):/?(.+)$")
   127  )
   128  
   129  // parseGittableURL parses and converts a git repository url into a url.URL
   130  func parseGittableURL(ref string) (*url.URL, error) {
   131  	if !hasSchemePattern.MatchString(ref) {
   132  		if scpLikeURLPattern.MatchString(ref) {
   133  			matched := scpLikeURLPattern.FindStringSubmatch(ref)
   134  			user := matched[1]
   135  			host := matched[2]
   136  			path := matched[3]
   137  			ref = fmt.Sprintf("ssh://%s%s/%s", user, host, path)
   138  		} else {
   139  			normalizedRef := strings.Replace(ref, "\\", "/", -1)
   140  			ref = fmt.Sprintf("file:///%s", strings.TrimPrefix(normalizedRef, "/"))
   141  		}
   142  	}
   143  	return url.Parse(ref)
   144  }
   145  
   146  // Clean up the SSH host and remove any key identifiers. See:
   147  // git@github.com-custom-identifier:foo/bar.git
   148  // https://buildkite.com/docs/agent/ssh-keys#creating-multiple-ssh-keys
   149  var gitHostAliasRegexp = regexp.MustCompile(`-[a-z0-9\-]+$`)
   150  
   151  func stripAliasesFromGitHost(host string) string {
   152  	return gitHostAliasRegexp.ReplaceAllString(host, "")
   153  }