+2
-2
config/config_test.go
+2
-2
config/config_test.go
+22
-13
config/url.go
+22
-13
config/url.go
···
17
17
Name string
18
18
// Any URL that starts with this value will be rewritten to start, instead, with <base>.
19
19
// When more than one insteadOf strings match a given URL, the longest match is used.
20
-
InsteadOf string
20
+
InsteadOfs []string
21
21
22
22
// raw representation of the subsection, filled by marshal or unmarshal are
23
23
// called.
···
26
26
27
27
// Validate validates fields of branch
28
28
func (b *URL) Validate() error {
29
-
if b.InsteadOf == "" {
29
+
if len(b.InsteadOfs) == 0 {
30
30
return errURLEmptyInsteadOf
31
31
}
32
32
···
41
41
u.raw = s
42
42
43
43
u.Name = s.Name
44
-
u.InsteadOf = u.raw.Option(insteadOfKey)
44
+
u.InsteadOfs = u.raw.OptionAll(insteadOfKey)
45
45
return nil
46
46
}
47
47
···
51
51
}
52
52
53
53
u.raw.Name = u.Name
54
-
u.raw.SetOption(insteadOfKey, u.InsteadOf)
54
+
u.raw.SetOption(insteadOfKey, u.InsteadOfs...)
55
55
56
56
return u.raw
57
57
}
58
58
59
59
func findLongestInsteadOfMatch(remoteURL string, urls map[string]*URL) *URL {
60
60
var longestMatch *URL
61
+
var longestMatchLength int
62
+
61
63
for _, u := range urls {
62
-
if !strings.HasPrefix(remoteURL, u.InsteadOf) {
63
-
continue
64
-
}
64
+
for _, currentInsteadOf := range u.InsteadOfs {
65
+
if !strings.HasPrefix(remoteURL, currentInsteadOf) {
66
+
continue
67
+
}
68
+
69
+
lengthCurrentInsteadOf := len(currentInsteadOf)
65
70
66
-
// according to spec if there is more than one match, take the logest
67
-
if longestMatch == nil || len(longestMatch.InsteadOf) < len(u.InsteadOf) {
68
-
longestMatch = u
71
+
// according to spec if there is more than one match, take the longest
72
+
if longestMatch == nil || longestMatchLength < lengthCurrentInsteadOf {
73
+
longestMatch = u
74
+
longestMatchLength = lengthCurrentInsteadOf
75
+
}
69
76
}
70
77
}
71
78
···
73
80
}
74
81
75
82
func (u *URL) ApplyInsteadOf(url string) string {
76
-
if !strings.HasPrefix(url, u.InsteadOf) {
77
-
return url
83
+
for _, j := range u.InsteadOfs {
84
+
if strings.HasPrefix(url, j) {
85
+
return u.Name + url[len(j):]
86
+
}
78
87
}
79
88
80
-
return u.Name + url[len(u.InsteadOf):]
89
+
return url
81
90
}
+80
-7
config/url_test.go
+80
-7
config/url_test.go
···
16
16
17
17
func (b *URLSuite) TestValidateInsteadOf() {
18
18
goodURL := URL{
19
-
Name: "ssh://github.com",
20
-
InsteadOf: "http://github.com",
19
+
Name: "ssh://github.com",
20
+
InsteadOfs: []string{"http://github.com"},
21
21
}
22
22
badURL := URL{}
23
23
b.Nil(goodURL.Validate())
···
33
33
34
34
cfg := NewConfig()
35
35
cfg.URLs["ssh://git@github.com/"] = &URL{
36
-
Name: "ssh://git@github.com/",
37
-
InsteadOf: "https://github.com/",
36
+
Name: "ssh://git@github.com/",
37
+
InsteadOfs: []string{"https://github.com/"},
38
+
}
39
+
40
+
actual, err := cfg.Marshal()
41
+
b.Nil(err)
42
+
b.Equal(string(expected), string(actual))
43
+
}
44
+
45
+
func (b *URLSuite) TestMarshalMultipleInsteadOf() {
46
+
expected := []byte(`[core]
47
+
bare = false
48
+
[url "ssh://git@github.com/"]
49
+
insteadOf = https://github.com/
50
+
insteadOf = https://google.com/
51
+
`)
52
+
53
+
cfg := NewConfig()
54
+
cfg.URLs["ssh://git@github.com/"] = &URL{
55
+
Name: "ssh://git@github.com/",
56
+
InsteadOfs: []string{"https://github.com/", "https://google.com/"},
38
57
}
39
58
40
59
actual, err := cfg.Marshal()
···
54
73
b.NoError(err)
55
74
url := cfg.URLs["ssh://git@github.com/"]
56
75
b.Equal("ssh://git@github.com/", url.Name)
57
-
b.Equal("https://github.com/", url.InsteadOf)
76
+
b.Equal("https://github.com/", url.InsteadOfs[0])
77
+
}
78
+
79
+
func (b *URLSuite) TestUnmarshalMultipleInsteadOf() {
80
+
input := []byte(`[core]
81
+
bare = false
82
+
[url "ssh://git@github.com/"]
83
+
insteadOf = https://github.com/
84
+
insteadOf = https://google.com/
85
+
`)
86
+
87
+
cfg := NewConfig()
88
+
err := cfg.Unmarshal(input)
89
+
b.Nil(err)
90
+
url := cfg.URLs["ssh://git@github.com/"]
91
+
b.Equal("ssh://git@github.com/", url.Name)
92
+
93
+
b.Equal("ssh://git@github.com/foobar", url.ApplyInsteadOf("https://github.com/foobar"))
94
+
b.Equal("ssh://git@github.com/foobar", url.ApplyInsteadOf("https://google.com/foobar"))
95
+
}
96
+
97
+
func (b *URLSuite) TestUnmarshalDuplicateUrls() {
98
+
input := []byte(`[core]
99
+
bare = false
100
+
[url "ssh://git@github.com/"]
101
+
insteadOf = https://github.com/
102
+
[url "ssh://git@github.com/"]
103
+
insteadOf = https://google.com/
104
+
`)
105
+
106
+
cfg := NewConfig()
107
+
err := cfg.Unmarshal(input)
108
+
b.Nil(err)
109
+
url := cfg.URLs["ssh://git@github.com/"]
110
+
b.Equal("ssh://git@github.com/", url.Name)
111
+
112
+
b.Equal("ssh://git@github.com/foobar", url.ApplyInsteadOf("https://github.com/foobar"))
113
+
b.Equal("ssh://git@github.com/foobar", url.ApplyInsteadOf("https://google.com/foobar"))
58
114
}
59
115
60
116
func (b *URLSuite) TestApplyInsteadOf() {
61
117
urlRule := URL{
62
-
Name: "ssh://github.com",
63
-
InsteadOf: "http://github.com",
118
+
Name: "ssh://github.com",
119
+
InsteadOfs: []string{"http://github.com"},
64
120
}
65
121
66
122
b.Equal("http://google.com", urlRule.ApplyInsteadOf("http://google.com"))
67
123
b.Equal("ssh://github.com/myrepo", urlRule.ApplyInsteadOf("http://github.com/myrepo"))
68
124
}
125
+
126
+
func (b *URLSuite) TestFindLongestInsteadOfMatch() {
127
+
urlRules := map[string]*URL{
128
+
"ssh://github.com": &URL{
129
+
Name: "ssh://github.com",
130
+
InsteadOfs: []string{"http://github.com"},
131
+
},
132
+
"ssh://somethingelse.com": &URL{
133
+
Name: "ssh://somethingelse.com",
134
+
InsteadOfs: []string{"http://github.com/foobar"},
135
+
},
136
+
}
137
+
138
+
longestUrl := findLongestInsteadOfMatch("http://github.com/foobar/bingbash.git", urlRules)
139
+
140
+
b.Equal("ssh://somethingelse.com", longestUrl.Name)
141
+
}