github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/experiment/bootstrap/repos.go (about) 1 /* 2 Copyright 2017 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "fmt" 21 "regexp" 22 "strings" 23 ) 24 25 // Repo contains the components of git repo refs used in bootstrap 26 type Repo struct { 27 Name string 28 Branch string 29 Pull string 30 } 31 32 // utility method used below, checks a PULL_REFS for `:` 33 func refHasSHAs(ref string) bool { 34 return strings.Contains(ref, ":") 35 } 36 37 // GitBasePath returns the base git path associated with the repo, 38 // this does not include the branch or pull. 39 // If ssh is true this assumes git@ is the appropriate user. 40 // TODO(bentheelder): do we want to continue to assume git@ for ssh in the future? 41 // This works fine for GitHub and matches jenkins/bootstrap.py's `repository(..)` 42 func (r *Repo) GitBasePath(ssh bool) string { 43 // TODO(bentheelder): perhaps this should contain a map of known prefix 44 // replacements instead so that supporting other repos is easier? 45 path := r.Name 46 if strings.HasPrefix(path, "k8s.io/") { 47 path = "github.com/kubernetes/" + strings.TrimPrefix(path, "k8s.io/") 48 } 49 if ssh { 50 if !refHasSHAs(path) { 51 path = strings.Replace(path, "/", ":", 1) 52 } 53 return "git@" + path 54 } 55 return "https://" + path 56 } 57 58 // PullNumbers converts a Pull's list string into a slice of PR number strings 59 // NOTE: this assumes that if there are pull requests specified that Repo.Pull 60 // looks something like: `master:hash,prNum:hash,prNum:hash,...` 61 func (r *Repo) PullNumbers() []string { 62 if refHasSHAs(r.Pull) { 63 res := []string{} 64 parts := strings.Split(r.Pull, ",") 65 for _, part := range parts { 66 res = append(res, strings.Split(part, ":")[0]) 67 } 68 return res[1:] 69 } 70 return []string{} 71 } 72 73 // Repos is a slice of Repo where Repos[0] is the main repo 74 type Repos []Repo 75 76 // Main returns the primary repo in a Repos produced by ParseRepos 77 func (r Repos) Main() *Repo { 78 if len(r) == 0 { 79 return nil 80 } 81 return &r[0] 82 } 83 84 // ParseRepos converts the refs related arguments to []Repo 85 // each repoArgs is expect to be "name=branch:commit,branch:commit" 86 // with one or more comma separated "branch:commit". 87 // EG: "k8s.io/kubernetes=master:42e2ca8c18c93ba25eb0e5bd02ecba2eaa05e871,52057:b4f639f57ae0a89cdf1b43d1810b617c76f4b1b3" 88 func ParseRepos(repoArgs []string) (Repos, error) { 89 repos := []Repo{} 90 re := regexp.MustCompile(`([^=]+)(=([^:,~^\s]+(:[0-9a-fA-F]+)?(,|$))+)?$`) 91 for _, repoArg := range repoArgs { 92 match := re.FindStringSubmatch(repoArg) 93 if len(match) == 0 { 94 return nil, fmt.Errorf("could not parse repo: %s, %v", repoArg, repos) 95 } 96 thisRepo := match[1] 97 // default to master 98 if match[2] == "" { 99 repos = append(repos, Repo{ 100 Name: thisRepo, 101 Branch: "master", 102 Pull: "", 103 }) 104 continue 105 } 106 commitsString := match[2][1:] 107 commits := strings.Split(commitsString, ",") 108 // Checking out a branch, possibly at a specific commit 109 if len(commits) == 1 { 110 repos = append(repos, Repo{ 111 Name: thisRepo, 112 Branch: commits[0], 113 Pull: "", 114 }) 115 continue 116 } 117 // Checking out one or more PRs 118 repos = append(repos, Repo{ 119 Name: thisRepo, 120 Branch: "", 121 Pull: commitsString, 122 }) 123 } 124 return repos, nil 125 }