github.com/stffabi/git-lfs@v2.3.5-0.20180214015214-8eeaa8d88902+incompatible/config/url_config.go (about) 1 package config 2 3 import ( 4 "fmt" 5 "net/url" 6 "strings" 7 ) 8 9 type URLConfig struct { 10 git Environment 11 } 12 13 func NewURLConfig(git Environment) *URLConfig { 14 if git == nil { 15 git = EnvironmentOf(make(mapFetcher)) 16 } 17 18 return &URLConfig{ 19 git: git, 20 } 21 } 22 23 // Get retrieves a `http.{url}.{key}` for the given key and urls, following the 24 // rules in https://git-scm.com/docs/git-config#git-config-httplturlgt. 25 // The value for `http.{key}` is returned as a fallback if no config keys are 26 // set for the given urls. 27 func (c *URLConfig) Get(prefix, rawurl, key string) (string, bool) { 28 if c == nil { 29 return "", false 30 } 31 32 key = strings.ToLower(key) 33 prefix = strings.ToLower(prefix) 34 if v := c.getAll(prefix, rawurl, key); len(v) > 0 { 35 return v[len(v)-1], true 36 } 37 return c.git.Get(strings.Join([]string{prefix, key}, ".")) 38 } 39 40 func (c *URLConfig) GetAll(prefix, rawurl, key string) []string { 41 if c == nil { 42 return nil 43 } 44 45 key = strings.ToLower(key) 46 prefix = strings.ToLower(prefix) 47 if v := c.getAll(prefix, rawurl, key); len(v) > 0 { 48 return v 49 } 50 return c.git.GetAll(strings.Join([]string{prefix, key}, ".")) 51 } 52 53 func (c *URLConfig) Bool(prefix, rawurl, key string, def bool) bool { 54 s, _ := c.Get(prefix, rawurl, key) 55 return Bool(s, def) 56 } 57 58 func (c *URLConfig) getAll(prefix, rawurl, key string) []string { 59 hosts, paths := c.hostsAndPaths(rawurl) 60 61 for i := len(paths); i > 0; i-- { 62 for _, host := range hosts { 63 path := strings.Join(paths[:i], slash) 64 if v := c.git.GetAll(fmt.Sprintf("%s.%s/%s.%s", prefix, host, path, key)); len(v) > 0 { 65 return v 66 } 67 if v := c.git.GetAll(fmt.Sprintf("%s.%s/%s/.%s", prefix, host, path, key)); len(v) > 0 { 68 return v 69 } 70 71 if isDefaultLFSUrl(path, paths, i) { 72 path = path[0 : len(path)-4] 73 if v := c.git.GetAll(fmt.Sprintf("%s.%s/%s.%s", prefix, host, path, key)); len(v) > 0 { 74 return v 75 } 76 } 77 } 78 } 79 80 for _, host := range hosts { 81 if v := c.git.GetAll(fmt.Sprintf("%s.%s.%s", prefix, host, key)); len(v) > 0 { 82 return v 83 } 84 if v := c.git.GetAll(fmt.Sprintf("%s.%s/.%s", prefix, host, key)); len(v) > 0 { 85 return v 86 } 87 } 88 return nil 89 90 } 91 func (c *URLConfig) hostsAndPaths(rawurl string) (hosts, paths []string) { 92 u, err := url.Parse(rawurl) 93 if err != nil { 94 return nil, nil 95 } 96 97 return c.hosts(u), c.paths(u.Path) 98 } 99 100 func (c *URLConfig) hosts(u *url.URL) []string { 101 hosts := make([]string, 0, 1) 102 103 if u.User != nil { 104 hosts = append(hosts, fmt.Sprintf("%s://%s@%s", u.Scheme, u.User.Username(), u.Host)) 105 } 106 hosts = append(hosts, fmt.Sprintf("%s://%s", u.Scheme, u.Host)) 107 108 return hosts 109 } 110 111 func (c *URLConfig) paths(path string) []string { 112 pLen := len(path) 113 if pLen <= 2 { 114 return nil 115 } 116 117 end := pLen 118 if strings.HasSuffix(path, slash) { 119 end-- 120 } 121 return strings.Split(path[1:end], slash) 122 } 123 124 const ( 125 gitExt = ".git" 126 infoPart = "info" 127 lfsPart = "lfs" 128 slash = "/" 129 ) 130 131 func isDefaultLFSUrl(path string, parts []string, index int) bool { 132 if len(path) < 5 { 133 return false // shorter than ".git" 134 } 135 136 if !strings.HasSuffix(path, gitExt) { 137 return false 138 } 139 140 if index > len(parts)-2 { 141 return false 142 } 143 144 return parts[index] == infoPart && parts[index+1] == lfsPart 145 }