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 }