all: expand config.Environment interface to support multiple values per key

This commit is contained in:
Taylor Blau 2017-04-12 17:29:11 -04:00
parent 2fb111ef1b
commit 552b955b3f
31 changed files with 313 additions and 180 deletions

@ -20,12 +20,14 @@ func updateCommand(cmd *cobra.Command, args []string) {
requireInRepo()
lfsAccessRE := regexp.MustCompile(`\Alfs\.(.*)\.access\z`)
for key, value := range cfg.Git.All() {
for key, _ := range cfg.Git.All() {
matches := lfsAccessRE.FindStringSubmatch(key)
if len(matches) < 2 {
continue
}
value, _ := cfg.Git.Get(key)
switch value {
case "basic":
case "private":

@ -9,9 +9,9 @@ import (
var (
testcfg = config.NewFrom(config.Values{
Git: map[string]string{
"lfs.fetchinclude": "/default/include",
"lfs.fetchexclude": "/default/exclude",
Git: map[string][]string{
"lfs.fetchinclude": []string{"/default/include"},
"lfs.fetchexclude": []string{"/default/exclude"},
},
})
)

@ -75,7 +75,7 @@ func New() *Configuration {
type Values struct {
// Git and Os are the stand-in maps used to provide values for their
// respective environments.
Git, Os map[string]string
Git, Os map[string][]string
}
// NewFrom returns a new `*config.Configuration` that reads both its Git

@ -9,8 +9,8 @@ import (
func TestConcurrentTransfersSetValue(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.concurrenttransfers": "5",
Git: map[string][]string{
"lfs.concurrenttransfers": []string{"5"},
},
})
@ -27,8 +27,8 @@ func TestConcurrentTransfersDefault(t *testing.T) {
func TestConcurrentTransfersZeroValue(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.concurrenttransfers": "0",
Git: map[string][]string{
"lfs.concurrenttransfers": []string{"0"},
},
})
@ -38,8 +38,8 @@ func TestConcurrentTransfersZeroValue(t *testing.T) {
func TestConcurrentTransfersNonNumeric(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.concurrenttransfers": "elephant",
Git: map[string][]string{
"lfs.concurrenttransfers": []string{"elephant"},
},
})
@ -49,8 +49,8 @@ func TestConcurrentTransfersNonNumeric(t *testing.T) {
func TestConcurrentTransfersNegativeValue(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.concurrenttransfers": "-5",
Git: map[string][]string{
"lfs.concurrenttransfers": []string{"-5"},
},
})
@ -60,8 +60,8 @@ func TestConcurrentTransfersNegativeValue(t *testing.T) {
func TestBasicTransfersOnlySetValue(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.basictransfersonly": "true",
Git: map[string][]string{
"lfs.basictransfersonly": []string{"true"},
},
})
@ -78,8 +78,8 @@ func TestBasicTransfersOnlyDefault(t *testing.T) {
func TestBasicTransfersOnlyInvalidValue(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.basictransfersonly": "wat",
Git: map[string][]string{
"lfs.basictransfersonly": []string{"wat"},
},
})
@ -89,8 +89,8 @@ func TestBasicTransfersOnlyInvalidValue(t *testing.T) {
func TestTusTransfersAllowedSetValue(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.tustransfers": "true",
Git: map[string][]string{
"lfs.tustransfers": []string{"true"},
},
})
@ -107,8 +107,8 @@ func TestTusTransfersAllowedDefault(t *testing.T) {
func TestTusTransfersAllowedInvalidValue(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.tustransfers": "wat",
Git: map[string][]string{
"lfs.tustransfers": []string{"wat"},
},
})
@ -118,7 +118,7 @@ func TestTusTransfersAllowedInvalidValue(t *testing.T) {
func TestLoadValidExtension(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{},
Git: map[string][]string{},
})
cfg.extensions = map[string]Extension{
@ -163,13 +163,13 @@ func TestFetchPruneConfigDefault(t *testing.T) {
}
func TestFetchPruneConfigCustom(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.fetchrecentrefsdays": "12",
"lfs.fetchrecentremoterefs": "false",
"lfs.fetchrecentcommitsdays": "9",
"lfs.pruneoffsetdays": "30",
"lfs.pruneverifyremotealways": "true",
"lfs.pruneremotetocheck": "upstream",
Git: map[string][]string{
"lfs.fetchrecentrefsdays": []string{"12"},
"lfs.fetchrecentremoterefs": []string{"false"},
"lfs.fetchrecentcommitsdays": []string{"9"},
"lfs.pruneoffsetdays": []string{"30"},
"lfs.pruneverifyremotealways": []string{"true"},
"lfs.pruneremotetocheck": []string{"upstream"},
},
})
fp := cfg.FetchPruneConfig()
@ -184,9 +184,9 @@ func TestFetchPruneConfigCustom(t *testing.T) {
func TestFetchIncludeExcludesAreCleaned(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"lfs.fetchinclude": "/path/to/clean/",
"lfs.fetchexclude": "/other/path/to/clean/",
Git: map[string][]string{
"lfs.fetchinclude": []string{"/path/to/clean/"},
"lfs.fetchexclude": []string{"/other/path/to/clean/"},
},
})
@ -196,15 +196,15 @@ func TestFetchIncludeExcludesAreCleaned(t *testing.T) {
func TestUnmarshalMultipleTypes(t *testing.T) {
cfg := NewFrom(Values{
Git: map[string]string{
"string": "string",
"int": "1",
"bool": "true",
Git: map[string][]string{
"string": []string{"string"},
"int": []string{"1"},
"bool": []string{"true"},
},
Os: map[string]string{
"string": "string",
"int": "1",
"bool": "true",
Os: map[string][]string{
"string": []string{"string"},
"int": []string{"1"},
"bool": []string{"true"},
},
})
@ -264,10 +264,10 @@ func TestUnmarshalOverridesNonZeroValuesWhenValuesPresent(t *testing.T) {
}{"foo", 1, true}
cfg := NewFrom(Values{
Git: map[string]string{
"string": "bar",
"int": "2",
"bool": "false",
Git: map[string][]string{
"string": []string{"bar"},
"int": []string{"2"},
"bool": []string{"false"},
},
})
@ -307,7 +307,7 @@ func TestUnmarshalErrsOnUnsupportedTypes(t *testing.T) {
}{}
cfg := NewFrom(Values{
Git: map[string]string{"duration": "foo"},
Git: map[string][]string{"duration": []string{"foo"}},
})
err := cfg.Unmarshal(v)

@ -15,6 +15,9 @@ type Environment interface {
// Get is shorthand for calling `e.Fetcher.Get(key)`.
Get(key string) (val string, ok bool)
// Get is shorthand for calling `e.Fetcher.GetAll(key)`.
GetAll(key string) (vals []string)
// Bool returns the boolean state associated with a given key, or the
// value "def", if no value was associated.
//
@ -38,8 +41,9 @@ type Environment interface {
// then it will be returned wholesale.
Int(key string, def int) (val int)
// All returns a copy of all the key/value pairs for the current environment.
All() map[string]string
// All returns a copy of all the key/value pairs for the current
// environment.
All() map[string][]string
}
type environment struct {
@ -57,6 +61,10 @@ func (e *environment) Get(key string) (val string, ok bool) {
return e.Fetcher.Get(key)
}
func (e *environment) GetAll(key string) []string {
return e.Fetcher.GetAll(key)
}
func (e *environment) Bool(key string, def bool) (val bool) {
s, _ := e.Fetcher.Get(key)
if len(s) == 0 {
@ -87,6 +95,6 @@ func (e *environment) Int(key string, def int) (val int) {
return i
}
func (e *environment) All() map[string]string {
func (e *environment) All() map[string][]string {
return e.Fetcher.All()
}

@ -8,8 +8,8 @@ import (
)
func TestEnvironmentGetDelegatesToFetcher(t *testing.T) {
fetcher := MapFetcher(map[string]string{
"foo": "bar",
fetcher := MapFetcher(map[string][]string{
"foo": []string{"bar"},
})
env := EnvironmentOf(fetcher)
@ -79,8 +79,8 @@ var (
)
func (c *EnvironmentConversionTestCase) Assert(t *testing.T) {
fetcher := MapFetcher(map[string]string{
c.Val: c.Val,
fetcher := MapFetcher(map[string][]string{
c.Val: []string{c.Val},
})
env := EnvironmentOf(fetcher)

@ -6,8 +6,17 @@ package config
type Fetcher interface {
// Get returns the string value associated with a given key and a bool
// determining if the key exists.
//
// If multiple entries match the given key, the first one will be
// returned.
Get(key string) (val string, ok bool)
// All returns a copy of all the key/value pairs for the current environment.
All() map[string]string
// GetAll returns the a set of string values associated with a given
// key. If no entries matched the given key, an empty slice will be
// returned instead.
GetAll(key string) (vals []string)
// All returns a copy of all the key/value pairs for the current
// environment.
All() map[string][]string
}

@ -21,6 +21,14 @@ func (g *gitEnvironment) Get(key string) (val string, ok bool) {
return g.git.Get(key)
}
// Get is shorthand for calling the loadGitConfig, and then returning
// `g.git.GetAll(key)`.
func (g *gitEnvironment) GetAll(key string) []string {
g.loadGitConfig()
return g.git.GetAll(key)
}
// Get is shorthand for calling the loadGitConfig, and then returning
// `g.git.Bool(key, def)`.
func (g *gitEnvironment) Bool(key string, def bool) (val bool) {
@ -38,7 +46,7 @@ func (g *gitEnvironment) Int(key string, def int) (val int) {
}
// All returns a copy of all the key/value pairs for the current git config.
func (g *gitEnvironment) All() map[string]string {
func (g *gitEnvironment) All() map[string][]string {
g.loadGitConfig()
return g.git.All()

@ -13,7 +13,7 @@ import (
type GitFetcher struct {
vmu sync.RWMutex
vals map[string]string
vals map[string][]string
}
type GitConfig struct {
@ -29,7 +29,7 @@ func NewGitConfig(gitconfiglines string, onlysafe bool) *GitConfig {
}
func ReadGitConfig(configs ...*GitConfig) (gf *GitFetcher, extensions map[string]Extension, uniqRemotes map[string]bool) {
vals := make(map[string]string)
vals := make(map[string][]string)
extensions = make(map[string]Extension)
uniqRemotes = make(map[string]bool)
@ -47,7 +47,7 @@ func ReadGitConfig(configs ...*GitConfig) (gf *GitFetcher, extensions map[string
key, val := strings.ToLower(pieces[0]), pieces[1]
if origKey, ok := uniqKeys[key]; ok {
if ShowConfigWarnings && vals[key] != val && strings.HasPrefix(key, gitConfigWarningPrefix) {
if ShowConfigWarnings && len(vals[key]) > 0 && vals[key][0] != val && strings.HasPrefix(key, gitConfigWarningPrefix) {
fmt.Fprintf(os.Stderr, "WARNING: These git config values clash:\n")
fmt.Fprintf(os.Stderr, " git config %q = %q\n", origKey, vals[key])
fmt.Fprintf(os.Stderr, " git config %q = %q\n", pieces[0], val)
@ -101,7 +101,7 @@ func ReadGitConfig(configs ...*GitConfig) (gf *GitFetcher, extensions map[string
continue
}
vals[key] = val
vals[key] = append(vals[key], val)
}
}
@ -119,21 +119,31 @@ func ReadGitConfig(configs ...*GitConfig) (gf *GitFetcher, extensions map[string
//
// Get is safe to call across multiple goroutines.
func (g *GitFetcher) Get(key string) (val string, ok bool) {
g.vmu.RLock()
defer g.vmu.RUnlock()
all := g.GetAll(key)
val, ok = g.vals[strings.ToLower(key)]
return
if len(all) == 0 {
return "", false
}
return all[0], true
}
func (g *GitFetcher) All() map[string]string {
newmap := make(map[string]string)
func (g *GitFetcher) GetAll(key string) []string {
g.vmu.RLock()
defer g.vmu.RUnlock()
return g.vals[strings.ToLower(key)]
}
func (g *GitFetcher) All() map[string][]string {
newmap := make(map[string][]string)
g.vmu.RLock()
defer g.vmu.RUnlock()
for key, value := range g.vals {
newmap[key] = value
for key, values := range g.vals {
for _, value := range values {
newmap[key] = append(newmap[key], value)
}
}
return newmap

@ -2,22 +2,42 @@ package config
// mapFetcher provides an implementation of the Fetcher interface by wrapping
// the `map[string]string` type.
type mapFetcher map[string]string
type mapFetcher map[string][]string
func MapFetcher(m map[string]string) Fetcher {
func UniqMapFetcher(m map[string]string) Fetcher {
multi := make(map[string][]string, len(m))
for k, v := range m {
multi[k] = []string{v}
}
return MapFetcher(multi)
}
func MapFetcher(m map[string][]string) Fetcher {
return mapFetcher(m)
}
// Get implements the func `Fetcher.Get`.
func (m mapFetcher) Get(key string) (val string, ok bool) {
val, ok = m[key]
return
all := m.GetAll(key)
if len(all) == 0 {
return "", false
}
return all[0], true
}
func (m mapFetcher) All() map[string]string {
newmap := make(map[string]string)
for key, value := range m {
newmap[key] = value
// Get implements the func `Fetcher.GetAll`.
func (m mapFetcher) GetAll(key string) []string {
return m[key]
}
func (m mapFetcher) All() map[string][]string {
newmap := make(map[string][]string)
for key, values := range m {
for _, value := range values {
newmap[key] = append(newmap[key], value)
}
}
return newmap
}

@ -54,6 +54,15 @@ func (o *OsFetcher) Get(key string) (val string, ok bool) {
return v, ok
}
func (o *OsFetcher) All() map[string]string {
// GetAll implements the `config.Fetcher.GetAll` method by returning, at most, a
// 1-ary set containing the result of `config.OsFetcher.Get()`.
func (o *OsFetcher) GetAll(key string) []string {
if v, ok := o.Get(key); ok {
return []string{v}
}
return make([]string, 0)
}
func (o *OsFetcher) All() map[string][]string {
return nil
}

@ -7,13 +7,13 @@ import (
)
func TestURLConfig(t *testing.T) {
u := NewURLConfig(EnvironmentOf(MapFetcher(map[string]string{
"http.key": "root",
"http.https://host.com.key": "host",
"http.https://user@host.com/a.key": "user-a",
"http.https://user@host.com.key": "user",
"http.https://host.com/a.key": "host-a",
"http.https://host.com:8080.key": "port",
u := NewURLConfig(EnvironmentOf(MapFetcher(map[string][]string{
"http.key": []string{"root"},
"http.https://host.com.key": []string{"host"},
"http.https://user@host.com/a.key": []string{"user-a"},
"http.https://user@host.com.key": []string{"user"},
"http.https://host.com/a.key": []string{"host-a"},
"http.https://host.com:8080.key": []string{"port"},
})))
tests := map[string]string{

@ -72,7 +72,7 @@ func TestDoWithAuthApprove(t *testing.T) {
defer srv.Close()
creds := newMockCredentialHelper()
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/repo/lfs",
}))
require.Nil(t, err)
@ -143,7 +143,7 @@ func TestDoWithAuthReject(t *testing.T) {
c := &Client{
Credentials: creds,
Endpoints: NewEndpointFinder(TestEnv(map[string]string{
Endpoints: NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.url": srv.URL,
})),
}
@ -532,7 +532,7 @@ func TestGetCreds(t *testing.T) {
req.Header.Set(key, value)
}
ef := NewEndpointFinder(TestEnv(test.Config))
ef := NewEndpointFinder(UniqTestEnv(test.Config))
endpoint, access, creds, credsURL, err := getCreds(credHelper, netrcFinder, ef, test.Remote, req)
if !assert.Nil(t, err) {
continue

@ -60,7 +60,7 @@ func TestCertFromSSLCAInfoConfig(t *testing.T) {
// Test http.<url>.sslcainfo
for _, hostName := range sslCAInfoConfigHostNames {
hostKey := fmt.Sprintf("http.https://%v.sslcainfo", hostName)
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
hostKey: tempfile.Name(),
}))
assert.Nil(t, err)
@ -82,7 +82,7 @@ func TestCertFromSSLCAInfoConfig(t *testing.T) {
}
// Test http.sslcainfo
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
"http.sslcainfo": tempfile.Name(),
}))
assert.Nil(t, err)
@ -103,7 +103,7 @@ func TestCertFromSSLCAInfoEnv(t *testing.T) {
assert.Nil(t, err, "Error writing temp cert file")
tempfile.Close()
c, err := NewClient(TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSL_CAINFO": tempfile.Name(),
}), nil)
assert.Nil(t, err)
@ -123,7 +123,7 @@ func TestCertFromSSLCAPathConfig(t *testing.T) {
err = ioutil.WriteFile(filepath.Join(tempdir, "cert1.pem"), []byte(testCert), 0644)
assert.Nil(t, err, "Error creating cert file")
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
"http.sslcapath": tempdir,
}))
@ -144,7 +144,7 @@ func TestCertFromSSLCAPathEnv(t *testing.T) {
err = ioutil.WriteFile(filepath.Join(tempdir, "cert1.pem"), []byte(testCert), 0644)
assert.Nil(t, err, "Error creating cert file")
c, err := NewClient(TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSL_CAPATH": tempdir,
}), nil)
assert.Nil(t, err)
@ -164,7 +164,7 @@ func TestCertVerifyDisabledGlobalEnv(t *testing.T) {
assert.False(t, tr.TLSClientConfig.InsecureSkipVerify)
}
c, err := NewClient(TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSL_NO_VERIFY": "1",
}), nil)
@ -185,7 +185,7 @@ func TestCertVerifyDisabledGlobalConfig(t *testing.T) {
assert.False(t, tr.TLSClientConfig.InsecureSkipVerify)
}
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
"http.sslverify": "false",
}))
assert.Nil(t, err)
@ -211,7 +211,7 @@ func TestCertVerifyDisabledHostConfig(t *testing.T) {
assert.False(t, tr.TLSClientConfig.InsecureSkipVerify)
}
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
"http.https://specifichost.com/.sslverify": "false",
}))
assert.Nil(t, err)

@ -99,7 +99,7 @@ func TestClientRedirect(t *testing.T) {
}
func TestNewClient(t *testing.T) {
c, err := NewClient(TestEnv(map[string]string{}), TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{}), UniqTestEnv(map[string]string{
"lfs.dialtimeout": "151",
"lfs.keepalive": "152",
"lfs.tlstimeout": "153",
@ -119,7 +119,7 @@ func TestNewClientWithGitSSLVerify(t *testing.T) {
assert.False(t, c.SkipSSLVerify)
for _, value := range []string{"true", "1", "t"} {
c, err = NewClient(TestEnv(map[string]string{}), TestEnv(map[string]string{
c, err = NewClient(UniqTestEnv(map[string]string{}), UniqTestEnv(map[string]string{
"http.sslverify": value,
}))
t.Logf("http.sslverify: %q", value)
@ -128,7 +128,7 @@ func TestNewClientWithGitSSLVerify(t *testing.T) {
}
for _, value := range []string{"false", "0", "f"} {
c, err = NewClient(TestEnv(map[string]string{}), TestEnv(map[string]string{
c, err = NewClient(UniqTestEnv(map[string]string{}), UniqTestEnv(map[string]string{
"http.sslverify": value,
}))
t.Logf("http.sslverify: %q", value)
@ -143,18 +143,18 @@ func TestNewClientWithOSSSLVerify(t *testing.T) {
assert.False(t, c.SkipSSLVerify)
for _, value := range []string{"false", "0", "f"} {
c, err = NewClient(TestEnv(map[string]string{
c, err = NewClient(UniqTestEnv(map[string]string{
"GIT_SSL_NO_VERIFY": value,
}), TestEnv(map[string]string{}))
}), UniqTestEnv(map[string]string{}))
t.Logf("GIT_SSL_NO_VERIFY: %q", value)
assert.Nil(t, err)
assert.False(t, c.SkipSSLVerify)
}
for _, value := range []string{"true", "1", "t"} {
c, err = NewClient(TestEnv(map[string]string{
c, err = NewClient(UniqTestEnv(map[string]string{
"GIT_SSL_NO_VERIFY": value,
}), TestEnv(map[string]string{}))
}), UniqTestEnv(map[string]string{}))
t.Logf("GIT_SSL_NO_VERIFY: %q", value)
assert.Nil(t, err)
assert.True(t, c.SkipSSLVerify)
@ -170,7 +170,7 @@ func TestNewRequest(t *testing.T) {
}
for _, test := range tests {
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
"lfs.url": test[0],
}))
require.Nil(t, err)
@ -183,7 +183,7 @@ func TestNewRequest(t *testing.T) {
}
func TestNewRequestWithBody(t *testing.T) {
c, err := NewClient(nil, TestEnv(map[string]string{
c, err := NewClient(nil, UniqTestEnv(map[string]string{
"lfs.url": "https://example.com",
}))
require.Nil(t, err)

@ -279,12 +279,12 @@ func initAliases(e *endpointGitFinder, git Env) {
prefix := "url."
suffix := ".insteadof"
for gitkey, gitval := range git.All() {
if !(strings.HasPrefix(gitkey, prefix) && strings.HasSuffix(gitkey, suffix)) {
if len(gitval) == 0 || !(strings.HasPrefix(gitkey, prefix) && strings.HasSuffix(gitkey, suffix)) {
continue
}
if _, ok := e.aliases[gitval]; ok {
if _, ok := e.aliases[gitval[0]]; ok {
fmt.Fprintf(os.Stderr, "WARNING: Multiple 'url.*.insteadof' keys with the same alias: %q\n", gitval)
}
e.aliases[gitval] = gitkey[len(prefix) : len(gitkey)-len(suffix)]
e.aliases[gitval[0]] = gitkey[len(prefix) : len(gitkey)-len(suffix)]
}
}

@ -7,7 +7,7 @@ import (
)
func TestEndpointDefaultsToOrigin(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.lfsurl": "abc",
}))
@ -18,7 +18,7 @@ func TestEndpointDefaultsToOrigin(t *testing.T) {
}
func TestEndpointOverridesOrigin(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.url": "abc",
"remote.origin.lfsurl": "def",
}))
@ -30,7 +30,7 @@ func TestEndpointOverridesOrigin(t *testing.T) {
}
func TestEndpointNoOverrideDefaultRemote(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.lfsurl": "abc",
"remote.other.lfsurl": "def",
}))
@ -42,7 +42,7 @@ func TestEndpointNoOverrideDefaultRemote(t *testing.T) {
}
func TestEndpointUseAlternateRemote(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.lfsurl": "abc",
"remote.other.lfsurl": "def",
}))
@ -54,7 +54,7 @@ func TestEndpointUseAlternateRemote(t *testing.T) {
}
func TestEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "https://example.com/foo/bar",
}))
@ -65,7 +65,7 @@ func TestEndpointAddsLfsSuffix(t *testing.T) {
}
func TestBareEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "https://example.com/foo/bar.git",
}))
@ -76,7 +76,7 @@ func TestBareEndpointAddsLfsSuffix(t *testing.T) {
}
func TestEndpointSeparateClonePushUrl(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "https://example.com/foo/bar.git",
"remote.origin.pushurl": "https://readwrite.com/foo/bar.git",
}))
@ -93,7 +93,7 @@ func TestEndpointSeparateClonePushUrl(t *testing.T) {
}
func TestEndpointOverriddenSeparateClonePushLfsUrl(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "https://example.com/foo/bar.git",
"remote.origin.pushurl": "https://readwrite.com/foo/bar.git",
"remote.origin.lfsurl": "https://examplelfs.com/foo/bar",
@ -112,7 +112,7 @@ func TestEndpointOverriddenSeparateClonePushLfsUrl(t *testing.T) {
}
func TestEndpointGlobalSeparateLfsPush(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.url": "https://readonly.com/foo/bar",
"lfs.pushurl": "https://write.com/foo/bar",
}))
@ -129,7 +129,7 @@ func TestEndpointGlobalSeparateLfsPush(t *testing.T) {
}
func TestSSHEndpointOverridden(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "git@example.com:foo/bar",
"remote.origin.lfsurl": "lfs",
}))
@ -142,7 +142,7 @@ func TestSSHEndpointOverridden(t *testing.T) {
}
func TestSSHEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "ssh://git@example.com/foo/bar",
}))
@ -154,7 +154,7 @@ func TestSSHEndpointAddsLfsSuffix(t *testing.T) {
}
func TestSSHCustomPortEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "ssh://git@example.com:9000/foo/bar",
}))
@ -166,7 +166,7 @@ func TestSSHCustomPortEndpointAddsLfsSuffix(t *testing.T) {
}
func TestBareSSHEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "git@example.com:foo/bar.git",
}))
@ -178,7 +178,7 @@ func TestBareSSHEndpointAddsLfsSuffix(t *testing.T) {
}
func TestSSHEndpointFromGlobalLfsUrl(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.url": "git@example.com:foo/bar.git",
}))
@ -190,7 +190,7 @@ func TestSSHEndpointFromGlobalLfsUrl(t *testing.T) {
}
func TestHTTPEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "http://example.com/foo/bar",
}))
@ -202,7 +202,7 @@ func TestHTTPEndpointAddsLfsSuffix(t *testing.T) {
}
func TestBareHTTPEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "http://example.com/foo/bar.git",
}))
@ -214,7 +214,7 @@ func TestBareHTTPEndpointAddsLfsSuffix(t *testing.T) {
}
func TestGitEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "git://example.com/foo/bar",
}))
@ -226,7 +226,7 @@ func TestGitEndpointAddsLfsSuffix(t *testing.T) {
}
func TestGitEndpointAddsLfsSuffixWithCustomProtocol(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "git://example.com/foo/bar",
"lfs.gitprotocol": "http",
}))
@ -239,7 +239,7 @@ func TestGitEndpointAddsLfsSuffixWithCustomProtocol(t *testing.T) {
}
func TestBareGitEndpointAddsLfsSuffix(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"remote.origin.url": "git://example.com/foo/bar.git",
}))
@ -266,7 +266,7 @@ func TestAccessConfig(t *testing.T) {
}
for value, expected := range tests {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.url": "http://example.com",
"lfs.http://example.com.access": value,
"lfs.https://example.com.access": "bad",
@ -285,7 +285,7 @@ func TestAccessConfig(t *testing.T) {
// Test again but with separate push url
for value, expected := range tests {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.url": "http://example.com",
"lfs.pushurl": "http://examplepush.com",
"lfs.http://example.com.access": value,
@ -312,7 +312,7 @@ func TestAccessAbsentConfig(t *testing.T) {
}
func TestSetAccess(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{}))
finder := NewEndpointFinder(UniqTestEnv(map[string]string{}))
assert.Equal(t, NoneAccess, finder.AccessFor("http://example.com"))
finder.SetAccess("http://example.com", NTLMAccess)
@ -320,7 +320,7 @@ func TestSetAccess(t *testing.T) {
}
func TestChangeAccess(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.http://example.com.access": "basic",
}))
@ -330,7 +330,7 @@ func TestChangeAccess(t *testing.T) {
}
func TestDeleteAccessWithNone(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.http://example.com.access": "basic",
}))
@ -340,7 +340,7 @@ func TestDeleteAccessWithNone(t *testing.T) {
}
func TestDeleteAccessWithEmptyString(t *testing.T) {
finder := NewEndpointFinder(TestEnv(map[string]string{
finder := NewEndpointFinder(UniqTestEnv(map[string]string{
"lfs.http://example.com.access": "basic",
}))

@ -147,18 +147,79 @@ func DecodeJSON(res *http.Response, obj interface{}) error {
// relies on.
type Env interface {
Get(string) (string, bool)
GetAll(string) []string
Int(string, int) int
Bool(string, bool) bool
All() map[string]string
All() map[string][]string
}
type UniqTestEnv map[string]string
func (e UniqTestEnv) Get(key string) (v string, ok bool) {
v, ok = e[key]
return
}
func (e UniqTestEnv) GetAll(key string) []string {
if v, ok := e.Get(key); ok {
return []string{v}
}
return make([]string, 0)
}
func (e UniqTestEnv) Int(key string, def int) (val int) {
s, _ := e.Get(key)
if len(s) == 0 {
return def
}
i, err := strconv.Atoi(s)
if err != nil {
return def
}
return i
}
func (e UniqTestEnv) Bool(key string, def bool) (val bool) {
s, _ := e.Get(key)
if len(s) == 0 {
return def
}
switch strings.ToLower(s) {
case "true", "1", "on", "yes", "t":
return true
case "false", "0", "off", "no", "f":
return false
default:
return false
}
}
func (e UniqTestEnv) All() map[string][]string {
m := make(map[string][]string)
for k, _ := range e {
m[k] = e.GetAll(k)
}
return m
}
// TestEnv is a basic config.Environment implementation. Only used in tests, or
// as a zero value to NewClient().
type TestEnv map[string]string
type TestEnv map[string][]string
func (e TestEnv) Get(key string) (string, bool) {
v, ok := e[key]
return v, ok
all := e.GetAll(key)
if len(all) == 0 {
return "", false
}
return all[0], true
}
func (e TestEnv) GetAll(key string) []string {
return e[key]
}
func (e TestEnv) Int(key string, def int) (val int) {
@ -191,6 +252,6 @@ func (e TestEnv) Bool(key string, def bool) (val bool) {
}
}
func (e TestEnv) All() map[string]string {
func (e TestEnv) All() map[string][]string {
return e
}

@ -77,7 +77,7 @@ func TestNTLMAuth(t *testing.T) {
require.Nil(t, err)
credHelper := newMockCredentialHelper()
cli, err := NewClient(nil, TestEnv(map[string]string{
cli, err := NewClient(nil, UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/ntlm",
"lfs." + srv.URL + "/ntlm.access": "ntlm",
}))

@ -9,9 +9,9 @@ import (
)
func TestProxyFromGitConfig(t *testing.T) {
c, err := NewClient(TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{
"HTTPS_PROXY": "https://proxy-from-env:8080",
}), TestEnv(map[string]string{
}), UniqTestEnv(map[string]string{
"http.proxy": "https://proxy-from-git-config:8080",
}))
require.Nil(t, err)
@ -25,9 +25,9 @@ func TestProxyFromGitConfig(t *testing.T) {
}
func TestHttpProxyFromGitConfig(t *testing.T) {
c, err := NewClient(TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{
"HTTPS_PROXY": "https://proxy-from-env:8080",
}), TestEnv(map[string]string{
}), UniqTestEnv(map[string]string{
"http.proxy": "http://proxy-from-git-config:8080",
}))
require.Nil(t, err)
@ -41,7 +41,7 @@ func TestHttpProxyFromGitConfig(t *testing.T) {
}
func TestProxyFromEnvironment(t *testing.T) {
c, err := NewClient(TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{
"HTTPS_PROXY": "https://proxy-from-env:8080",
}), nil)
require.Nil(t, err)
@ -66,9 +66,9 @@ func TestProxyIsNil(t *testing.T) {
}
func TestProxyNoProxy(t *testing.T) {
c, err := NewClient(TestEnv(map[string]string{
c, err := NewClient(UniqTestEnv(map[string]string{
"NO_PROXY": "some-host",
}), TestEnv(map[string]string{
}), UniqTestEnv(map[string]string{
"http.proxy": "https://proxy-from-git-config:8080",
}))
require.Nil(t, err)

@ -212,7 +212,7 @@ func (r *fakeResolver) Resolve(e Endpoint, method string) (sshAuthResponse, erro
}
func TestSSHGetLFSExeAndArgs(t *testing.T) {
cli, err := NewClient(TestEnv(map[string]string{}), nil)
cli, err := NewClient(UniqTestEnv(map[string]string{}), nil)
require.Nil(t, err)
endpoint := cli.Endpoints.Endpoint("download", "")
@ -251,7 +251,7 @@ func TestSSHGetLFSExeAndArgs(t *testing.T) {
}
func TestSSHGetExeAndArgsSsh(t *testing.T) {
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "",
"GIT_SSH": "",
}), nil)
@ -266,7 +266,7 @@ func TestSSHGetExeAndArgsSsh(t *testing.T) {
}
func TestSSHGetExeAndArgsSshCustomPort(t *testing.T) {
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "",
"GIT_SSH": "",
}), nil)
@ -284,7 +284,7 @@ func TestSSHGetExeAndArgsSshCustomPort(t *testing.T) {
func TestSSHGetExeAndArgsPlink(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "plink.exe")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "",
"GIT_SSH": plink,
}), nil)
@ -301,7 +301,7 @@ func TestSSHGetExeAndArgsPlink(t *testing.T) {
func TestSSHGetExeAndArgsPlinkCustomPort(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "plink")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "",
"GIT_SSH": plink,
}), nil)
@ -319,7 +319,7 @@ func TestSSHGetExeAndArgsPlinkCustomPort(t *testing.T) {
func TestSSHGetExeAndArgsTortoisePlink(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink.exe")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "",
"GIT_SSH": plink,
}), nil)
@ -336,7 +336,7 @@ func TestSSHGetExeAndArgsTortoisePlink(t *testing.T) {
func TestSSHGetExeAndArgsTortoisePlinkCustomPort(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "",
"GIT_SSH": plink,
}), nil)
@ -352,7 +352,7 @@ func TestSSHGetExeAndArgsTortoisePlinkCustomPort(t *testing.T) {
}
func TestSSHGetExeAndArgsSshCommandPrecedence(t *testing.T) {
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "sshcmd",
"GIT_SSH": "bad",
}), nil)
@ -367,7 +367,7 @@ func TestSSHGetExeAndArgsSshCommandPrecedence(t *testing.T) {
}
func TestSSHGetExeAndArgsSshCommandArgs(t *testing.T) {
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "sshcmd --args 1",
}), nil)
require.Nil(t, err)
@ -381,7 +381,7 @@ func TestSSHGetExeAndArgsSshCommandArgs(t *testing.T) {
}
func TestSSHGetExeAndArgsSshCommandArgsWithMixedQuotes(t *testing.T) {
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "sshcmd foo 'bar \"baz\"'",
}), nil)
require.Nil(t, err)
@ -395,7 +395,7 @@ func TestSSHGetExeAndArgsSshCommandArgsWithMixedQuotes(t *testing.T) {
}
func TestSSHGetExeAndArgsSshCommandCustomPort(t *testing.T) {
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": "sshcmd",
}), nil)
require.Nil(t, err)
@ -412,7 +412,7 @@ func TestSSHGetExeAndArgsSshCommandCustomPort(t *testing.T) {
func TestSSHGetExeAndArgsPlinkCommand(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "plink.exe")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": plink,
}), nil)
require.Nil(t, err)
@ -428,7 +428,7 @@ func TestSSHGetExeAndArgsPlinkCommand(t *testing.T) {
func TestSSHGetExeAndArgsPlinkCommandCustomPort(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "plink")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": plink,
}), nil)
require.Nil(t, err)
@ -445,7 +445,7 @@ func TestSSHGetExeAndArgsPlinkCommandCustomPort(t *testing.T) {
func TestSSHGetExeAndArgsTortoisePlinkCommand(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink.exe")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": plink,
}), nil)
require.Nil(t, err)
@ -461,7 +461,7 @@ func TestSSHGetExeAndArgsTortoisePlinkCommand(t *testing.T) {
func TestSSHGetExeAndArgsTortoisePlinkCommandCustomPort(t *testing.T) {
plink := filepath.Join("Users", "joebloggs", "bin", "tortoiseplink")
cli, err := NewClient(TestEnv(map[string]string{
cli, err := NewClient(UniqTestEnv(map[string]string{
"GIT_SSH_COMMAND": plink,
}), nil)
require.Nil(t, err)

@ -52,7 +52,7 @@ func TestAPILock(t *testing.T) {
}))
defer srv.Close()
c, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
c, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
}))
require.Nil(t, err)
@ -100,7 +100,7 @@ func TestAPIUnlock(t *testing.T) {
}))
defer srv.Close()
c, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
c, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
}))
require.Nil(t, err)
@ -144,7 +144,7 @@ func TestAPISearch(t *testing.T) {
}))
defer srv.Close()
c, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
c, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
}))
require.Nil(t, err)
@ -199,7 +199,7 @@ func TestAPIVerifiableLocks(t *testing.T) {
}))
defer srv.Close()
c, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
c, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
}))
require.Nil(t, err)

@ -48,7 +48,7 @@ func TestRefreshCache(t *testing.T) {
srv.Close()
}()
lfsclient, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
lfsclient, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
"user.name": "Fred",
"user.email": "fred@bloggs.com",
@ -119,7 +119,7 @@ func TestGetVerifiableLocks(t *testing.T) {
defer srv.Close()
lfsclient, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
lfsclient, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
"user.name": "Fred",
"user.email": "fred@bloggs.com",

@ -19,6 +19,9 @@ begin_test "default config"
git lfs env | tee env.log
grep "Endpoint=http://lfsconfig-file (auth=lfsconfig)" env.log
git config --file=.lfsconfig --unset lfs.url
git config --file=.lfsconfig --unset lfs.http://lfsconfig-file.access
# new endpoint url from local git config
# access setting no longer applied
git config lfs.url http://local-lfsconfig
@ -30,6 +33,8 @@ begin_test "default config"
git lfs env | tee env.log
grep "Endpoint=http://local-lfsconfig (auth=lfsconfig)" env.log
git config --file=.lfsconfig --unset lfs.http://local-lfsconfig.access
# add the access setting to git config
git config lfs.http://local-lfsconfig.access gitconfig
git lfs env | tee env.log

@ -54,7 +54,7 @@ func TestAPIBatch(t *testing.T) {
}))
defer srv.Close()
c, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
c, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
}))
require.Nil(t, err)
@ -110,7 +110,7 @@ func TestAPIBatchOnlyBasic(t *testing.T) {
}))
defer srv.Close()
c, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
c, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": srv.URL + "/api",
}))
require.Nil(t, err)

@ -345,14 +345,14 @@ func newCustomAdapter(name string, dir Direction, path, args string, concurrent
// Initialise custom adapters based on current config
func configureCustomAdapters(git Env, m *Manifest) {
pathRegex := regexp.MustCompile(`lfs.customtransfer.([^.]+).path`)
for k, v := range git.All() {
for k, _ := range git.All() {
match := pathRegex.FindStringSubmatch(k)
if match == nil {
continue
}
name := match[1]
path := v
path, _ := git.Get(k)
// retrieve other values
args, _ := git.Get(fmt.Sprintf("lfs.customtransfer.%s.args", name))
concurrent := git.Bool(fmt.Sprintf("lfs.customtransfer.%s.concurrent", name), true)

@ -10,7 +10,7 @@ import (
func TestCustomTransferBasicConfig(t *testing.T) {
path := "/path/to/binary"
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.customtransfer.testsimple.path": path,
}))
require.Nil(t, err)
@ -36,7 +36,7 @@ func TestCustomTransferBasicConfig(t *testing.T) {
func TestCustomTransferDownloadConfig(t *testing.T) {
path := "/path/to/binary"
args := "-c 1 --whatever"
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.customtransfer.testdownload.path": path,
"lfs.customtransfer.testdownload.args": args,
"lfs.customtransfer.testdownload.concurrent": "false",
@ -62,7 +62,7 @@ func TestCustomTransferDownloadConfig(t *testing.T) {
func TestCustomTransferUploadConfig(t *testing.T) {
path := "/path/to/binary"
args := "-c 1 --whatever"
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.customtransfer.testupload.path": path,
"lfs.customtransfer.testupload.args": args,
"lfs.customtransfer.testupload.concurrent": "false",
@ -88,7 +88,7 @@ func TestCustomTransferUploadConfig(t *testing.T) {
func TestCustomTransferBothConfig(t *testing.T) {
path := "/path/to/binary"
args := "-c 1 --whatever --yeah"
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.customtransfer.testboth.path": path,
"lfs.customtransfer.testboth.args": args,
"lfs.customtransfer.testboth.concurrent": "yes",

@ -186,7 +186,8 @@ func (m *Manifest) NewUploadAdapter(name string) Adapter {
// Env is any object with a config.Environment interface.
type Env interface {
Get(key string) (val string, ok bool)
GetAll(key string) []string
Bool(key string, def bool) (val bool)
Int(key string, def int) (val int)
All() map[string]string
All() map[string][]string
}

@ -9,7 +9,7 @@ import (
)
func TestManifestIsConfigurable(t *testing.T) {
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.transfer.maxretries": "3",
}))
require.Nil(t, err)
@ -19,7 +19,7 @@ func TestManifestIsConfigurable(t *testing.T) {
}
func TestManifestChecksNTLM(t *testing.T) {
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.url": "http://foo",
"lfs.http://foo.access": "ntlm",
"lfs.concurrenttransfers": "3",
@ -31,7 +31,7 @@ func TestManifestChecksNTLM(t *testing.T) {
}
func TestManifestClampsValidValues(t *testing.T) {
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.transfer.maxretries": "-1",
}))
require.Nil(t, err)
@ -41,7 +41,7 @@ func TestManifestClampsValidValues(t *testing.T) {
}
func TestManifestIgnoresNonInts(t *testing.T) {
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.transfer.maxretries": "not_an_int",
}))
require.Nil(t, err)

@ -118,7 +118,7 @@ func testAdapterRegAndOverride(t *testing.T) {
}
func testAdapterRegButBasicOnly(t *testing.T) {
cli, err := lfsapi.NewClient(nil, lfsapi.TestEnv(map[string]string{
cli, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv(map[string]string{
"lfs.basictransfersonly": "yes",
}))
require.Nil(t, err)

@ -44,7 +44,7 @@ func TestVerifySuccess(t *testing.T) {
}))
defer srv.Close()
c, err := lfsapi.NewClient(nil, lfsapi.TestEnv{
c, err := lfsapi.NewClient(nil, lfsapi.UniqTestEnv{
"lfs.transfer.maxverifies": "1",
})
require.Nil(t, err)