mirror of
https://github.com/rclone/rclone.git
synced 2025-01-19 12:12:46 +08:00
fs: check the names and types of the options blocks are correct
This commit is contained in:
parent
2e653f8128
commit
0d9d0eef4c
|
@ -8,12 +8,14 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"regexp"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/rclone/rclone/fs/config/configmap"
|
"github.com/rclone/rclone/fs/config/configmap"
|
||||||
"github.com/rclone/rclone/fs/config/configstruct"
|
"github.com/rclone/rclone/fs/config/configstruct"
|
||||||
|
"github.com/rclone/rclone/lib/errcount"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registry of filesystems
|
// Registry of filesystems
|
||||||
|
@ -416,6 +418,61 @@ var OptionsRegistry = map[string]OptionsInfo{}
|
||||||
// Packages which need global options should use this in an init() function
|
// Packages which need global options should use this in an init() function
|
||||||
func RegisterGlobalOptions(oi OptionsInfo) {
|
func RegisterGlobalOptions(oi OptionsInfo) {
|
||||||
OptionsRegistry[oi.Name] = oi
|
OptionsRegistry[oi.Name] = oi
|
||||||
|
if oi.Opt != nil && oi.Options != nil {
|
||||||
|
err := oi.Check()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var optionName = regexp.MustCompile(`^[a-z0-9_]+$`)
|
||||||
|
|
||||||
|
// Check ensures that for every element of oi.Options there is a field
|
||||||
|
// in oi.Opt that matches it
|
||||||
|
func (oi *OptionsInfo) Check() error {
|
||||||
|
errCount := errcount.New()
|
||||||
|
items, err := configstruct.Items(oi.Opt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
itemsByName := map[string]*configstruct.Item{}
|
||||||
|
for i := range items {
|
||||||
|
item := &items[i]
|
||||||
|
itemsByName[item.Name] = item
|
||||||
|
if !optionName.MatchString(item.Name) {
|
||||||
|
err = fmt.Errorf("invalid name in `config:%q` in Options struct", item.Name)
|
||||||
|
errCount.Add(err)
|
||||||
|
Errorf(nil, "%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i := range oi.Options {
|
||||||
|
option := &oi.Options[i]
|
||||||
|
// Check name is correct
|
||||||
|
if !optionName.MatchString(option.Name) {
|
||||||
|
err = fmt.Errorf("invalid Name: %q", option.Name)
|
||||||
|
errCount.Add(err)
|
||||||
|
Errorf(nil, "%s", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Check item exists
|
||||||
|
item, found := itemsByName[option.Name]
|
||||||
|
if !found {
|
||||||
|
err = fmt.Errorf("key %q in OptionsInfo not found in Options struct", option.Name)
|
||||||
|
errCount.Add(err)
|
||||||
|
Errorf(nil, "%s", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Check type
|
||||||
|
optType := fmt.Sprintf("%T", option.Default)
|
||||||
|
itemType := fmt.Sprintf("%T", item.Value)
|
||||||
|
if optType != itemType {
|
||||||
|
err = fmt.Errorf("key %q in has type %q in OptionsInfo.Default but type %q in Options struct", option.Name, optType, itemType)
|
||||||
|
//errCount.Add(err)
|
||||||
|
Errorf(nil, "%s", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errCount.Err(fmt.Sprintf("internal error: options block %q", oi.Name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// load the defaults from the options
|
// load the defaults from the options
|
||||||
|
|
Loading…
Reference in New Issue
Block a user