forked from TrueCloudLab/rclone
config: Improve the Provider matching to have a negated match #2140
This makes it easier to make classes of provider in the config.
This commit is contained in:
parent
acd5d4377e
commit
8c3740c2c5
3 changed files with 70 additions and 28 deletions
|
@ -22,6 +22,9 @@ var (
|
||||||
// This is a function pointer to decouple the config
|
// This is a function pointer to decouple the config
|
||||||
// implementation from the fs
|
// implementation from the fs
|
||||||
CountError = func(err error) {}
|
CountError = func(err error) {}
|
||||||
|
|
||||||
|
// ConfigProvider is the config key used for provider options
|
||||||
|
ConfigProvider = "provider"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ConfigInfo is filesystem config options
|
// ConfigInfo is filesystem config options
|
||||||
|
|
|
@ -683,9 +683,39 @@ func RemoteConfig(name string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// matchProvider returns true if provider matches the providerConfig string.
|
||||||
|
//
|
||||||
|
// The providerConfig string can either be a list of providers to
|
||||||
|
// match, or if it starts with "!" it will be a list of providers not
|
||||||
|
// to match.
|
||||||
|
//
|
||||||
|
// If either providerConfig or provider is blank then it will return true
|
||||||
|
func matchProvider(providerConfig, provider string) bool {
|
||||||
|
if providerConfig == "" || provider == "" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
negate := false
|
||||||
|
if strings.HasPrefix(providerConfig, "!") {
|
||||||
|
providerConfig = providerConfig[1:]
|
||||||
|
negate = true
|
||||||
|
}
|
||||||
|
providers := strings.Split(providerConfig, ",")
|
||||||
|
matched := false
|
||||||
|
for _, p := range providers {
|
||||||
|
if p == provider {
|
||||||
|
matched = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if negate {
|
||||||
|
return !matched
|
||||||
|
}
|
||||||
|
return matched
|
||||||
|
}
|
||||||
|
|
||||||
// ChooseOption asks the user to choose an option
|
// ChooseOption asks the user to choose an option
|
||||||
func ChooseOption(o *fs.Option, name string) string {
|
func ChooseOption(o *fs.Option, name string) string {
|
||||||
var subProvider = getConfigData().MustValue(name, "Provider", "")
|
var subProvider = getConfigData().MustValue(name, fs.ConfigProvider, "")
|
||||||
fmt.Println(o.Help)
|
fmt.Println(o.Help)
|
||||||
if o.IsPassword {
|
if o.IsPassword {
|
||||||
actions := []string{"yYes type in my own password", "gGenerate random password"}
|
actions := []string{"yYes type in my own password", "gGenerate random password"}
|
||||||
|
@ -727,14 +757,7 @@ func ChooseOption(o *fs.Option, name string) string {
|
||||||
var values []string
|
var values []string
|
||||||
var help []string
|
var help []string
|
||||||
for _, example := range o.Examples {
|
for _, example := range o.Examples {
|
||||||
if example.Provider != "" {
|
if matchProvider(example.Provider, subProvider) {
|
||||||
if strings.Contains(example.Provider, subProvider) {
|
|
||||||
values = append(values, example.Value)
|
|
||||||
help = append(help, example.Help)
|
|
||||||
} else {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
values = append(values, example.Value)
|
values = append(values, example.Value)
|
||||||
help = append(help, example.Help)
|
help = append(help, example.Help)
|
||||||
}
|
}
|
||||||
|
@ -848,14 +871,10 @@ func NewRemoteName() (name string) {
|
||||||
func NewRemote(name string) {
|
func NewRemote(name string) {
|
||||||
newType := ChooseOption(fsOption(), name)
|
newType := ChooseOption(fsOption(), name)
|
||||||
getConfigData().SetValue(name, "type", newType)
|
getConfigData().SetValue(name, "type", newType)
|
||||||
fs := fs.MustFind(newType)
|
ri := fs.MustFind(newType)
|
||||||
for _, option := range fs.Options {
|
for _, option := range ri.Options {
|
||||||
var subProvider = getConfigData().MustValue(name, "Provider", "")
|
subProvider := getConfigData().MustValue(name, fs.ConfigProvider, "")
|
||||||
if option.Provider != "" {
|
if matchProvider(option.Provider, subProvider) {
|
||||||
if strings.Contains(option.Provider, subProvider) {
|
|
||||||
getConfigData().SetValue(name, option.Name, ChooseOption(&option, name))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
getConfigData().SetValue(name, option.Name, ChooseOption(&option, name))
|
getConfigData().SetValue(name, option.Name, ChooseOption(&option, name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -864,32 +883,30 @@ func NewRemote(name string) {
|
||||||
SaveConfig()
|
SaveConfig()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
EditRemote(fs, name)
|
EditRemote(ri, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditRemote gets the user to edit a remote
|
// EditRemote gets the user to edit a remote
|
||||||
func EditRemote(fs *fs.RegInfo, name string) {
|
func EditRemote(ri *fs.RegInfo, name string) {
|
||||||
ShowRemote(name)
|
ShowRemote(name)
|
||||||
fmt.Printf("Edit remote\n")
|
fmt.Printf("Edit remote\n")
|
||||||
var subProvider = ""
|
subProvider := getConfigData().MustValue(name, fs.ConfigProvider, "")
|
||||||
for {
|
for {
|
||||||
for _, option := range fs.Options {
|
for _, option := range ri.Options {
|
||||||
key := option.Name
|
key := option.Name
|
||||||
value := FileGet(name, key)
|
value := FileGet(name, key)
|
||||||
if strings.Compare(key, "Provider") == 0 {
|
if !matchProvider(option.Provider, subProvider) {
|
||||||
subProvider = value
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if option.Provider != "" {
|
|
||||||
if !(strings.Contains(option.Provider, subProvider)) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fmt.Printf("Value %q = %q\n", key, value)
|
fmt.Printf("Value %q = %q\n", key, value)
|
||||||
fmt.Printf("Edit? (y/n)>\n")
|
fmt.Printf("Edit? (y/n)>\n")
|
||||||
if Confirm() {
|
if Confirm() {
|
||||||
newValue := ChooseOption(&option, name)
|
newValue := ChooseOption(&option, name)
|
||||||
getConfigData().SetValue(name, key, newValue)
|
getConfigData().SetValue(name, key, newValue)
|
||||||
|
// Update subProvider if it changed
|
||||||
|
if key == fs.ConfigProvider {
|
||||||
|
subProvider = newValue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if OkRemote(name) {
|
if OkRemote(name) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -205,3 +206,24 @@ func hashedKeyCompare(t *testing.T, a, b string, shouldMatch bool) {
|
||||||
assert.NotEqual(t, k1, k2)
|
assert.NotEqual(t, k1, k2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMatchProvider(t *testing.T) {
|
||||||
|
for _, test := range []struct {
|
||||||
|
config string
|
||||||
|
provider string
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{"", "", true},
|
||||||
|
{"one", "one", true},
|
||||||
|
{"one,two", "two", true},
|
||||||
|
{"one,two,three", "two", true},
|
||||||
|
{"one", "on", false},
|
||||||
|
{"one,two,three", "tw", false},
|
||||||
|
{"!one,two,three", "two", false},
|
||||||
|
{"!one,two,three", "four", true},
|
||||||
|
} {
|
||||||
|
what := fmt.Sprintf("%q,%q", test.config, test.provider)
|
||||||
|
got := matchProvider(test.config, test.provider)
|
||||||
|
assert.Equal(t, test.want, got, what)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue