Skip to content

Commit 259cecd

Browse files
committed
add handling function for remote url hostname
1 parent 38873aa commit 259cecd

File tree

2 files changed

+209
-23
lines changed

2 files changed

+209
-23
lines changed

pkg/loader/gitcloner.go

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"io/ioutil"
2222
"os/exec"
2323
"path/filepath"
24+
"regexp"
2425
"strings"
2526

2627
"github.com/pkg/errors"
@@ -44,7 +45,8 @@ func isRepoUrl(arg string) bool {
4445
strings.HasPrefix(arg, "gh:") ||
4546
strings.HasPrefix(arg, "github.com") ||
4647
strings.HasPrefix(arg, "[email protected]:") ||
47-
strings.Index(arg, "github.com/") > -1)
48+
strings.Index(arg, "github.com/") > -1 ||
49+
isAzureHost(arg) || isAWSHost(arg))
4850
}
4951

5052
func makeTmpDir() (string, error) {
@@ -61,14 +63,14 @@ func simpleGitCloner(spec string) (
6163
if err != nil {
6264
return
6365
}
64-
repo, pathInCoDir, gitRef, err := parseGithubUrl(spec)
66+
repo, pathInCoDir, gitRef, err := parseUrl(spec)
6567
if err != nil {
6668
return
6769
}
6870
cmd := exec.Command(
6971
gitProgram,
7072
"clone",
71-
"https://github.com/"+repo+".git",
73+
repo,
7274
checkoutDir)
7375
var out bytes.Buffer
7476
cmd.Stdout = &out
@@ -90,27 +92,36 @@ func simpleGitCloner(spec string) (
9092
return checkoutDir, pathInCoDir, nil
9193
}
9294

95+
func parseUrl(n string) (
96+
repo string, path string, gitRef string, err error) {
97+
host, repo, path, gitRef, err := parseGithubUrl(n)
98+
if err != nil {
99+
return
100+
}
101+
if isAzureHost(host) || isAWSHost(host) {
102+
repo = host + repo
103+
return
104+
}
105+
repo = host + repo + ".git"
106+
return
107+
}
108+
93109
const refQuery = "?ref="
94110

95111
// From strings like [email protected]:someOrg/someRepo.git or
96112
// https://github.com/someOrg/someRepo?ref=someHash, extract
97113
// the parts.
98114
func parseGithubUrl(n string) (
99-
repo string, path string, gitRef string, err error) {
100-
for _, p := range []string{
101-
// Order matters here.
102-
"git::", "gh:", "https://", "http://",
103-
"git@", "github.com:", "github.com/", "gitlab.com/"} {
104-
if strings.ToLower(n[:len(p)]) == p {
105-
n = n[len(p):]
106-
}
107-
}
115+
host string, repo string, path string, gitRef string, err error) {
116+
host, n = parseHostSpec(n)
117+
host = normalizeGitHostSpec(host)
118+
108119
if strings.HasSuffix(n, ".git") {
109120
n = n[0 : len(n)-len(".git")]
110121
}
111122
i := strings.Index(n, string(filepath.Separator))
112123
if i < 1 {
113-
return "", "", "", errors.New("no separator")
124+
return "", "", "", "", errors.New("no separator")
114125
}
115126
j := strings.Index(n[i+1:], string(filepath.Separator))
116127
if j >= 0 {
@@ -131,3 +142,57 @@ func peelQuery(arg string) (string, string) {
131142
}
132143
return arg, ""
133144
}
145+
146+
func parseHostSpec(n string) (string, string) {
147+
var host string
148+
for _, p := range []string{
149+
// Order matters here.
150+
"git::", "gh:", "ssh://", "https://", "http://",
151+
"git@", "github.com:", "github.com/", "gitlab.com/"} {
152+
if strings.ToLower(n[:len(p)]) == p {
153+
n = n[len(p):]
154+
host = host + p
155+
}
156+
}
157+
for _, p := range []string{
158+
"git-codecommit.[a-z0-9-]*.amazonaws.com/",
159+
"dev.azure.com/",
160+
".*visualstudio.com/"} {
161+
index := regexp.MustCompile(p).FindStringIndex(n)
162+
if len(index) > 0 {
163+
host = host + n[0:index[len(index)-1]]
164+
n = n[index[len(index)-1]:]
165+
}
166+
}
167+
return host, n
168+
}
169+
170+
func normalizeGitHostSpec(host string) string {
171+
s := strings.ToLower(host)
172+
if strings.Contains(s, "github.com") {
173+
if strings.Contains(s, "git@") || strings.Contains(s, "ssh:") {
174+
175+
} else {
176+
host = "https://github.com/"
177+
}
178+
}
179+
if strings.Contains(s, "gitlab") {
180+
if strings.HasPrefix(s, "git::") {
181+
host = strings.TrimLeft(s, "git::")
182+
}
183+
}
184+
return host
185+
}
186+
187+
// The format of Azure repo URL is documented
188+
// https://docs.microsoft.com/en-us/azure/devops/repos/git/clone?view=vsts&tabs=visual-studio#clone_url
189+
func isAzureHost(host string) bool {
190+
return strings.Contains(host, "dev.azure.com") ||
191+
strings.Contains(host, "visualstudio.com")
192+
}
193+
194+
// The format of AWS repo URL is documented
195+
// https://docs.aws.amazon.com/codecommit/latest/userguide/regions.html
196+
func isAWSHost(host string) bool {
197+
return strings.Contains(host, "amazonaws.com")
198+
}

pkg/loader/gitcloner_test.go

Lines changed: 131 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -185,20 +185,20 @@ var paths = []string{"README.md", "foo/krusty.txt", ""}
185185

186186
var hrefArgs = []string{"someBranch", ""}
187187

188-
var extractFmts = []string{
189-
"gh:%s",
190-
"GH:%s",
191-
"gitHub.com/%s",
192-
"https://github.com/%s",
193-
"hTTps://github.com/%s",
194-
"git::https://gitlab.com/%s",
195-
"github.com:%s",
188+
var extractFmts = map[string]string{
189+
"gh:%s": "gh:",
190+
"GH:%s": "gh:",
191+
"gitHub.com/%s": "https://github.com/",
192+
"https://github.com/%s": "https://github.com/",
193+
"hTTps://github.com/%s": "https://github.com/",
194+
"git::https://gitlab.com/%s": "https://gitlab.com/",
195+
"github.com:%s": "https://github.com/",
196196
}
197197

198198
func TestParseGithubUrl(t *testing.T) {
199199
for _, repoName := range repoNames {
200200
for _, pathName := range paths {
201-
for _, extractFmt := range extractFmts {
201+
for extractFmt, hostSpec := range extractFmts {
202202
for _, hrefArg := range hrefArgs {
203203
spec := repoName
204204
if len(pathName) > 0 {
@@ -212,10 +212,16 @@ func TestParseGithubUrl(t *testing.T) {
212212
t.Errorf("Should smell like github arg: %s\n", input)
213213
continue
214214
}
215-
repo, path, gitRef, err := parseGithubUrl(input)
215+
host, repo, path, gitRef, err := parseGithubUrl(input)
216216
if err != nil {
217217
t.Errorf("problem %v", err)
218218
}
219+
if host != hostSpec {
220+
t.Errorf("\n"+
221+
" from %s\n"+
222+
" actual host %s\n"+
223+
"expected host %s\n", input, host, hostSpec)
224+
}
219225
if repo != repoName {
220226
t.Errorf("\n"+
221227
" from %s\n"+
@@ -239,3 +245,118 @@ func TestParseGithubUrl(t *testing.T) {
239245
}
240246
}
241247
}
248+
249+
func TestParseUrl(t *testing.T) {
250+
testcases := []struct {
251+
input string
252+
repo string
253+
path string
254+
ref string
255+
}{
256+
{
257+
input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir",
258+
repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo",
259+
path: "somedir",
260+
ref: "",
261+
},
262+
{
263+
input: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo/somedir?ref=testbranch",
264+
repo: "https://git-codecommit.us-east-2.amazonaws.com/someorg/somerepo",
265+
path: "somedir",
266+
ref: "testbranch",
267+
},
268+
{
269+
input: "https://fabrikops2.visualstudio.com/someorg/somerepo?ref=master",
270+
repo: "https://fabrikops2.visualstudio.com/someorg/somerepo",
271+
path: "",
272+
ref: "master",
273+
},
274+
{
275+
input: "http://github.com/someorg/somerepo/somedir",
276+
repo: "https://github.com/someorg/somerepo.git",
277+
path: "somedir",
278+
ref: "",
279+
},
280+
{
281+
input: "[email protected]:someorg/somerepo/somedir",
282+
repo: "[email protected]:someorg/somerepo.git",
283+
path: "somedir",
284+
ref: "",
285+
},
286+
}
287+
for _, testcase := range testcases {
288+
repo, path, ref, err := parseUrl(testcase.input)
289+
if err != nil {
290+
t.Errorf("Unexpected error: %v", err)
291+
}
292+
if repo != testcase.repo {
293+
t.Errorf("repo expected to be %v, but got %v on %s", testcase.repo, repo, testcase.input)
294+
}
295+
if path != testcase.path {
296+
t.Errorf("path expected to be %v, but got %v on %s", testcase.path, path, testcase.input)
297+
}
298+
if ref != testcase.ref {
299+
t.Errorf("ref expected to be %v, but got %v on %s", testcase.ref, ref, testcase.input)
300+
}
301+
}
302+
}
303+
304+
func TestIsAzureHost(t *testing.T) {
305+
testcases := []struct {
306+
input string
307+
expect bool
308+
}{
309+
{
310+
input: "https://git-codecommit.us-east-2.amazonaws.com",
311+
expect: false,
312+
},
313+
{
314+
input: "ssh://git-codecommit.us-east-2.amazonaws.com",
315+
expect: false,
316+
},
317+
{
318+
input: "https://fabrikops2.visualstudio.com/",
319+
expect: true,
320+
},
321+
{
322+
input: "https://dev.azure.com/myorg/myproject/",
323+
expect: true,
324+
},
325+
}
326+
for _, testcase := range testcases {
327+
actual := isAzureHost(testcase.input)
328+
if actual != testcase.expect {
329+
t.Errorf("IsAzureHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input)
330+
}
331+
}
332+
}
333+
334+
func TestIsAWSHost(t *testing.T) {
335+
testcases := []struct {
336+
input string
337+
expect bool
338+
}{
339+
{
340+
input: "https://git-codecommit.us-east-2.amazonaws.com",
341+
expect: true,
342+
},
343+
{
344+
input: "ssh://git-codecommit.us-east-2.amazonaws.com",
345+
expect: true,
346+
},
347+
{
348+
input: "[email protected]:",
349+
expect: false,
350+
},
351+
{
352+
input: "http://github.com/",
353+
expect: false,
354+
},
355+
}
356+
for _, testcase := range testcases {
357+
actual := isAWSHost(testcase.input)
358+
if actual != testcase.expect {
359+
t.Errorf("IsAWSHost: expected %v, but got %v on %s", testcase.expect, actual, testcase.input)
360+
}
361+
}
362+
}

0 commit comments

Comments
 (0)