diff options
author | Kostya Ostrovsky <kostyay@users.noreply.github.com> | 2020-12-01 11:52:53 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-01 10:52:53 +0100 |
commit | 51cbc24bbecfecbbcea9cd733ad44eaf74b8ae4b (patch) | |
tree | 73a4fdcb346d3233181781e37d1929b457a65216 /config/url.go | |
parent | d525a514057f97bc2b183e2c67f542dd6f0ac0aa (diff) | |
download | go-git-51cbc24bbecfecbbcea9cd733ad44eaf74b8ae4b.tar.gz |
config: support insteadOf for remotes' URLs (#79)
Diffstat (limited to 'config/url.go')
-rw-r--r-- | config/url.go | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/config/url.go b/config/url.go new file mode 100644 index 0000000..114d6b2 --- /dev/null +++ b/config/url.go @@ -0,0 +1,81 @@ +package config + +import ( + "errors" + "strings" + + format "github.com/go-git/go-git/v5/plumbing/format/config" +) + +var ( + errURLEmptyInsteadOf = errors.New("url config: empty insteadOf") +) + +// Url defines Url rewrite rules +type URL struct { + // Name new base url + Name string + // Any URL that starts with this value will be rewritten to start, instead, with <base>. + // When more than one insteadOf strings match a given URL, the longest match is used. + InsteadOf string + + // raw representation of the subsection, filled by marshal or unmarshal are + // called. + raw *format.Subsection +} + +// Validate validates fields of branch +func (b *URL) Validate() error { + if b.InsteadOf == "" { + return errURLEmptyInsteadOf + } + + return nil +} + +const ( + insteadOfKey = "insteadOf" +) + +func (u *URL) unmarshal(s *format.Subsection) error { + u.raw = s + + u.Name = s.Name + u.InsteadOf = u.raw.Option(insteadOfKey) + return nil +} + +func (u *URL) marshal() *format.Subsection { + if u.raw == nil { + u.raw = &format.Subsection{} + } + + u.raw.Name = u.Name + u.raw.SetOption(insteadOfKey, u.InsteadOf) + + return u.raw +} + +func findLongestInsteadOfMatch(remoteURL string, urls map[string]*URL) *URL { + var longestMatch *URL + for _, u := range urls { + if !strings.HasPrefix(remoteURL, u.InsteadOf) { + continue + } + + // according to spec if there is more than one match, take the logest + if longestMatch == nil || len(longestMatch.InsteadOf) < len(u.InsteadOf) { + longestMatch = u + } + } + + return longestMatch +} + +func (u *URL) ApplyInsteadOf(url string) string { + if !strings.HasPrefix(url, u.InsteadOf) { + return url + } + + return u.Name + url[len(u.InsteadOf):] +} |