github.com/saracen/git-lfs@v2.5.2+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  }