pkg/cfgstruct: add pflag support to bind (#2425)
This commit is contained in:
parent
6d55bbdb57
commit
9e26149a2d
@ -16,7 +16,6 @@ import (
|
||||
"github.com/spf13/pflag"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"storj.io/storj/internal/memory"
|
||||
"storj.io/storj/internal/version"
|
||||
)
|
||||
|
||||
@ -139,6 +138,37 @@ func bindConfig(flags FlagSet, prefix string, val reflect.Value, vars map[string
|
||||
continue
|
||||
}
|
||||
|
||||
fieldaddr := fieldval.Addr().Interface()
|
||||
if fieldvalue, ok := fieldaddr.(pflag.Value); ok {
|
||||
help := field.Tag.Get("help")
|
||||
var def string
|
||||
if isDev {
|
||||
def = getDefault(field.Tag, "devDefault", "releaseDefault", "default", flagname)
|
||||
} else {
|
||||
def = getDefault(field.Tag, "releaseDefault", "devDefault", "default", flagname)
|
||||
}
|
||||
|
||||
err := fieldvalue.Set(def)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("invalid default value for %s: %#v, %v", flagname, def, err))
|
||||
}
|
||||
flags.Var(fieldvalue, flagname, help)
|
||||
|
||||
if onlyForSetup {
|
||||
setBoolAnnotation(flags, flagname, "setup")
|
||||
}
|
||||
if field.Tag.Get("user") == "true" {
|
||||
setBoolAnnotation(flags, flagname, "user")
|
||||
}
|
||||
if field.Tag.Get("hidden") == "true" {
|
||||
err := flags.MarkHidden(flagname)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("mark hidden failed %s: %v", flagname, err))
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
switch field.Type.Kind() {
|
||||
case reflect.Struct:
|
||||
if field.Anonymous {
|
||||
@ -167,9 +197,6 @@ func bindConfig(flags FlagSet, prefix string, val reflect.Value, vars map[string
|
||||
}
|
||||
}
|
||||
switch field.Type {
|
||||
case reflect.TypeOf(memory.Size(0)):
|
||||
check(fieldaddr.(*memory.Size).Set(def))
|
||||
flags.Var(fieldaddr.(*memory.Size), flagname, help)
|
||||
case reflect.TypeOf(int(0)):
|
||||
val, err := strconv.ParseInt(def, 0, strconv.IntSize)
|
||||
check(err)
|
||||
|
@ -10,6 +10,10 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"storj.io/storj/internal/memory"
|
||||
"storj.io/storj/pkg/storj"
|
||||
)
|
||||
|
||||
func assertEqual(actual, expected interface{}) {
|
||||
@ -21,14 +25,17 @@ func assertEqual(actual, expected interface{}) {
|
||||
func TestBind(t *testing.T) {
|
||||
f := pflag.NewFlagSet("test", pflag.PanicOnError)
|
||||
var c struct {
|
||||
String string `default:""`
|
||||
Bool bool `releaseDefault:"false" devDefault:"true"`
|
||||
Int64 int64 `releaseDefault:"0" devDefault:"1"`
|
||||
Int int `default:"0"`
|
||||
Uint64 uint64 `default:"0"`
|
||||
Uint uint `default:"0"`
|
||||
Float64 float64 `default:"0"`
|
||||
Duration time.Duration `default:"0"`
|
||||
String string `default:""`
|
||||
Bool bool `releaseDefault:"false" devDefault:"true"`
|
||||
Int64 int64 `releaseDefault:"0" devDefault:"1"`
|
||||
Int int `default:"0"`
|
||||
Uint64 uint64 `default:"0"`
|
||||
Uint uint `default:"0"`
|
||||
Float64 float64 `default:"0"`
|
||||
Size memory.Size `default:"0"`
|
||||
Duration time.Duration `default:"0"`
|
||||
NodeURL storj.NodeURL `releaseDefault:"" devDefault:""`
|
||||
NodeURLs storj.NodeURLs `releaseDefault:"" devDefault:""`
|
||||
Struct struct {
|
||||
AnotherString string `default:""`
|
||||
}
|
||||
@ -45,11 +52,20 @@ func TestBind(t *testing.T) {
|
||||
assertEqual(c.Uint64, uint64(0))
|
||||
assertEqual(c.Uint, uint(0))
|
||||
assertEqual(c.Float64, float64(0))
|
||||
assertEqual(c.Size, memory.Size(0))
|
||||
assertEqual(c.Duration, time.Duration(0))
|
||||
assertEqual(c.NodeURL, storj.NodeURL{})
|
||||
assertEqual(c.NodeURLs, storj.NodeURLs(nil))
|
||||
assertEqual(c.Struct.AnotherString, string(""))
|
||||
assertEqual(c.Fields[0].AnotherInt, int(0))
|
||||
assertEqual(c.Fields[3].AnotherInt, int(0))
|
||||
err := f.Parse([]string{
|
||||
|
||||
node1, err := storj.NodeIDFromString("12EayRS2V1kEsWESU9QMRseFhdxYxKicsiFmxrsLZHeLUtdps3S")
|
||||
require.NoError(t, err)
|
||||
node2, err := storj.NodeIDFromString("12L9ZFwhzVpuEKMUNUqkaTLGzwY9G24tbiigLiXpmZWKwmcNDDs")
|
||||
require.NoError(t, err)
|
||||
|
||||
err = f.Parse([]string{
|
||||
"--string=1",
|
||||
"--bool=true",
|
||||
"--int64=1",
|
||||
@ -57,7 +73,10 @@ func TestBind(t *testing.T) {
|
||||
"--uint64=1",
|
||||
"--uint=1",
|
||||
"--float64=1",
|
||||
"--size=1MiB",
|
||||
"--duration=1h",
|
||||
"--node-url=12EayRS2V1kEsWESU9QMRseFhdxYxKicsiFmxrsLZHeLUtdps3S@mars.tardigrade.io:7777",
|
||||
"--node-ur-ls=12EayRS2V1kEsWESU9QMRseFhdxYxKicsiFmxrsLZHeLUtdps3S@mars.tardigrade.io:7777,12L9ZFwhzVpuEKMUNUqkaTLGzwY9G24tbiigLiXpmZWKwmcNDDs@jupiter.tardigrade.io:7777",
|
||||
"--struct.another-string=1",
|
||||
"--fields.03.another-int=1"})
|
||||
if err != nil {
|
||||
@ -70,7 +89,13 @@ func TestBind(t *testing.T) {
|
||||
assertEqual(c.Uint64, uint64(1))
|
||||
assertEqual(c.Uint, uint(1))
|
||||
assertEqual(c.Float64, float64(1))
|
||||
assertEqual(c.Size, memory.MiB)
|
||||
assertEqual(c.Duration, time.Hour)
|
||||
assertEqual(c.NodeURL, storj.NodeURL{ID: node1, Address: "mars.tardigrade.io:7777"})
|
||||
assertEqual(c.NodeURLs, storj.NodeURLs{
|
||||
storj.NodeURL{ID: node1, Address: "mars.tardigrade.io:7777"},
|
||||
storj.NodeURL{ID: node2, Address: "jupiter.tardigrade.io:7777"},
|
||||
})
|
||||
assertEqual(c.Struct.AnotherString, string("1"))
|
||||
assertEqual(c.Fields[0].AnotherInt, int(0))
|
||||
assertEqual(c.Fields[3].AnotherInt, int(1))
|
||||
@ -154,11 +179,12 @@ func TestBindDevDefaults(t *testing.T) {
|
||||
func TestHiddenDev(t *testing.T) {
|
||||
f := pflag.NewFlagSet("test", pflag.PanicOnError)
|
||||
var c struct {
|
||||
String string `default:"dev" hidden:"true"`
|
||||
String2 string `default:"dev" hidden:"false"`
|
||||
Bool bool `releaseDefault:"false" devDefault:"true" hidden:"true"`
|
||||
Int64 int64 `releaseDefault:"0" devDefault:"1"`
|
||||
Int int `default:"2"`
|
||||
String string `default:"dev" hidden:"true"`
|
||||
String2 string `default:"dev" hidden:"false"`
|
||||
Bool bool `releaseDefault:"false" devDefault:"true" hidden:"true"`
|
||||
Int64 int64 `releaseDefault:"0" devDefault:"1"`
|
||||
Int int `default:"2"`
|
||||
Size memory.Size `default:"0" hidden:"true"`
|
||||
}
|
||||
Bind(f, &c, UseDevDefaults())
|
||||
|
||||
@ -167,11 +193,13 @@ func TestHiddenDev(t *testing.T) {
|
||||
flagBool := f.Lookup("bool")
|
||||
flagInt64 := f.Lookup("int64")
|
||||
flagInt := f.Lookup("int")
|
||||
flagSize := f.Lookup("size")
|
||||
assertEqual(flagString.Hidden, true)
|
||||
assertEqual(flagStringHide.Hidden, false)
|
||||
assertEqual(flagBool.Hidden, true)
|
||||
assertEqual(flagInt64.Hidden, false)
|
||||
assertEqual(flagInt.Hidden, false)
|
||||
assertEqual(flagSize.Hidden, true)
|
||||
}
|
||||
|
||||
func TestHiddenRelease(t *testing.T) {
|
||||
|
@ -37,7 +37,7 @@ type NodeURL struct {
|
||||
// 12vha9oTFnerxYRgeQ2BZqoFrLrnmmf5UWTCY2jA77dF3YvWew7@
|
||||
func ParseNodeURL(s string) (NodeURL, error) {
|
||||
if s == "" {
|
||||
return NodeURL{}, ErrNodeURL.New("empty string")
|
||||
return NodeURL{}, nil
|
||||
}
|
||||
if !strings.HasPrefix(s, "storj://") {
|
||||
if strings.Index(s, "://") < 0 {
|
||||
@ -65,6 +65,11 @@ func ParseNodeURL(s string) (NodeURL, error) {
|
||||
return node, nil
|
||||
}
|
||||
|
||||
// IsZero returns whether tthe url is empty.
|
||||
func (url NodeURL) IsZero() bool {
|
||||
return url == NodeURL{}
|
||||
}
|
||||
|
||||
// String converts NodeURL to a string
|
||||
func (url NodeURL) String() string {
|
||||
if url.ID.IsZero() {
|
||||
@ -84,6 +89,9 @@ func (url *NodeURL) Set(s string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type implements pflag.Value
|
||||
func (NodeURL) Type() string { return "storj.NodeURL" }
|
||||
|
||||
// NodeURLs defines a comma delimited flag for defining a list node url-s.
|
||||
type NodeURLs []NodeURL
|
||||
|
||||
@ -124,3 +132,6 @@ func (urls *NodeURLs) Set(s string) error {
|
||||
*urls = parsed
|
||||
return nil
|
||||
}
|
||||
|
||||
// Type implements pflag.Value
|
||||
func (NodeURLs) Type() string { return "storj.NodeURLs" }
|
||||
|
@ -24,6 +24,7 @@ func TestNodeURL(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, testcase := range []Test{
|
||||
{"", storj.NodeURL{}},
|
||||
// host
|
||||
{"33.20.0.1:7777", storj.NodeURL{emptyID, "33.20.0.1:7777"}},
|
||||
{"[2001:db8:1f70::999:de8:7648:6e8]:7777", storj.NodeURL{emptyID, "[2001:db8:1f70::999:de8:7648:6e8]:7777"}},
|
||||
@ -45,7 +46,6 @@ func TestNodeURL(t *testing.T) {
|
||||
|
||||
t.Run("Invalid", func(t *testing.T) {
|
||||
for _, testcase := range []string{
|
||||
"",
|
||||
// invalid host
|
||||
"exampl e.com:7777",
|
||||
// invalid node id
|
||||
|
Loading…
Reference in New Issue
Block a user