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