aboutsummaryrefslogtreecommitdiffstats
path: root/config/url.go
diff options
context:
space:
mode:
authorKostya Ostrovsky <kostyay@users.noreply.github.com>2020-12-01 11:52:53 +0200
committerGitHub <noreply@github.com>2020-12-01 10:52:53 +0100
commit51cbc24bbecfecbbcea9cd733ad44eaf74b8ae4b (patch)
tree73a4fdcb346d3233181781e37d1929b457a65216 /config/url.go
parentd525a514057f97bc2b183e2c67f542dd6f0ac0aa (diff)
downloadgo-git-51cbc24bbecfecbbcea9cd733ad44eaf74b8ae4b.tar.gz
config: support insteadOf for remotes' URLs (#79)
Diffstat (limited to 'config/url.go')
-rw-r--r--config/url.go81
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):]
+}