github.com/psexton/git-lfs@v2.1.1-0.20170517224304-289a18b2bc53+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) getAll(prefix, rawurl, key string) []string { 54 hosts, paths := c.hostsAndPaths(rawurl) 55 56 for i := len(paths); i > 0; i-- { 57 for _, host := range hosts { 58 path := strings.Join(paths[:i], slash) 59 if v := c.git.GetAll(fmt.Sprintf("%s.%s/%s.%s", prefix, host, path, key)); len(v) > 0 { 60 return v 61 } 62 if v := c.git.GetAll(fmt.Sprintf("%s.%s/%s/.%s", prefix, host, path, key)); len(v) > 0 { 63 return v 64 } 65 66 if isDefaultLFSUrl(path, paths, i) { 67 path = path[0 : len(path)-4] 68 if v := c.git.GetAll(fmt.Sprintf("%s.%s/%s.%s", prefix, host, path, key)); len(v) > 0 { 69 return v 70 } 71 } 72 } 73 } 74 75 for _, host := range hosts { 76 if v := c.git.GetAll(fmt.Sprintf("%s.%s.%s", prefix, host, key)); len(v) > 0 { 77 return v 78 } 79 if v := c.git.GetAll(fmt.Sprintf("%s.%s/.%s", prefix, host, key)); len(v) > 0 { 80 return v 81 } 82 } 83 return nil 84 85 } 86 func (c *URLConfig) hostsAndPaths(rawurl string) (hosts, paths []string) { 87 u, err := url.Parse(rawurl) 88 if err != nil { 89 return nil, nil 90 } 91 92 return c.hosts(u), c.paths(u.Path) 93 } 94 95 func (c *URLConfig) hosts(u *url.URL) []string { 96 hosts := make([]string, 0, 1) 97 98 if u.User != nil { 99 hosts = append(hosts, fmt.Sprintf("%s://%s@%s", u.Scheme, u.User.Username(), u.Host)) 100 } 101 hosts = append(hosts, fmt.Sprintf("%s://%s", u.Scheme, u.Host)) 102 103 return hosts 104 } 105 106 func (c *URLConfig) paths(path string) []string { 107 pLen := len(path) 108 if pLen <= 2 { 109 return nil 110 } 111 112 end := pLen 113 if strings.HasSuffix(path, slash) { 114 end-- 115 } 116 return strings.Split(path[1:end], slash) 117 } 118 119 const ( 120 gitExt = ".git" 121 infoPart = "info" 122 lfsPart = "lfs" 123 slash = "/" 124 ) 125 126 func isDefaultLFSUrl(path string, parts []string, index int) bool { 127 if len(path) < 5 { 128 return false // shorter than ".git" 129 } 130 131 if !strings.HasSuffix(path, gitExt) { 132 return false 133 } 134 135 if index > len(parts)-2 { 136 return false 137 } 138 139 return parts[index] == infoPart && parts[index+1] == lfsPart 140 }