From 9361cba851bd140ac0a90f7620f959690d429b5b Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Tue, 8 Nov 2022 16:27:46 -0500 Subject: [PATCH] Remove local altsrc and references in favor of separate repo at https://github.com/urfave/cli-altsrc --- altsrc/default_input_source.go | 6 - altsrc/flag-spec.yaml | 18 - altsrc/flag.go | 328 -------------- altsrc/flag_generated.go | 277 ------------ altsrc/flag_test.go | 743 ------------------------------- altsrc/helpers_test.go | 31 -- altsrc/input_source_context.go | 28 -- altsrc/json_command_test.go | 329 -------------- altsrc/json_source_context.go | 240 ---------- altsrc/map_input_source.go | 300 ------------- altsrc/map_input_source_test.go | 35 -- altsrc/toml_command_test.go | 305 ------------- altsrc/toml_file_loader.go | 112 ----- altsrc/yaml_command_test.go | 308 ------------- altsrc/yaml_file_loader.go | 89 ---- altsrc/yaml_file_loader_test.go | 87 ---- cmd/urfave-cli-genflags/Makefile | 1 - godoc-current.txt | 355 --------------- internal/build/build.go | 9 +- testdata/godoc-v3.x.txt | 355 --------------- 20 files changed, 2 insertions(+), 3954 deletions(-) delete mode 100644 altsrc/default_input_source.go delete mode 100644 altsrc/flag-spec.yaml delete mode 100644 altsrc/flag.go delete mode 100644 altsrc/flag_generated.go delete mode 100644 altsrc/flag_test.go delete mode 100644 altsrc/helpers_test.go delete mode 100644 altsrc/input_source_context.go delete mode 100644 altsrc/json_command_test.go delete mode 100644 altsrc/json_source_context.go delete mode 100644 altsrc/map_input_source.go delete mode 100644 altsrc/map_input_source_test.go delete mode 100644 altsrc/toml_command_test.go delete mode 100644 altsrc/toml_file_loader.go delete mode 100644 altsrc/yaml_command_test.go delete mode 100644 altsrc/yaml_file_loader.go delete mode 100644 altsrc/yaml_file_loader_test.go diff --git a/altsrc/default_input_source.go b/altsrc/default_input_source.go deleted file mode 100644 index 7fda719..0000000 --- a/altsrc/default_input_source.go +++ /dev/null @@ -1,6 +0,0 @@ -package altsrc - -// defaultInputSource creates a default InputSourceContext. -func defaultInputSource() (InputSourceContext, error) { - return &MapInputSource{file: "", valueMap: map[interface{}]interface{}{}}, nil -} diff --git a/altsrc/flag-spec.yaml b/altsrc/flag-spec.yaml deleted file mode 100644 index 8c7db6f..0000000 --- a/altsrc/flag-spec.yaml +++ /dev/null @@ -1,18 +0,0 @@ -# NOTE: this file is used by the tool defined in -# ./cmd/urfave-cli-genflags/main.go which uses the -# `Spec` type that maps to this file structure. -flag_types: - Bool: - Duration: - Float64: - Generic: - Int64: - Int: - IntSlice: - Int64Slice: - Float64Slice: - String: - Path: - StringSlice: - Uint64: - Uint: \ No newline at end of file diff --git a/altsrc/flag.go b/altsrc/flag.go deleted file mode 100644 index 50ebd9e..0000000 --- a/altsrc/flag.go +++ /dev/null @@ -1,328 +0,0 @@ -package altsrc - -import ( - "fmt" - "path/filepath" - "strconv" - "syscall" - - "github.com/urfave/cli/v3" -) - -// FlagInputSourceExtension is an extension interface of cli.Flag that -// allows a value to be set on the existing parsed flags. -type FlagInputSourceExtension interface { - cli.Flag - ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error -} - -// ApplyInputSourceValues iterates over all provided flags and -// executes ApplyInputSourceValue on flags implementing the -// FlagInputSourceExtension interface to initialize these flags -// to an alternate input source. -func ApplyInputSourceValues(cCtx *cli.Context, inputSourceContext InputSourceContext, flags []cli.Flag) error { - for _, f := range flags { - inputSourceExtendedFlag, isType := f.(FlagInputSourceExtension) - if isType { - err := inputSourceExtendedFlag.ApplyInputSourceValue(cCtx, inputSourceContext) - if err != nil { - return err - } - } - } - - return nil -} - -// InitInputSource is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new -// input source based on the func provided. If there is no error it will then apply the new input source to any flags -// that are supported by the input source -func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) cli.BeforeFunc { - return func(cCtx *cli.Context) error { - inputSource, err := createInputSource() - if err != nil { - return fmt.Errorf("Unable to create input source: inner error: \n'%v'", err.Error()) - } - - return ApplyInputSourceValues(cCtx, inputSource, flags) - } -} - -// InitInputSourceWithContext is used to to setup an InputSourceContext on a cli.Command Before method. It will create a new -// input source based on the func provided with potentially using existing cli.Context values to initialize itself. If there is -// no error it will then apply the new input source to any flags that are supported by the input source -func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *cli.Context) (InputSourceContext, error)) cli.BeforeFunc { - return func(cCtx *cli.Context) error { - inputSource, err := createInputSource(cCtx) - if err != nil { - return fmt.Errorf("Unable to create input source with context: inner error: \n'%v'", err.Error()) - } - - return ApplyInputSourceValues(cCtx, inputSource, flags) - } -} - -// ApplyInputSourceValue applies a generic value to the flagSet if required -func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.GenericFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.Generic(name) - if err != nil { - return err - } - if value == nil { - continue - } - for _, n := range f.Names() { - _ = f.set.Set(n, value.String()) - } - } - - return nil -} - -// ApplyInputSourceValue applies a StringSlice value to the flagSet if required -func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.StringSliceFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.StringSlice(name) - if err != nil { - return err - } - if value == nil { - continue - } - var sliceValue = *(cli.NewStringSlice(value...)) - for _, n := range f.Names() { - underlyingFlag := f.set.Lookup(n) - if underlyingFlag == nil { - continue - } - underlyingFlag.Value = &sliceValue - } - if f.Destination != nil { - f.Destination.Set(sliceValue.Serialize()) - } - } - return nil -} - -// ApplyInputSourceValue applies a IntSlice value if required -func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.IntSliceFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.IntSlice(name) - if err != nil { - return err - } - if value == nil { - continue - } - var sliceValue = *(cli.NewIntSlice(value...)) - for _, n := range f.Names() { - underlyingFlag := f.set.Lookup(n) - if underlyingFlag == nil { - continue - } - underlyingFlag.Value = &sliceValue - } - if f.Destination != nil { - f.Destination.Set(sliceValue.Serialize()) - } - } - return nil -} - -// ApplyInputSourceValue applies a Int64Slice value if required -func (f *Int64SliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.Int64SliceFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.Int64Slice(name) - if err != nil { - return err - } - if value == nil { - continue - } - var sliceValue = *(cli.NewInt64Slice(value...)) - for _, n := range f.Names() { - underlyingFlag := f.set.Lookup(n) - if underlyingFlag == nil { - continue - } - underlyingFlag.Value = &sliceValue - } - if f.Destination != nil { - f.Destination.Set(sliceValue.Serialize()) - } - } - return nil -} - -// ApplyInputSourceValue applies a Bool value to the flagSet if required -func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.BoolFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.Bool(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, strconv.FormatBool(value)) - } - } - return nil -} - -// ApplyInputSourceValue applies a String value to the flagSet if required -func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.StringFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.String(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, value) - } - } - return nil -} - -// ApplyInputSourceValue applies a Path value to the flagSet if required -func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.PathFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.String(name) - if err != nil { - return err - } - if value == "" { - continue - } - for _, n := range f.Names() { - if !filepath.IsAbs(value) && isc.Source() != "" { - basePathAbs, err := filepath.Abs(isc.Source()) - if err != nil { - return err - } - value = filepath.Join(filepath.Dir(basePathAbs), value) - } - _ = f.set.Set(n, value) - } - } - return nil -} - -// ApplyInputSourceValue applies a int value to the flagSet if required -func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.IntFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.Int(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, strconv.FormatInt(int64(value), 10)) - } - } - return nil -} - -// ApplyInputSourceValue applies a Duration value to the flagSet if required -func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.DurationFlag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.Duration(name) - if err != nil { - return err - } - for _, n := range f.Names() { - _ = f.set.Set(n, value.String()) - } - } - return nil -} - -// ApplyInputSourceValue applies a Float64 value to the flagSet if required -func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error { - if f.set == nil || cCtx.IsSet(f.Name) || isEnvVarSet(f.EnvVars) { - return nil - } - for _, name := range f.Float64Flag.Names() { - if !isc.isSet(name) { - continue - } - value, err := isc.Float64(name) - if err != nil { - return err - } - floatStr := float64ToString(value) - for _, n := range f.Names() { - _ = f.set.Set(n, floatStr) - } - } - return nil -} - -func isEnvVarSet(envVars []string) bool { - for _, envVar := range envVars { - if _, ok := syscall.Getenv(envVar); ok { - // TODO: Can't use this for bools as - // set means that it was true or false based on - // Bool flag type, should work for other types - return true - } - } - - return false -} - -func float64ToString(f float64) string { - return fmt.Sprintf("%v", f) -} diff --git a/altsrc/flag_generated.go b/altsrc/flag_generated.go deleted file mode 100644 index 2a521d1..0000000 --- a/altsrc/flag_generated.go +++ /dev/null @@ -1,277 +0,0 @@ -// WARNING: this file is generated. DO NOT EDIT - -package altsrc - -import ( - "flag" - - "github.com/urfave/cli/v3" -) - -// BoolFlag is the flag type that wraps cli.BoolFlag to allow -// for other values to be specified -type BoolFlag struct { - *cli.BoolFlag - set *flag.FlagSet -} - -// NewBoolFlag creates a new BoolFlag -func NewBoolFlag(fl *cli.BoolFlag) *BoolFlag { - return &BoolFlag{BoolFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped BoolFlag.Apply -func (f *BoolFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.BoolFlag.Apply(set) -} - -// DurationFlag is the flag type that wraps cli.DurationFlag to allow -// for other values to be specified -type DurationFlag struct { - *cli.DurationFlag - set *flag.FlagSet -} - -// NewDurationFlag creates a new DurationFlag -func NewDurationFlag(fl *cli.DurationFlag) *DurationFlag { - return &DurationFlag{DurationFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped DurationFlag.Apply -func (f *DurationFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.DurationFlag.Apply(set) -} - -// Float64Flag is the flag type that wraps cli.Float64Flag to allow -// for other values to be specified -type Float64Flag struct { - *cli.Float64Flag - set *flag.FlagSet -} - -// NewFloat64Flag creates a new Float64Flag -func NewFloat64Flag(fl *cli.Float64Flag) *Float64Flag { - return &Float64Flag{Float64Flag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped Float64Flag.Apply -func (f *Float64Flag) Apply(set *flag.FlagSet) error { - f.set = set - return f.Float64Flag.Apply(set) -} - -// Float64SliceFlag is the flag type that wraps cli.Float64SliceFlag to allow -// for other values to be specified -type Float64SliceFlag struct { - *cli.Float64SliceFlag - set *flag.FlagSet -} - -// NewFloat64SliceFlag creates a new Float64SliceFlag -func NewFloat64SliceFlag(fl *cli.Float64SliceFlag) *Float64SliceFlag { - return &Float64SliceFlag{Float64SliceFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped Float64SliceFlag.Apply -func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.Float64SliceFlag.Apply(set) -} - -// GenericFlag is the flag type that wraps cli.GenericFlag to allow -// for other values to be specified -type GenericFlag struct { - *cli.GenericFlag - set *flag.FlagSet -} - -// NewGenericFlag creates a new GenericFlag -func NewGenericFlag(fl *cli.GenericFlag) *GenericFlag { - return &GenericFlag{GenericFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped GenericFlag.Apply -func (f *GenericFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.GenericFlag.Apply(set) -} - -// IntFlag is the flag type that wraps cli.IntFlag to allow -// for other values to be specified -type IntFlag struct { - *cli.IntFlag - set *flag.FlagSet -} - -// NewIntFlag creates a new IntFlag -func NewIntFlag(fl *cli.IntFlag) *IntFlag { - return &IntFlag{IntFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped IntFlag.Apply -func (f *IntFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.IntFlag.Apply(set) -} - -// Int64Flag is the flag type that wraps cli.Int64Flag to allow -// for other values to be specified -type Int64Flag struct { - *cli.Int64Flag - set *flag.FlagSet -} - -// NewInt64Flag creates a new Int64Flag -func NewInt64Flag(fl *cli.Int64Flag) *Int64Flag { - return &Int64Flag{Int64Flag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped Int64Flag.Apply -func (f *Int64Flag) Apply(set *flag.FlagSet) error { - f.set = set - return f.Int64Flag.Apply(set) -} - -// Int64SliceFlag is the flag type that wraps cli.Int64SliceFlag to allow -// for other values to be specified -type Int64SliceFlag struct { - *cli.Int64SliceFlag - set *flag.FlagSet -} - -// NewInt64SliceFlag creates a new Int64SliceFlag -func NewInt64SliceFlag(fl *cli.Int64SliceFlag) *Int64SliceFlag { - return &Int64SliceFlag{Int64SliceFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped Int64SliceFlag.Apply -func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.Int64SliceFlag.Apply(set) -} - -// IntSliceFlag is the flag type that wraps cli.IntSliceFlag to allow -// for other values to be specified -type IntSliceFlag struct { - *cli.IntSliceFlag - set *flag.FlagSet -} - -// NewIntSliceFlag creates a new IntSliceFlag -func NewIntSliceFlag(fl *cli.IntSliceFlag) *IntSliceFlag { - return &IntSliceFlag{IntSliceFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped IntSliceFlag.Apply -func (f *IntSliceFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.IntSliceFlag.Apply(set) -} - -// PathFlag is the flag type that wraps cli.PathFlag to allow -// for other values to be specified -type PathFlag struct { - *cli.PathFlag - set *flag.FlagSet -} - -// NewPathFlag creates a new PathFlag -func NewPathFlag(fl *cli.PathFlag) *PathFlag { - return &PathFlag{PathFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped PathFlag.Apply -func (f *PathFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.PathFlag.Apply(set) -} - -// StringFlag is the flag type that wraps cli.StringFlag to allow -// for other values to be specified -type StringFlag struct { - *cli.StringFlag - set *flag.FlagSet -} - -// NewStringFlag creates a new StringFlag -func NewStringFlag(fl *cli.StringFlag) *StringFlag { - return &StringFlag{StringFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped StringFlag.Apply -func (f *StringFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.StringFlag.Apply(set) -} - -// StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow -// for other values to be specified -type StringSliceFlag struct { - *cli.StringSliceFlag - set *flag.FlagSet -} - -// NewStringSliceFlag creates a new StringSliceFlag -func NewStringSliceFlag(fl *cli.StringSliceFlag) *StringSliceFlag { - return &StringSliceFlag{StringSliceFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped StringSliceFlag.Apply -func (f *StringSliceFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.StringSliceFlag.Apply(set) -} - -// UintFlag is the flag type that wraps cli.UintFlag to allow -// for other values to be specified -type UintFlag struct { - *cli.UintFlag - set *flag.FlagSet -} - -// NewUintFlag creates a new UintFlag -func NewUintFlag(fl *cli.UintFlag) *UintFlag { - return &UintFlag{UintFlag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped UintFlag.Apply -func (f *UintFlag) Apply(set *flag.FlagSet) error { - f.set = set - return f.UintFlag.Apply(set) -} - -// Uint64Flag is the flag type that wraps cli.Uint64Flag to allow -// for other values to be specified -type Uint64Flag struct { - *cli.Uint64Flag - set *flag.FlagSet -} - -// NewUint64Flag creates a new Uint64Flag -func NewUint64Flag(fl *cli.Uint64Flag) *Uint64Flag { - return &Uint64Flag{Uint64Flag: fl, set: nil} -} - -// Apply saves the flagSet for later usage calls, then calls -// the wrapped Uint64Flag.Apply -func (f *Uint64Flag) Apply(set *flag.FlagSet) error { - f.set = set - return f.Uint64Flag.Apply(set) -} - -// vim:ro diff --git a/altsrc/flag_test.go b/altsrc/flag_test.go deleted file mode 100644 index 7f85d74..0000000 --- a/altsrc/flag_test.go +++ /dev/null @@ -1,743 +0,0 @@ -package altsrc - -import ( - "flag" - "fmt" - "os" - "path/filepath" - "runtime" - "strings" - "testing" - "time" - - "github.com/urfave/cli/v3" -) - -type testApplyInputSource struct { - Flag FlagInputSourceExtension - FlagName string - FlagSetName string - Expected string - ContextValueString string - ContextValue flag.Value - EnvVarValue string - EnvVarName string - SourcePath string - MapValue interface{} -} - -type racyInputSource struct { - *MapInputSource -} - -func (ris *racyInputSource) isSet(name string) bool { - if _, ok := ris.MapInputSource.valueMap[name]; ok { - ris.MapInputSource.valueMap[name] = bogus{0} - } - return true -} - -func TestGenericApplyInputSourceValue_Alias(t *testing.T) { - v := &Parser{"abc", "def"} - tis := testApplyInputSource{ - Flag: NewGenericFlag(&cli.GenericFlag{Name: "test", Aliases: []string{"test_alias"}, Value: &Parser{}}), - FlagName: "test_alias", - MapValue: v, - } - c := runTest(t, tis) - expect(t, v, c.Generic("test_alias")) - - c = runRacyTest(t, tis) - refute(t, v, c.Generic("test_alias")) -} - -func TestGenericApplyInputSourceValue(t *testing.T) { - v := &Parser{"abc", "def"} - tis := testApplyInputSource{ - Flag: NewGenericFlag(&cli.GenericFlag{Name: "test", Value: &Parser{}}), - FlagName: "test", - MapValue: v, - } - c := runTest(t, tis) - expect(t, v, c.Generic("test")) - - c = runRacyTest(t, tis) - refute(t, v, c.Generic("test")) -} - -func TestGenericApplyInputSourceMethodContextSet(t *testing.T) { - p := &Parser{"abc", "def"} - tis := testApplyInputSource{ - Flag: NewGenericFlag(&cli.GenericFlag{Name: "test", Value: &Parser{}}), - FlagName: "test", - MapValue: &Parser{"efg", "hig"}, - ContextValueString: p.String(), - } - c := runTest(t, tis) - expect(t, p, c.Generic("test")) - - c = runRacyTest(t, tis) - refute(t, p, c.Generic("test")) -} - -func TestGenericApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewGenericFlag(&cli.GenericFlag{ - Name: "test", - Value: &Parser{}, - EnvVars: []string{"TEST"}, - }), - FlagName: "test", - MapValue: &Parser{"efg", "hij"}, - EnvVarName: "TEST", - EnvVarValue: "abc,def", - } - c := runTest(t, tis) - expect(t, &Parser{"abc", "def"}, c.Generic("test")) - - c = runRacyTest(t, tis) - refute(t, &Parser{"abc", "def"}, c.Generic("test")) -} - -func TestStringSliceApplyInputSourceValue_Alias(t *testing.T) { - dest := cli.NewStringSlice() - tis := testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), - FlagName: "test_alias", - MapValue: []interface{}{"hello", "world"}, - } - c := runTest(t, tis) - expect(t, c.StringSlice("test_alias"), []string{"hello", "world"}) - expect(t, dest.Value(), []string{"hello", "world"}) - - // reset dest - dest = cli.NewStringSlice() - tis = testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), - FlagName: "test_alias", - MapValue: []interface{}{"hello", "world"}, - } - c = runRacyTest(t, tis) - refute(t, c.StringSlice("test_alias"), []string{"hello", "world"}) - refute(t, dest.Value(), []string{"hello", "world"}) -} - -func TestStringSliceApplyInputSourceValue(t *testing.T) { - dest := cli.NewStringSlice() - tis := testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{"hello", "world"}, - } - c := runTest(t, tis) - expect(t, c.StringSlice("test"), []string{"hello", "world"}) - expect(t, dest.Value(), []string{"hello", "world"}) - - // reset dest - dest = cli.NewStringSlice() - tis = testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{"hello", "world"}, - } - c = runRacyTest(t, tis) - refute(t, c.StringSlice("test"), []string{"hello", "world"}) - refute(t, dest.Value(), []string{"hello", "world"}) -} - -func TestStringSliceApplyInputSourceMethodContextSet(t *testing.T) { - dest := cli.NewStringSlice() - c := runTest(t, testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{"hello", "world"}, - ContextValueString: "ohno", - }) - expect(t, c.StringSlice("test"), []string{"ohno"}) - expect(t, dest.Value(), []string{"ohno"}) -} - -func TestStringSliceApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewStringSliceFlag(&cli.StringSliceFlag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: []interface{}{"hello", "world"}, - EnvVarName: "TEST", - EnvVarValue: "oh,no", - } - c := runTest(t, tis) - expect(t, c.StringSlice("test"), []string{"oh", "no"}) - - c = runRacyTest(t, tis) - refute(t, c.StringSlice("test"), []string{"oh", "no"}) -} - -func TestIntSliceApplyInputSourceValue_Alias(t *testing.T) { - dest := cli.NewIntSlice() - tis := testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), - FlagName: "test_alias", - MapValue: []interface{}{1, 2}, - } - c := runTest(t, tis) - expect(t, c.IntSlice("test_alias"), []int{1, 2}) - expect(t, dest.Value(), []int{1, 2}) - - dest = cli.NewIntSlice() - tis = testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Aliases: []string{"test_alias"}, Destination: dest}), - FlagName: "test_alias", - MapValue: []interface{}{1, 2}, - } - c = runRacyTest(t, tis) - refute(t, c.IntSlice("test_alias"), []int{1, 2}) - refute(t, dest.Value(), []int{1, 2}) -} - -func TestIntSliceApplyInputSourceValue(t *testing.T) { - dest := cli.NewIntSlice() - tis := testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{1, 2}, - } - c := runTest(t, tis) - expect(t, c.IntSlice("test"), []int{1, 2}) - expect(t, dest.Value(), []int{1, 2}) - - // reset dest - dest = cli.NewIntSlice() - tis = testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{1, 2}, - } - c = runRacyTest(t, tis) - refute(t, c.IntSlice("test"), []int{1, 2}) - refute(t, dest.Value(), []int{1, 2}) -} - -func TestIntSliceApplyInputSourceMethodContextSet(t *testing.T) { - dest := cli.NewIntSlice() - tis := testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{1, 2}, - ContextValueString: "3", - } - c := runTest(t, tis) - expect(t, c.IntSlice("test"), []int{3}) - expect(t, dest.Value(), []int{3}) - - // reset dest - dest = cli.NewIntSlice() - tis = testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{1, 2}, - ContextValueString: "3", - } - c = runRacyTest(t, tis) - refute(t, c.IntSlice("test"), []int{3}) - refute(t, dest.Value(), []int{3}) -} - -func TestIntSliceApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewIntSliceFlag(&cli.IntSliceFlag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: []interface{}{1, 2}, - EnvVarName: "TEST", - EnvVarValue: "3,4", - } - c := runTest(t, tis) - expect(t, c.IntSlice("test"), []int{3, 4}) - - c = runRacyTest(t, tis) - refute(t, c.IntSlice("test"), []int{3, 4}) -} - -func TestInt64SliceFlagApplyInputSourceValue(t *testing.T) { - dest := cli.NewInt64Slice() - tis := testApplyInputSource{ - Flag: NewInt64SliceFlag(&cli.Int64SliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{int64(1), int64(2)}, - } - c := runTest(t, tis) - expect(t, c.Int64Slice("test"), []int64{1, 2}) - expect(t, dest.Value(), []int64{1, 2}) - - // reset dest - dest = cli.NewInt64Slice() - tis = testApplyInputSource{ - Flag: NewInt64SliceFlag(&cli.Int64SliceFlag{Name: "test", Destination: dest}), - FlagName: "test", - MapValue: []interface{}{int64(1), int64(2)}, - } - c = runRacyTest(t, tis) - refute(t, c.IntSlice("test"), []int64{1, 2}) - refute(t, dest.Value(), []int64{1, 2}) -} - -func TestBoolApplyInputSourceMethodSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewBoolFlag(&cli.BoolFlag{Name: "test"}), - FlagName: "test", - MapValue: true, - } - c := runTest(t, tis) - expect(t, true, c.Bool("test")) - - c = runRacyTest(t, tis) - refute(t, true, c.Bool("test")) -} - -func TestBoolApplyInputSourceMethodSet_Alias(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewBoolFlag(&cli.BoolFlag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test_alias", - MapValue: true, - } - c := runTest(t, tis) - expect(t, true, c.Bool("test_alias")) - - c = runRacyTest(t, tis) - refute(t, true, c.Bool("test_alias")) -} - -func TestBoolApplyInputSourceMethodContextSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewBoolFlag(&cli.BoolFlag{Name: "test"}), - FlagName: "test", - MapValue: false, - ContextValueString: "true", - } - c := runTest(t, tis) - expect(t, true, c.Bool("test")) - - c = runRacyTest(t, tis) - refute(t, true, c.Bool("test")) -} - -func TestBoolApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewBoolFlag(&cli.BoolFlag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: false, - EnvVarName: "TEST", - EnvVarValue: "true", - } - c := runTest(t, tis) - expect(t, true, c.Bool("test")) - - c = runRacyTest(t, tis) - refute(t, true, c.Bool("test")) -} - -func TestStringApplyInputSourceMethodSet_Alias(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewStringFlag(&cli.StringFlag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test_alias", - MapValue: "hello", - } - c := runTest(t, tis) - expect(t, "hello", c.String("test_alias")) - - c = runRacyTest(t, tis) - refute(t, "hello", c.String("test_alias")) -} - -func TestStringApplyInputSourceMethodSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewStringFlag(&cli.StringFlag{Name: "test"}), - FlagName: "test", - MapValue: "hello", - } - c := runTest(t, tis) - expect(t, "hello", c.String("test")) - - c = runRacyTest(t, tis) - refute(t, "hello", c.String("test")) -} - -func TestStringApplyInputSourceMethodContextSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewStringFlag(&cli.StringFlag{Name: "test"}), - FlagName: "test", - MapValue: "hello", - ContextValueString: "goodbye", - } - c := runTest(t, tis) - expect(t, "goodbye", c.String("test")) - - c = runRacyTest(t, tis) - refute(t, "goodbye", c.String("test")) -} - -func TestStringApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewStringFlag(&cli.StringFlag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: "hello", - EnvVarName: "TEST", - EnvVarValue: "goodbye", - } - c := runTest(t, tis) - expect(t, "goodbye", c.String("test")) - - c = runRacyTest(t, tis) - refute(t, "goodbye", c.String("test")) -} - -func TestPathApplyInputSourceMethodSet_Alias(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewPathFlag(&cli.PathFlag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test_alias", - MapValue: "hello", - SourcePath: "/path/to/source/file", - } - c := runTest(t, tis) - - expected := "/path/to/source/hello" - if runtime.GOOS == "windows" { - var err error - // Prepend the corresponding drive letter (or UNC path?), and change - // to windows-style path: - expected, err = filepath.Abs(expected) - if err != nil { - t.Fatal(err) - } - } - expect(t, expected, c.String("test_alias")) - - c = runRacyTest(t, tis) - refute(t, expected, c.String("test_alias")) -} - -func TestPathApplyInputSourceMethodSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewPathFlag(&cli.PathFlag{Name: "test"}), - FlagName: "test", - MapValue: "hello", - SourcePath: "/path/to/source/file", - } - c := runTest(t, tis) - - expected := "/path/to/source/hello" - if runtime.GOOS == "windows" { - var err error - // Prepend the corresponding drive letter (or UNC path?), and change - // to windows-style path: - expected, err = filepath.Abs(expected) - if err != nil { - t.Fatal(err) - } - } - expect(t, expected, c.String("test")) - - c = runRacyTest(t, tis) - refute(t, expected, c.String("test")) -} - -func TestPathApplyInputSourceMethodContextSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewPathFlag(&cli.PathFlag{Name: "test"}), - FlagName: "test", - MapValue: "hello", - ContextValueString: "goodbye", - SourcePath: "/path/to/source/file", - } - c := runTest(t, tis) - expect(t, "goodbye", c.String("test")) - - c = runRacyTest(t, tis) - refute(t, "goodbye", c.String("test")) -} - -func TestPathApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewPathFlag(&cli.PathFlag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: "hello", - EnvVarName: "TEST", - EnvVarValue: "goodbye", - SourcePath: "/path/to/source/file", - } - c := runTest(t, tis) - expect(t, "goodbye", c.String("test")) - - c = runRacyTest(t, tis) - refute(t, "goodbye", c.String("test")) -} - -func TestIntApplyInputSourceMethodSet_Alias(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewIntFlag(&cli.IntFlag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test_alias", - MapValue: 15, - } - c := runTest(t, tis) - expect(t, 15, c.Int("test_alias")) - - c = runRacyTest(t, tis) - refute(t, 15, c.Int("test_alias")) -} - -func TestIntApplyInputSourceMethodSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewIntFlag(&cli.IntFlag{Name: "test"}), - FlagName: "test", - MapValue: 15, - } - c := runTest(t, tis) - expect(t, 15, c.Int("test")) - - c = runRacyTest(t, tis) - refute(t, 15, c.Int("test")) -} - -func TestIntApplyInputSourceMethodSetNegativeValue(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewIntFlag(&cli.IntFlag{Name: "test"}), - FlagName: "test", - MapValue: -1, - } - c := runTest(t, tis) - expect(t, -1, c.Int("test")) - - c = runRacyTest(t, tis) - refute(t, -1, c.Int("test")) -} - -func TestIntApplyInputSourceMethodContextSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewIntFlag(&cli.IntFlag{Name: "test"}), - FlagName: "test", - MapValue: 15, - ContextValueString: "7", - } - c := runTest(t, tis) - expect(t, 7, c.Int("test")) - - c = runRacyTest(t, tis) - refute(t, 7, c.Int("test")) -} - -func TestIntApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewIntFlag(&cli.IntFlag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: 15, - EnvVarName: "TEST", - EnvVarValue: "12", - } - c := runTest(t, tis) - expect(t, 12, c.Int("test")) - - c = runRacyTest(t, tis) - refute(t, 12, c.Int("test")) -} - -func TestDurationApplyInputSourceMethodSet_Alias(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewDurationFlag(&cli.DurationFlag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test_alias", - MapValue: 30 * time.Second, - } - c := runTest(t, tis) - expect(t, 30*time.Second, c.Duration("test_alias")) - - c = runRacyTest(t, tis) - refute(t, 30*time.Second, c.Duration("test_alias")) -} - -func TestDurationApplyInputSourceMethodSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewDurationFlag(&cli.DurationFlag{Name: "test"}), - FlagName: "test", - MapValue: 30 * time.Second, - } - c := runTest(t, tis) - expect(t, 30*time.Second, c.Duration("test")) - - c = runRacyTest(t, tis) - refute(t, 30*time.Second, c.Duration("test")) -} - -func TestDurationApplyInputSourceMethodSetNegativeValue(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewDurationFlag(&cli.DurationFlag{Name: "test"}), - FlagName: "test", - MapValue: -30 * time.Second, - } - c := runTest(t, tis) - expect(t, -30*time.Second, c.Duration("test")) - - c = runRacyTest(t, tis) - refute(t, -30*time.Second, c.Duration("test")) -} - -func TestDurationApplyInputSourceMethodContextSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewDurationFlag(&cli.DurationFlag{Name: "test"}), - FlagName: "test", - MapValue: 30 * time.Second, - ContextValueString: (15 * time.Second).String(), - } - c := runTest(t, tis) - expect(t, 15*time.Second, c.Duration("test")) - - c = runRacyTest(t, tis) - refute(t, 15*time.Second, c.Duration("test")) -} - -func TestDurationApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewDurationFlag(&cli.DurationFlag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: 30 * time.Second, - EnvVarName: "TEST", - EnvVarValue: (15 * time.Second).String(), - } - c := runTest(t, tis) - expect(t, 15*time.Second, c.Duration("test")) - - c = runRacyTest(t, tis) - refute(t, 15*time.Second, c.Duration("test")) -} - -func TestFloat64ApplyInputSourceMethodSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test"}), - FlagName: "test", - MapValue: 1.3, - } - c := runTest(t, tis) - expect(t, 1.3, c.Float64("test")) - - c = runRacyTest(t, tis) - refute(t, 1.3, c.Float64("test")) -} - -func TestFloat64ApplyInputSourceMethodSetNegativeValue_Alias(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test", Aliases: []string{"test_alias"}}), - FlagName: "test_alias", - MapValue: -1.3, - } - c := runTest(t, tis) - expect(t, -1.3, c.Float64("test_alias")) - - c = runRacyTest(t, tis) - refute(t, -1.3, c.Float64("test_alias")) -} - -func TestFloat64ApplyInputSourceMethodSetNegativeValue(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test"}), - FlagName: "test", - MapValue: -1.3, - } - c := runTest(t, tis) - expect(t, -1.3, c.Float64("test")) - - c = runRacyTest(t, tis) - refute(t, -1.3, c.Float64("test")) -} - -func TestFloat64ApplyInputSourceMethodSetNegativeValueNotSet(t *testing.T) { - c := runTest(t, testApplyInputSource{ - Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test1"}), - FlagName: "test1", - // dont set map value - }) - expect(t, 0.0, c.Float64("test1")) -} - -func TestFloat64ApplyInputSourceMethodContextSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test"}), - FlagName: "test", - MapValue: 1.3, - ContextValueString: fmt.Sprintf("%v", 1.4), - } - c := runTest(t, tis) - expect(t, 1.4, c.Float64("test")) - - c = runRacyTest(t, tis) - refute(t, 1.4, c.Float64("test")) -} - -func TestFloat64ApplyInputSourceMethodEnvVarSet(t *testing.T) { - tis := testApplyInputSource{ - Flag: NewFloat64Flag(&cli.Float64Flag{Name: "test", EnvVars: []string{"TEST"}}), - FlagName: "test", - MapValue: 1.3, - EnvVarName: "TEST", - EnvVarValue: fmt.Sprintf("%v", 1.4), - } - c := runTest(t, tis) - expect(t, 1.4, c.Float64("test")) - - c = runRacyTest(t, tis) - refute(t, 1.4, c.Float64("test")) -} - -func runTest(t *testing.T, test testApplyInputSource) *cli.Context { - inputSource := &MapInputSource{ - file: test.SourcePath, - valueMap: map[interface{}]interface{}{test.FlagName: test.MapValue}, - } - set := flag.NewFlagSet(test.FlagSetName, flag.ContinueOnError) - c := cli.NewContext(nil, set, nil) - if test.EnvVarName != "" && test.EnvVarValue != "" { - _ = os.Setenv(test.EnvVarName, test.EnvVarValue) - defer os.Setenv(test.EnvVarName, "") - } - - _ = test.Flag.Apply(set) - if test.ContextValue != nil { - f := set.Lookup(test.FlagName) - f.Value = test.ContextValue - } - if test.ContextValueString != "" { - _ = set.Set(test.FlagName, test.ContextValueString) - } - _ = test.Flag.ApplyInputSourceValue(c, inputSource) - - return c -} - -func runRacyTest(t *testing.T, test testApplyInputSource) *cli.Context { - set := flag.NewFlagSet(test.FlagSetName, flag.ContinueOnError) - c := cli.NewContext(nil, set, nil) - _ = test.Flag.ApplyInputSourceValue(c, &racyInputSource{ - MapInputSource: &MapInputSource{ - file: test.SourcePath, - valueMap: map[interface{}]interface{}{test.FlagName: test.MapValue}, - }, - }) - - return c -} - -type Parser [2]string - -func (p *Parser) Set(value string) error { - parts := strings.Split(value, ",") - if len(parts) != 2 { - return fmt.Errorf("invalid format") - } - - (*p)[0] = parts[0] - (*p)[1] = parts[1] - - return nil -} - -func (p *Parser) String() string { - return fmt.Sprintf("%s,%s", p[0], p[1]) -} - -type bogus [1]uint diff --git a/altsrc/helpers_test.go b/altsrc/helpers_test.go deleted file mode 100644 index 1f8d5c2..0000000 --- a/altsrc/helpers_test.go +++ /dev/null @@ -1,31 +0,0 @@ -package altsrc - -import ( - "os" - "reflect" - "runtime" - "strings" - "testing" -) - -var ( - wd, _ = os.Getwd() -) - -func expect(t *testing.T, a interface{}, b interface{}) { - _, fn, line, _ := runtime.Caller(1) - fn = strings.Replace(fn, wd+"/", "", -1) - - if !reflect.DeepEqual(a, b) { - t.Errorf("(%s:%d) Expected %v (type %v) - Got %v (type %v)", fn, line, b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} - -func refute(t *testing.T, a interface{}, b interface{}) { - _, fn, line, _ := runtime.Caller(1) - fn = strings.Replace(fn, wd+"/", "", -1) - - if reflect.DeepEqual(a, b) { - t.Errorf("(%s:%d) Did not expect %v (type %v) - Got %v (type %v)", fn, line, b, reflect.TypeOf(b), a, reflect.TypeOf(a)) - } -} diff --git a/altsrc/input_source_context.go b/altsrc/input_source_context.go deleted file mode 100644 index 4cd8392..0000000 --- a/altsrc/input_source_context.go +++ /dev/null @@ -1,28 +0,0 @@ -package altsrc - -import ( - "time" - - "github.com/urfave/cli/v3" -) - -// InputSourceContext is an interface used to allow -// other input sources to be implemented as needed. -// -// Source returns an identifier for the input source. In case of file source -// it should return path to the file. -type InputSourceContext interface { - Source() string - - Int(name string) (int, error) - Duration(name string) (time.Duration, error) - Float64(name string) (float64, error) - String(name string) (string, error) - StringSlice(name string) ([]string, error) - IntSlice(name string) ([]int, error) - Int64Slice(name string) ([]int64, error) - Generic(name string) (cli.Generic, error) - Bool(name string) (bool, error) - - isSet(name string) bool -} diff --git a/altsrc/json_command_test.go b/altsrc/json_command_test.go deleted file mode 100644 index e39dabc..0000000 --- a/altsrc/json_command_test.go +++ /dev/null @@ -1,329 +0,0 @@ -package altsrc - -import ( - "flag" - "io/ioutil" - "os" - "testing" - - "github.com/urfave/cli/v3" -) - -const ( - fileName = "current.json" - simpleJSON = `{"test": 15, "testb": false}` - nestedJSON = `{"top": {"test": 15}}` -) - -func TestCommandJSONFileTest(t *testing.T) { - cleanup := writeTempFile(t, fileName, simpleJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - test := []string{"test-cmd", "--load", fileName} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 15) - - valb := c.Bool("testb") - expect(t, valb, false) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test"}), - &cli.StringFlag{Name: "load"}, - NewBoolFlag(&cli.BoolFlag{Name: "testb", Value: true}), - }, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileTestGlobalEnvVarWins(t *testing.T) { - cleanup := writeTempFile(t, fileName, simpleJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = os.Setenv("THE_TEST", "10") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", fileName} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 10) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileTestGlobalEnvVarWinsNested(t *testing.T) { - cleanup := writeTempFile(t, fileName, nestedJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = os.Setenv("THE_TEST", "10") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", fileName} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 10) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileTestSpecifiedFlagWins(t *testing.T) { - cleanup := writeTempFile(t, fileName, simpleJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - test := []string{"test-cmd", "--load", fileName, "--test", "7"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 7) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileTestSpecifiedFlagWinsNested(t *testing.T) { - cleanup := writeTempFile(t, fileName, nestedJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - test := []string{"test-cmd", "--load", fileName, "--top.test", "7"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 7) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileTestDefaultValueFileWins(t *testing.T) { - cleanup := writeTempFile(t, fileName, simpleJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - test := []string{"test-cmd", "--load", fileName} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", Value: 7}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileTestDefaultValueFileWinsNested(t *testing.T) { - cleanup := writeTempFile(t, fileName, nestedJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - test := []string{"test-cmd", "--load", fileName} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", Value: 7}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileFlagHasDefaultGlobalEnvJSONSetGlobalEnvWins(t *testing.T) { - cleanup := writeTempFile(t, fileName, simpleJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = os.Setenv("THE_TEST", "11") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", fileName} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 11) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", Value: 7, EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandJSONFileFlagHasDefaultGlobalEnvJSONSetGlobalEnvWinsNested(t *testing.T) { - cleanup := writeTempFile(t, fileName, nestedJSON) - defer cleanup() - - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = os.Setenv("THE_TEST", "11") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", fileName} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 11) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", Value: 7, EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewJSONSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func writeTempFile(t *testing.T, name string, content string) func() { - if err := ioutil.WriteFile(name, []byte(content), 0666); err != nil { - t.Fatalf("cannot write %q: %v", name, err) - } - return func() { - if err := os.Remove(name); err != nil { - t.Errorf("cannot remove %q: %v", name, err) - } - } -} diff --git a/altsrc/json_source_context.go b/altsrc/json_source_context.go deleted file mode 100644 index 5589d59..0000000 --- a/altsrc/json_source_context.go +++ /dev/null @@ -1,240 +0,0 @@ -package altsrc - -import ( - "encoding/json" - "fmt" - "io" - "io/ioutil" - "strings" - "time" - - "github.com/urfave/cli/v3" -) - -// NewJSONSourceFromFlagFunc returns a func that takes a cli.Context -// and returns an InputSourceContext suitable for retrieving config -// variables from a file containing JSON data with the file name defined -// by the given flag. -func NewJSONSourceFromFlagFunc(flag string) func(c *cli.Context) (InputSourceContext, error) { - return func(cCtx *cli.Context) (InputSourceContext, error) { - if cCtx.IsSet(flag) { - return NewJSONSourceFromFile(cCtx.String(flag)) - } - - return defaultInputSource() - } -} - -// NewJSONSourceFromFile returns an InputSourceContext suitable for -// retrieving config variables from a file (or url) containing JSON -// data. -func NewJSONSourceFromFile(f string) (InputSourceContext, error) { - data, err := loadDataFrom(f) - if err != nil { - return nil, err - } - - return NewJSONSource(data) -} - -// NewJSONSourceFromReader returns an InputSourceContext suitable for -// retrieving config variables from an io.Reader that returns JSON data. -func NewJSONSourceFromReader(r io.Reader) (InputSourceContext, error) { - data, err := ioutil.ReadAll(r) - if err != nil { - return nil, err - } - return NewJSONSource(data) -} - -// NewJSONSource returns an InputSourceContext suitable for retrieving -// config variables from raw JSON data. -func NewJSONSource(data []byte) (InputSourceContext, error) { - var deserialized map[string]interface{} - if err := json.Unmarshal(data, &deserialized); err != nil { - return nil, err - } - return &jsonSource{deserialized: deserialized}, nil -} - -func (x *jsonSource) Source() string { - return x.file -} - -func (x *jsonSource) Int(name string) (int, error) { - i, err := x.getValue(name) - if err != nil { - return 0, err - } - switch v := i.(type) { - default: - return 0, fmt.Errorf("unexpected type %T for %q", i, name) - case int: - return v, nil - case float32: - return int(v), nil - case float64: - return int(v), nil - } -} - -func (x *jsonSource) Duration(name string) (time.Duration, error) { - i, err := x.getValue(name) - if err != nil { - return 0, err - } - v, ok := i.(time.Duration) - if !ok { - return 0, fmt.Errorf("unexpected type %T for %q", i, name) - } - return v, nil -} - -func (x *jsonSource) Float64(name string) (float64, error) { - i, err := x.getValue(name) - if err != nil { - return 0, err - } - v, ok := i.(float64) - if !ok { - return 0, fmt.Errorf("unexpected type %T for %q", i, name) - } - return v, nil -} - -func (x *jsonSource) String(name string) (string, error) { - i, err := x.getValue(name) - if err != nil { - return "", err - } - v, ok := i.(string) - if !ok { - return "", fmt.Errorf("unexpected type %T for %q", i, name) - } - return v, nil -} - -func (x *jsonSource) StringSlice(name string) ([]string, error) { - i, err := x.getValue(name) - if err != nil { - return nil, err - } - switch v := i.(type) { - default: - return nil, fmt.Errorf("unexpected type %T for %q", i, name) - case []string: - return v, nil - case []interface{}: - c := []string{} - for _, s := range v { - if str, ok := s.(string); ok { - c = append(c, str) - } else { - return c, fmt.Errorf("unexpected item type %T in %T for %q", s, c, name) - } - } - return c, nil - } -} - -func (x *jsonSource) IntSlice(name string) ([]int, error) { - i, err := x.getValue(name) - if err != nil { - return nil, err - } - switch v := i.(type) { - default: - return nil, fmt.Errorf("unexpected type %T for %q", i, name) - case []int: - return v, nil - case []interface{}: - c := []int{} - for _, s := range v { - if i2, ok := s.(int); ok { - c = append(c, i2) - } else { - return c, fmt.Errorf("unexpected item type %T in %T for %q", s, c, name) - } - } - return c, nil - } -} - -func (x *jsonSource) Int64Slice(name string) ([]int64, error) { - i, err := x.getValue(name) - if err != nil { - return nil, err - } - switch v := i.(type) { - default: - return nil, fmt.Errorf("unexpected type %T for %q", i, name) - case []int64: - return v, nil - case []interface{}: - c := []int64{} - for _, s := range v { - if i2, ok := s.(int64); ok { - c = append(c, i2) - } else { - return c, fmt.Errorf("unexpected item type %T in %T for %q", s, c, name) - } - } - return c, nil - } -} - -func (x *jsonSource) Generic(name string) (cli.Generic, error) { - i, err := x.getValue(name) - if err != nil { - return nil, err - } - v, ok := i.(cli.Generic) - if !ok { - return nil, fmt.Errorf("unexpected type %T for %q", i, name) - } - return v, nil -} - -func (x *jsonSource) Bool(name string) (bool, error) { - i, err := x.getValue(name) - if err != nil { - return false, err - } - v, ok := i.(bool) - if !ok { - return false, fmt.Errorf("unexpected type %T for %q", i, name) - } - return v, nil -} - -func (x *jsonSource) isSet(name string) bool { - _, err := x.getValue(name) - return err == nil -} - -func (x *jsonSource) getValue(key string) (interface{}, error) { - return jsonGetValue(key, x.deserialized) -} - -func jsonGetValue(key string, m map[string]interface{}) (interface{}, error) { - var ret interface{} - var ok bool - working := m - keys := strings.Split(key, ".") - for ix, k := range keys { - if ret, ok = working[k]; !ok { - return ret, fmt.Errorf("missing key %q", key) - } - if working, ok = ret.(map[string]interface{}); !ok { - if ix < len(keys)-1 { - return ret, fmt.Errorf("unexpected intermediate value at %q segment of %q: %T", k, key, ret) - } - } - } - return ret, nil -} - -type jsonSource struct { - file string - deserialized map[string]interface{} -} diff --git a/altsrc/map_input_source.go b/altsrc/map_input_source.go deleted file mode 100644 index 4bac92c..0000000 --- a/altsrc/map_input_source.go +++ /dev/null @@ -1,300 +0,0 @@ -package altsrc - -import ( - "fmt" - "reflect" - "strings" - "time" - - "github.com/urfave/cli/v3" -) - -// MapInputSource implements InputSourceContext to return -// data from the map that is loaded. -type MapInputSource struct { - file string - valueMap map[interface{}]interface{} -} - -// NewMapInputSource creates a new MapInputSource for implementing custom input sources. -func NewMapInputSource(file string, valueMap map[interface{}]interface{}) *MapInputSource { - return &MapInputSource{file: file, valueMap: valueMap} -} - -// nestedVal checks if the name has '.' delimiters. -// If so, it tries to traverse the tree by the '.' delimited sections to find -// a nested value for the key. -func nestedVal(name string, tree map[interface{}]interface{}) (interface{}, bool) { - if sections := strings.Split(name, "."); len(sections) > 1 { - node := tree - for _, section := range sections[:len(sections)-1] { - child, ok := node[section] - if !ok { - return nil, false - } - - switch child := child.(type) { - case map[string]interface{}: - node = make(map[interface{}]interface{}, len(child)) - for k, v := range child { - node[k] = v - } - case map[interface{}]interface{}: - node = child - default: - return nil, false - } - } - if val, ok := node[sections[len(sections)-1]]; ok { - return val, true - } - } - return nil, false -} - -// Source returns the path of the source file -func (fsm *MapInputSource) Source() string { - return fsm.file -} - -// Int returns an int from the map if it exists otherwise returns 0 -func (fsm *MapInputSource) Int(name string) (int, error) { - otherGenericValue, exists := fsm.valueMap[name] - if exists { - otherValue, isType := otherGenericValue.(int) - if !isType { - return 0, incorrectTypeForFlagError(name, "int", otherGenericValue) - } - return otherValue, nil - } - nestedGenericValue, exists := nestedVal(name, fsm.valueMap) - if exists { - otherValue, isType := nestedGenericValue.(int) - if !isType { - return 0, incorrectTypeForFlagError(name, "int", nestedGenericValue) - } - return otherValue, nil - } - - return 0, nil -} - -// Duration returns a duration from the map if it exists otherwise returns 0 -func (fsm *MapInputSource) Duration(name string) (time.Duration, error) { - otherGenericValue, exists := fsm.valueMap[name] - if exists { - return castDuration(name, otherGenericValue) - } - nestedGenericValue, exists := nestedVal(name, fsm.valueMap) - if exists { - return castDuration(name, nestedGenericValue) - } - - return 0, nil -} - -func castDuration(name string, value interface{}) (time.Duration, error) { - if otherValue, isType := value.(time.Duration); isType { - return otherValue, nil - } - otherStringValue, isType := value.(string) - parsedValue, err := time.ParseDuration(otherStringValue) - if !isType || err != nil { - return 0, incorrectTypeForFlagError(name, "duration", value) - } - return parsedValue, nil -} - -// Float64 returns an float64 from the map if it exists otherwise returns 0 -func (fsm *MapInputSource) Float64(name string) (float64, error) { - otherGenericValue, exists := fsm.valueMap[name] - if exists { - otherValue, isType := otherGenericValue.(float64) - if !isType { - return 0, incorrectTypeForFlagError(name, "float64", otherGenericValue) - } - return otherValue, nil - } - nestedGenericValue, exists := nestedVal(name, fsm.valueMap) - if exists { - otherValue, isType := nestedGenericValue.(float64) - if !isType { - return 0, incorrectTypeForFlagError(name, "float64", nestedGenericValue) - } - return otherValue, nil - } - - return 0, nil -} - -// String returns a string from the map if it exists otherwise returns an empty string -func (fsm *MapInputSource) String(name string) (string, error) { - otherGenericValue, exists := fsm.valueMap[name] - if exists { - otherValue, isType := otherGenericValue.(string) - if !isType { - return "", incorrectTypeForFlagError(name, "string", otherGenericValue) - } - return otherValue, nil - } - nestedGenericValue, exists := nestedVal(name, fsm.valueMap) - if exists { - otherValue, isType := nestedGenericValue.(string) - if !isType { - return "", incorrectTypeForFlagError(name, "string", nestedGenericValue) - } - return otherValue, nil - } - - return "", nil -} - -// StringSlice returns an []string from the map if it exists otherwise returns nil -func (fsm *MapInputSource) StringSlice(name string) ([]string, error) { - otherGenericValue, exists := fsm.valueMap[name] - if !exists { - otherGenericValue, exists = nestedVal(name, fsm.valueMap) - if !exists { - return nil, nil - } - } - - otherValue, isType := otherGenericValue.([]interface{}) - if !isType { - return nil, incorrectTypeForFlagError(name, "[]interface{}", otherGenericValue) - } - - var stringSlice = make([]string, 0, len(otherValue)) - for i, v := range otherValue { - stringValue, isType := v.(string) - - if !isType { - return nil, incorrectTypeForFlagError(fmt.Sprintf("%s[%d]", name, i), "string", v) - } - - stringSlice = append(stringSlice, stringValue) - } - - return stringSlice, nil -} - -// IntSlice returns an []int from the map if it exists otherwise returns nil -func (fsm *MapInputSource) IntSlice(name string) ([]int, error) { - otherGenericValue, exists := fsm.valueMap[name] - if !exists { - otherGenericValue, exists = nestedVal(name, fsm.valueMap) - if !exists { - return nil, nil - } - } - - otherValue, isType := otherGenericValue.([]interface{}) - if !isType { - return nil, incorrectTypeForFlagError(name, "[]interface{}", otherGenericValue) - } - - var intSlice = make([]int, 0, len(otherValue)) - for i, v := range otherValue { - intValue, isType := v.(int) - - if !isType { - return nil, incorrectTypeForFlagError(fmt.Sprintf("%s[%d]", name, i), "int", v) - } - - intSlice = append(intSlice, intValue) - } - - return intSlice, nil -} - -// Int64Slice returns an []int64 from the map if it exists otherwise returns nil -func (fsm *MapInputSource) Int64Slice(name string) ([]int64, error) { - otherGenericValue, exists := fsm.valueMap[name] - if !exists { - otherGenericValue, exists = nestedVal(name, fsm.valueMap) - if !exists { - return nil, nil - } - } - - otherValue, isType := otherGenericValue.([]interface{}) - if !isType { - return nil, incorrectTypeForFlagError(name, "[]interface{}", otherGenericValue) - } - - var int64Slice = make([]int64, 0, len(otherValue)) - for i, v := range otherValue { - int64Value, isType := v.(int64) - - if !isType { - return nil, incorrectTypeForFlagError(fmt.Sprintf("%s[%d]", name, i), "int", v) - } - - int64Slice = append(int64Slice, int64Value) - } - - return int64Slice, nil -} - -// Generic returns an cli.Generic from the map if it exists otherwise returns nil -func (fsm *MapInputSource) Generic(name string) (cli.Generic, error) { - otherGenericValue, exists := fsm.valueMap[name] - if exists { - otherValue, isType := otherGenericValue.(cli.Generic) - if !isType { - return nil, incorrectTypeForFlagError(name, "cli.Generic", otherGenericValue) - } - return otherValue, nil - } - nestedGenericValue, exists := nestedVal(name, fsm.valueMap) - if exists { - otherValue, isType := nestedGenericValue.(cli.Generic) - if !isType { - return nil, incorrectTypeForFlagError(name, "cli.Generic", nestedGenericValue) - } - return otherValue, nil - } - - return nil, nil -} - -// Bool returns an bool from the map otherwise returns false -func (fsm *MapInputSource) Bool(name string) (bool, error) { - otherGenericValue, exists := fsm.valueMap[name] - if exists { - otherValue, isType := otherGenericValue.(bool) - if !isType { - return false, incorrectTypeForFlagError(name, "bool", otherGenericValue) - } - return otherValue, nil - } - nestedGenericValue, exists := nestedVal(name, fsm.valueMap) - if exists { - otherValue, isType := nestedGenericValue.(bool) - if !isType { - return false, incorrectTypeForFlagError(name, "bool", nestedGenericValue) - } - return otherValue, nil - } - - return false, nil -} - -func (fsm *MapInputSource) isSet(name string) bool { - if _, exists := fsm.valueMap[name]; exists { - return exists - } - - _, exists := nestedVal(name, fsm.valueMap) - return exists -} - -func incorrectTypeForFlagError(name, expectedTypeName string, value interface{}) error { - valueType := reflect.TypeOf(value) - valueTypeName := "" - if valueType != nil { - valueTypeName = valueType.Name() - } - - return fmt.Errorf("Mismatched type for flag '%s'. Expected '%s' but actual is '%s'", name, expectedTypeName, valueTypeName) -} diff --git a/altsrc/map_input_source_test.go b/altsrc/map_input_source_test.go deleted file mode 100644 index cf399b5..0000000 --- a/altsrc/map_input_source_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package altsrc - -import ( - "testing" - "time" -) - -func TestMapDuration(t *testing.T) { - inputSource := NewMapInputSource( - "test", - map[interface{}]interface{}{ - "duration_of_duration_type": time.Minute, - "duration_of_string_type": "1m", - "duration_of_int_type": 1000, - }) - d, err := inputSource.Duration("duration_of_duration_type") - expect(t, time.Minute, d) - expect(t, nil, err) - d, err = inputSource.Duration("duration_of_string_type") - expect(t, time.Minute, d) - expect(t, nil, err) - _, err = inputSource.Duration("duration_of_int_type") - refute(t, nil, err) -} - -func TestMapInputSource_Int64Slice(t *testing.T) { - inputSource := NewMapInputSource( - "test", - map[interface{}]interface{}{ - "test_num": []interface{}{int64(1), int64(2), int64(3)}, - }) - d, err := inputSource.Int64Slice("test_num") - expect(t, []int64{1, 2, 3}, d) - expect(t, nil, err) -} diff --git a/altsrc/toml_command_test.go b/altsrc/toml_command_test.go deleted file mode 100644 index 9e52435..0000000 --- a/altsrc/toml_command_test.go +++ /dev/null @@ -1,305 +0,0 @@ -package altsrc - -import ( - "flag" - "io/ioutil" - "os" - "testing" - - "github.com/urfave/cli/v3" -) - -func TestCommandTomFileTest(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("test = 15"), 0666) - defer os.Remove("current.toml") - test := []string{"test-cmd", "--load", "current.toml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileTestGlobalEnvVarWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("test = 15"), 0666) - defer os.Remove("current.toml") - - _ = os.Setenv("THE_TEST", "10") - defer os.Setenv("THE_TEST", "") - test := []string{"test-cmd", "--load", "current.toml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 10) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileTestGlobalEnvVarWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("[top]\ntest = 15"), 0666) - defer os.Remove("current.toml") - - _ = os.Setenv("THE_TEST", "10") - defer os.Setenv("THE_TEST", "") - test := []string{"test-cmd", "--load", "current.toml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 10) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileTestSpecifiedFlagWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("test = 15"), 0666) - defer os.Remove("current.toml") - - test := []string{"test-cmd", "--load", "current.toml", "--test", "7"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 7) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileTestSpecifiedFlagWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte(`[top] - test = 15`), 0666) - defer os.Remove("current.toml") - - test := []string{"test-cmd", "--load", "current.toml", "--top.test", "7"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 7) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileTestDefaultValueFileWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("test = 15"), 0666) - defer os.Remove("current.toml") - - test := []string{"test-cmd", "--load", "current.toml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", Value: 7}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileTestDefaultValueFileWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("[top]\ntest = 15"), 0666) - defer os.Remove("current.toml") - - test := []string{"test-cmd", "--load", "current.toml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", Value: 7}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileFlagHasDefaultGlobalEnvTomlSetGlobalEnvWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("test = 15"), 0666) - defer os.Remove("current.toml") - - _ = os.Setenv("THE_TEST", "11") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", "current.toml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 11) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", Value: 7, EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandTomlFileFlagHasDefaultGlobalEnvTomlSetGlobalEnvWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.toml", []byte("[top]\ntest = 15"), 0666) - defer os.Remove("current.toml") - - _ = os.Setenv("THE_TEST", "11") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", "current.toml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 11) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", Value: 7, EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewTomlSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} diff --git a/altsrc/toml_file_loader.go b/altsrc/toml_file_loader.go deleted file mode 100644 index 0e614e3..0000000 --- a/altsrc/toml_file_loader.go +++ /dev/null @@ -1,112 +0,0 @@ -package altsrc - -import ( - "fmt" - "reflect" - - "github.com/BurntSushi/toml" - "github.com/urfave/cli/v3" -) - -type tomlMap struct { - Map map[interface{}]interface{} -} - -func unmarshalMap(i interface{}) (ret map[interface{}]interface{}, err error) { - ret = make(map[interface{}]interface{}) - m := i.(map[string]interface{}) - for key, val := range m { - v := reflect.ValueOf(val) - switch v.Kind() { - case reflect.Bool: - ret[key] = val.(bool) - case reflect.String: - ret[key] = val.(string) - case reflect.Int: - ret[key] = val.(int) - case reflect.Int8: - ret[key] = int(val.(int8)) - case reflect.Int16: - ret[key] = int(val.(int16)) - case reflect.Int32: - ret[key] = int(val.(int32)) - case reflect.Int64: - ret[key] = int(val.(int64)) - case reflect.Uint: - ret[key] = int(val.(uint)) - case reflect.Uint8: - ret[key] = int(val.(uint8)) - case reflect.Uint16: - ret[key] = int(val.(uint16)) - case reflect.Uint32: - ret[key] = int(val.(uint32)) - case reflect.Uint64: - ret[key] = int(val.(uint64)) - case reflect.Float32: - ret[key] = float64(val.(float32)) - case reflect.Float64: - ret[key] = val.(float64) - case reflect.Map: - if tmp, err := unmarshalMap(val); err == nil { - ret[key] = tmp - } else { - return nil, err - } - case reflect.Array, reflect.Slice: - ret[key] = val.([]interface{}) - default: - return nil, fmt.Errorf("Unsupported: type = %#v", v.Kind()) - } - } - return ret, nil -} - -func (tm *tomlMap) UnmarshalTOML(i interface{}) error { - if tmp, err := unmarshalMap(i); err == nil { - tm.Map = tmp - } else { - return err - } - return nil -} - -type tomlSourceContext struct { - FilePath string -} - -// NewTomlSourceFromFile creates a new TOML InputSourceContext from a filepath. -func NewTomlSourceFromFile(file string) (InputSourceContext, error) { - tsc := &tomlSourceContext{FilePath: file} - var results tomlMap = tomlMap{} - if err := readCommandToml(tsc.FilePath, &results); err != nil { - return nil, fmt.Errorf("Unable to load TOML file '%s': inner error: \n'%v'", tsc.FilePath, err.Error()) - } - return &MapInputSource{file: file, valueMap: results.Map}, nil -} - -// NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a provided flag name and source context. -func NewTomlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) { - return func(cCtx *cli.Context) (InputSourceContext, error) { - if cCtx.IsSet(flagFileName) { - filePath := cCtx.String(flagFileName) - return NewTomlSourceFromFile(filePath) - } - - return defaultInputSource() - } -} - -func readCommandToml(filePath string, container interface{}) (err error) { - b, err := loadDataFrom(filePath) - if err != nil { - return err - } - - err = toml.Unmarshal(b, container) - if err != nil { - return err - } - - err = nil - return -} diff --git a/altsrc/yaml_command_test.go b/altsrc/yaml_command_test.go deleted file mode 100644 index ed67d80..0000000 --- a/altsrc/yaml_command_test.go +++ /dev/null @@ -1,308 +0,0 @@ -package altsrc - -import ( - "flag" - "io/ioutil" - "os" - "testing" - - "github.com/urfave/cli/v3" -) - -func TestCommandYamlFileTest(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666) - defer os.Remove("current.yaml") - test := []string{"test-cmd", "--load", "current.yaml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileTestGlobalEnvVarWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666) - defer os.Remove("current.yaml") - - _ = os.Setenv("THE_TEST", "10") - defer os.Setenv("THE_TEST", "") - test := []string{"test-cmd", "--load", "current.yaml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 10) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileTestGlobalEnvVarWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte(`top: - test: 15`), 0666) - defer os.Remove("current.yaml") - - _ = os.Setenv("THE_TEST", "10") - defer os.Setenv("THE_TEST", "") - test := []string{"test-cmd", "--load", "current.yaml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 10) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileTestSpecifiedFlagWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666) - defer os.Remove("current.yaml") - - test := []string{"test-cmd", "--load", "current.yaml", "--test", "7"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 7) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileTestSpecifiedFlagWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte(`top: - test: 15`), 0666) - defer os.Remove("current.yaml") - - test := []string{"test-cmd", "--load", "current.yaml", "--top.test", "7"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 7) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test"}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileTestDefaultValueFileWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666) - defer os.Remove("current.yaml") - - test := []string{"test-cmd", "--load", "current.yaml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", Value: 7}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileTestDefaultValueFileWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte(`top: - test: 15`), 0666) - defer os.Remove("current.yaml") - - test := []string{"test-cmd", "--load", "current.yaml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 15) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", Value: 7}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWins(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte("test: 15"), 0666) - defer os.Remove("current.yaml") - - _ = os.Setenv("THE_TEST", "11") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", "current.yaml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("test") - expect(t, val, 11) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "test", Value: 7, EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} - -func TestCommandYamlFileFlagHasDefaultGlobalEnvYamlSetGlobalEnvWinsNested(t *testing.T) { - app := &cli.App{} - set := flag.NewFlagSet("test", 0) - _ = ioutil.WriteFile("current.yaml", []byte(`top: - test: 15`), 0666) - defer os.Remove("current.yaml") - - _ = os.Setenv("THE_TEST", "11") - defer os.Setenv("THE_TEST", "") - - test := []string{"test-cmd", "--load", "current.yaml"} - _ = set.Parse(test) - - c := cli.NewContext(app, set, nil) - - command := &cli.Command{ - Name: "test-cmd", - Aliases: []string{"tc"}, - Usage: "this is for testing", - Description: "testing", - Action: func(c *cli.Context) error { - val := c.Int("top.test") - expect(t, val, 11) - return nil - }, - Flags: []cli.Flag{ - NewIntFlag(&cli.IntFlag{Name: "top.test", Value: 7, EnvVars: []string{"THE_TEST"}}), - &cli.StringFlag{Name: "load"}}, - } - command.Before = InitInputSourceWithContext(command.Flags, NewYamlSourceFromFlagFunc("load")) - err := command.Run(c, test...) - - expect(t, err, nil) -} diff --git a/altsrc/yaml_file_loader.go b/altsrc/yaml_file_loader.go deleted file mode 100644 index b1f6c84..0000000 --- a/altsrc/yaml_file_loader.go +++ /dev/null @@ -1,89 +0,0 @@ -package altsrc - -import ( - "fmt" - "io/ioutil" - "net/http" - "net/url" - "os" - "runtime" - "strings" - - "github.com/urfave/cli/v3" - - "gopkg.in/yaml.v3" -) - -type yamlSourceContext struct { - FilePath string -} - -// NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath. -func NewYamlSourceFromFile(file string) (InputSourceContext, error) { - ysc := &yamlSourceContext{FilePath: file} - var results map[interface{}]interface{} - err := readCommandYaml(ysc.FilePath, &results) - if err != nil { - return nil, fmt.Errorf("Unable to load Yaml file '%s': inner error: \n'%v'", ysc.FilePath, err.Error()) - } - - return &MapInputSource{file: file, valueMap: results}, nil -} - -// NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a provided flag name and source context. -func NewYamlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) { - return func(cCtx *cli.Context) (InputSourceContext, error) { - if filePath := cCtx.String(flagFileName); filePath != "" { - return NewYamlSourceFromFile(filePath) - } - return defaultInputSource() - } -} - -func readCommandYaml(filePath string, container interface{}) (err error) { - b, err := loadDataFrom(filePath) - if err != nil { - return err - } - - err = yaml.Unmarshal(b, container) - if err != nil { - return err - } - - err = nil - return -} - -func loadDataFrom(filePath string) ([]byte, error) { - u, err := url.Parse(filePath) - if err != nil { - return nil, err - } - - if u.Host != "" { // i have a host, now do i support the scheme? - switch u.Scheme { - case "http", "https": - res, err := http.Get(filePath) - if err != nil { - return nil, err - } - return ioutil.ReadAll(res.Body) - default: - return nil, fmt.Errorf("scheme of %s is unsupported", filePath) - } - } else if u.Path != "" { // i dont have a host, but I have a path. I am a local file. - if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil { - return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath) - } - return ioutil.ReadFile(filePath) - } else if runtime.GOOS == "windows" && strings.Contains(u.String(), "\\") { - // on Windows systems u.Path is always empty, so we need to check the string directly. - if _, notFoundFileErr := os.Stat(filePath); notFoundFileErr != nil { - return nil, fmt.Errorf("Cannot read from file: '%s' because it does not exist.", filePath) - } - return ioutil.ReadFile(filePath) - } - - return nil, fmt.Errorf("unable to determine how to load from path %s", filePath) -} diff --git a/altsrc/yaml_file_loader_test.go b/altsrc/yaml_file_loader_test.go deleted file mode 100644 index 37455c6..0000000 --- a/altsrc/yaml_file_loader_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package altsrc_test - -import ( - "fmt" - "log" - "os" - "time" - - "github.com/urfave/cli/v3" - "github.com/urfave/cli/v3/altsrc" -) - -func ExampleApp_Run_yamlFileLoaderDuration() { - execServe := func(c *cli.Context) error { - keepaliveInterval := c.Duration("keepalive-interval") - fmt.Printf("keepalive %s\n", keepaliveInterval) - return nil - } - - fileExists := func(filename string) bool { - stat, _ := os.Stat(filename) - return stat != nil - } - - // initConfigFileInputSource is like altsrc.InitInputSourceWithContext and altsrc.NewYamlSourceFromFlagFunc, but checks - // if the config flag is exists and only loads it if it does. If the flag is set and the file exists, it fails. - initConfigFileInputSource := func(configFlag string, flags []cli.Flag) cli.BeforeFunc { - return func(context *cli.Context) error { - configFile := context.String(configFlag) - if context.IsSet(configFlag) && !fileExists(configFile) { - return fmt.Errorf("config file %s does not exist", configFile) - } else if !context.IsSet(configFlag) && !fileExists(configFile) { - return nil - } - inputSource, err := altsrc.NewYamlSourceFromFile(configFile) - if err != nil { - return err - } - return altsrc.ApplyInputSourceValues(context, inputSource, flags) - } - } - - flagsServe := []cli.Flag{ - &cli.StringFlag{ - Name: "config", - Aliases: []string{"c"}, - EnvVars: []string{"CONFIG_FILE"}, - Value: "../testdata/empty.yml", - DefaultText: "../testdata/empty.yml", - Usage: "config file", - }, - altsrc.NewDurationFlag( - &cli.DurationFlag{ - Name: "keepalive-interval", - Aliases: []string{"k"}, - EnvVars: []string{"KEEPALIVE_INTERVAL"}, - Value: 45 * time.Second, - Usage: "interval of keepalive messages", - }, - ), - } - - cmdServe := &cli.Command{ - Name: "serve", - Usage: "Run the server", - UsageText: "serve [OPTIONS..]", - Action: execServe, - Flags: flagsServe, - Before: initConfigFileInputSource("config", flagsServe), - } - - c := &cli.App{ - Name: "cmd", - HideVersion: true, - UseShortOptionHandling: true, - Commands: []*cli.Command{ - cmdServe, - }, - } - - if err := c.Run([]string{"cmd", "serve", "--config", "../testdata/empty.yml"}); err != nil { - log.Fatal(err) - } - - // Output: - // keepalive 45s -} diff --git a/cmd/urfave-cli-genflags/Makefile b/cmd/urfave-cli-genflags/Makefile index 8f33ca2..434e588 100644 --- a/cmd/urfave-cli-genflags/Makefile +++ b/cmd/urfave-cli-genflags/Makefile @@ -26,4 +26,3 @@ show-cover: .PHONY: run run: build ./urfave-cli-genflags - ./urfave-cli-genflags -f altsrc/flag-spec.yaml -o altsrc/flag_generated.go -p altsrc -a diff --git a/godoc-current.txt b/godoc-current.txt index 9abda4b..fbcd2ec 100644 --- a/godoc-current.txt +++ b/godoc-current.txt @@ -2313,358 +2313,3 @@ type VisibleFlagCategory interface { } VisibleFlagCategory is a category containing flags. -package altsrc // import "github.com/urfave/cli/v3/altsrc" - - -FUNCTIONS - -func ApplyInputSourceValues(cCtx *cli.Context, inputSourceContext InputSourceContext, flags []cli.Flag) error - ApplyInputSourceValues iterates over all provided flags and executes - ApplyInputSourceValue on flags implementing the FlagInputSourceExtension - interface to initialize these flags to an alternate input source. - -func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) cli.BeforeFunc - InitInputSource is used to to setup an InputSourceContext on a cli.Command - Before method. It will create a new input source based on the func provided. - If there is no error it will then apply the new input source to any flags - that are supported by the input source - -func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *cli.Context) (InputSourceContext, error)) cli.BeforeFunc - InitInputSourceWithContext is used to to setup an InputSourceContext on - a cli.Command Before method. It will create a new input source based on - the func provided with potentially using existing cli.Context values to - initialize itself. If there is no error it will then apply the new input - source to any flags that are supported by the input source - -func NewJSONSourceFromFlagFunc(flag string) func(c *cli.Context) (InputSourceContext, error) - NewJSONSourceFromFlagFunc returns a func that takes a cli.Context and - returns an InputSourceContext suitable for retrieving config variables from - a file containing JSON data with the file name defined by the given flag. - -func NewTomlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) - NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a - provided flag name and source context. - -func NewYamlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) - NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a - provided flag name and source context. - - -TYPES - -type BoolFlag struct { - *cli.BoolFlag - // Has unexported fields. -} - BoolFlag is the flag type that wraps cli.BoolFlag to allow for other values - to be specified - -func NewBoolFlag(fl *cli.BoolFlag) *BoolFlag - NewBoolFlag creates a new BoolFlag - -func (f *BoolFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - BoolFlag.Apply - -func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Bool value to the flagSet if required - -type DurationFlag struct { - *cli.DurationFlag - // Has unexported fields. -} - DurationFlag is the flag type that wraps cli.DurationFlag to allow for other - values to be specified - -func NewDurationFlag(fl *cli.DurationFlag) *DurationFlag - NewDurationFlag creates a new DurationFlag - -func (f *DurationFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - DurationFlag.Apply - -func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Duration value to the flagSet if required - -type FlagInputSourceExtension interface { - cli.Flag - ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error -} - FlagInputSourceExtension is an extension interface of cli.Flag that allows a - value to be set on the existing parsed flags. - -type Float64Flag struct { - *cli.Float64Flag - // Has unexported fields. -} - Float64Flag is the flag type that wraps cli.Float64Flag to allow for other - values to be specified - -func NewFloat64Flag(fl *cli.Float64Flag) *Float64Flag - NewFloat64Flag creates a new Float64Flag - -func (f *Float64Flag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Float64Flag.Apply - -func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Float64 value to the flagSet if required - -type Float64SliceFlag struct { - *cli.Float64SliceFlag - // Has unexported fields. -} - Float64SliceFlag is the flag type that wraps cli.Float64SliceFlag to allow - for other values to be specified - -func NewFloat64SliceFlag(fl *cli.Float64SliceFlag) *Float64SliceFlag - NewFloat64SliceFlag creates a new Float64SliceFlag - -func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Float64SliceFlag.Apply - -type GenericFlag struct { - *cli.GenericFlag - // Has unexported fields. -} - GenericFlag is the flag type that wraps cli.GenericFlag to allow for other - values to be specified - -func NewGenericFlag(fl *cli.GenericFlag) *GenericFlag - NewGenericFlag creates a new GenericFlag - -func (f *GenericFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - GenericFlag.Apply - -func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a generic value to the flagSet if required - -type InputSourceContext interface { - Source() string - - Int(name string) (int, error) - Duration(name string) (time.Duration, error) - Float64(name string) (float64, error) - String(name string) (string, error) - StringSlice(name string) ([]string, error) - IntSlice(name string) ([]int, error) - Int64Slice(name string) ([]int64, error) - Generic(name string) (cli.Generic, error) - Bool(name string) (bool, error) - - // Has unexported methods. -} - InputSourceContext is an interface used to allow other input sources to be - implemented as needed. - - Source returns an identifier for the input source. In case of file source it - should return path to the file. - -func NewJSONSource(data []byte) (InputSourceContext, error) - NewJSONSource returns an InputSourceContext suitable for retrieving config - variables from raw JSON data. - -func NewJSONSourceFromFile(f string) (InputSourceContext, error) - NewJSONSourceFromFile returns an InputSourceContext suitable for retrieving - config variables from a file (or url) containing JSON data. - -func NewJSONSourceFromReader(r io.Reader) (InputSourceContext, error) - NewJSONSourceFromReader returns an InputSourceContext suitable for - retrieving config variables from an io.Reader that returns JSON data. - -func NewTomlSourceFromFile(file string) (InputSourceContext, error) - NewTomlSourceFromFile creates a new TOML InputSourceContext from a filepath. - -func NewYamlSourceFromFile(file string) (InputSourceContext, error) - NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath. - -type Int64Flag struct { - *cli.Int64Flag - // Has unexported fields. -} - Int64Flag is the flag type that wraps cli.Int64Flag to allow for other - values to be specified - -func NewInt64Flag(fl *cli.Int64Flag) *Int64Flag - NewInt64Flag creates a new Int64Flag - -func (f *Int64Flag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Int64Flag.Apply - -type Int64SliceFlag struct { - *cli.Int64SliceFlag - // Has unexported fields. -} - Int64SliceFlag is the flag type that wraps cli.Int64SliceFlag to allow for - other values to be specified - -func NewInt64SliceFlag(fl *cli.Int64SliceFlag) *Int64SliceFlag - NewInt64SliceFlag creates a new Int64SliceFlag - -func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Int64SliceFlag.Apply - -func (f *Int64SliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Int64Slice value if required - -type IntFlag struct { - *cli.IntFlag - // Has unexported fields. -} - IntFlag is the flag type that wraps cli.IntFlag to allow for other values to - be specified - -func NewIntFlag(fl *cli.IntFlag) *IntFlag - NewIntFlag creates a new IntFlag - -func (f *IntFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - IntFlag.Apply - -func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a int value to the flagSet if required - -type IntSliceFlag struct { - *cli.IntSliceFlag - // Has unexported fields. -} - IntSliceFlag is the flag type that wraps cli.IntSliceFlag to allow for other - values to be specified - -func NewIntSliceFlag(fl *cli.IntSliceFlag) *IntSliceFlag - NewIntSliceFlag creates a new IntSliceFlag - -func (f *IntSliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - IntSliceFlag.Apply - -func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a IntSlice value if required - -type MapInputSource struct { - // Has unexported fields. -} - MapInputSource implements InputSourceContext to return data from the map - that is loaded. - -func NewMapInputSource(file string, valueMap map[interface{}]interface{}) *MapInputSource - NewMapInputSource creates a new MapInputSource for implementing custom input - sources. - -func (fsm *MapInputSource) Bool(name string) (bool, error) - Bool returns an bool from the map otherwise returns false - -func (fsm *MapInputSource) Duration(name string) (time.Duration, error) - Duration returns a duration from the map if it exists otherwise returns 0 - -func (fsm *MapInputSource) Float64(name string) (float64, error) - Float64 returns an float64 from the map if it exists otherwise returns 0 - -func (fsm *MapInputSource) Generic(name string) (cli.Generic, error) - Generic returns an cli.Generic from the map if it exists otherwise returns - nil - -func (fsm *MapInputSource) Int(name string) (int, error) - Int returns an int from the map if it exists otherwise returns 0 - -func (fsm *MapInputSource) Int64Slice(name string) ([]int64, error) - Int64Slice returns an []int64 from the map if it exists otherwise returns - nil - -func (fsm *MapInputSource) IntSlice(name string) ([]int, error) - IntSlice returns an []int from the map if it exists otherwise returns nil - -func (fsm *MapInputSource) Source() string - Source returns the path of the source file - -func (fsm *MapInputSource) String(name string) (string, error) - String returns a string from the map if it exists otherwise returns an empty - string - -func (fsm *MapInputSource) StringSlice(name string) ([]string, error) - StringSlice returns an []string from the map if it exists otherwise returns - nil - -type PathFlag struct { - *cli.PathFlag - // Has unexported fields. -} - PathFlag is the flag type that wraps cli.PathFlag to allow for other values - to be specified - -func NewPathFlag(fl *cli.PathFlag) *PathFlag - NewPathFlag creates a new PathFlag - -func (f *PathFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - PathFlag.Apply - -func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Path value to the flagSet if required - -type StringFlag struct { - *cli.StringFlag - // Has unexported fields. -} - StringFlag is the flag type that wraps cli.StringFlag to allow for other - values to be specified - -func NewStringFlag(fl *cli.StringFlag) *StringFlag - NewStringFlag creates a new StringFlag - -func (f *StringFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - StringFlag.Apply - -func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a String value to the flagSet if required - -type StringSliceFlag struct { - *cli.StringSliceFlag - // Has unexported fields. -} - StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow for - other values to be specified - -func NewStringSliceFlag(fl *cli.StringSliceFlag) *StringSliceFlag - NewStringSliceFlag creates a new StringSliceFlag - -func (f *StringSliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - StringSliceFlag.Apply - -func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a StringSlice value to the flagSet if required - -type Uint64Flag struct { - *cli.Uint64Flag - // Has unexported fields. -} - Uint64Flag is the flag type that wraps cli.Uint64Flag to allow for other - values to be specified - -func NewUint64Flag(fl *cli.Uint64Flag) *Uint64Flag - NewUint64Flag creates a new Uint64Flag - -func (f *Uint64Flag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Uint64Flag.Apply - -type UintFlag struct { - *cli.UintFlag - // Has unexported fields. -} - UintFlag is the flag type that wraps cli.UintFlag to allow for other values - to be specified - -func NewUintFlag(fl *cli.UintFlag) *UintFlag - NewUintFlag creates a new UintFlag - -func (f *UintFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - UintFlag.Apply - diff --git a/internal/build/build.go b/internal/build/build.go index 977a328..344a5d7 100644 --- a/internal/build/build.go +++ b/internal/build/build.go @@ -155,7 +155,7 @@ func main() { }, &cli.StringSliceFlag{ Name: "packages", - Value: cli.NewStringSlice("cli", "altsrc", "internal/build"), + Value: cli.NewStringSlice("cli", "internal/build"), }, }, } @@ -500,14 +500,9 @@ func GenerateActionFunc(cCtx *cli.Context) error { return err } - altsrcDocs, err := sh("go", "doc", "-all", filepath.Join(top, "altsrc")) - if err != nil { - return err - } - if err := os.WriteFile( filepath.Join(top, "godoc-current.txt"), - []byte(cliDocs+altsrcDocs), + []byte(cliDocs), 0644, ); err != nil { return err diff --git a/testdata/godoc-v3.x.txt b/testdata/godoc-v3.x.txt index 9abda4b..fbcd2ec 100644 --- a/testdata/godoc-v3.x.txt +++ b/testdata/godoc-v3.x.txt @@ -2313,358 +2313,3 @@ type VisibleFlagCategory interface { } VisibleFlagCategory is a category containing flags. -package altsrc // import "github.com/urfave/cli/v3/altsrc" - - -FUNCTIONS - -func ApplyInputSourceValues(cCtx *cli.Context, inputSourceContext InputSourceContext, flags []cli.Flag) error - ApplyInputSourceValues iterates over all provided flags and executes - ApplyInputSourceValue on flags implementing the FlagInputSourceExtension - interface to initialize these flags to an alternate input source. - -func InitInputSource(flags []cli.Flag, createInputSource func() (InputSourceContext, error)) cli.BeforeFunc - InitInputSource is used to to setup an InputSourceContext on a cli.Command - Before method. It will create a new input source based on the func provided. - If there is no error it will then apply the new input source to any flags - that are supported by the input source - -func InitInputSourceWithContext(flags []cli.Flag, createInputSource func(cCtx *cli.Context) (InputSourceContext, error)) cli.BeforeFunc - InitInputSourceWithContext is used to to setup an InputSourceContext on - a cli.Command Before method. It will create a new input source based on - the func provided with potentially using existing cli.Context values to - initialize itself. If there is no error it will then apply the new input - source to any flags that are supported by the input source - -func NewJSONSourceFromFlagFunc(flag string) func(c *cli.Context) (InputSourceContext, error) - NewJSONSourceFromFlagFunc returns a func that takes a cli.Context and - returns an InputSourceContext suitable for retrieving config variables from - a file containing JSON data with the file name defined by the given flag. - -func NewTomlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) - NewTomlSourceFromFlagFunc creates a new TOML InputSourceContext from a - provided flag name and source context. - -func NewYamlSourceFromFlagFunc(flagFileName string) func(cCtx *cli.Context) (InputSourceContext, error) - NewYamlSourceFromFlagFunc creates a new Yaml InputSourceContext from a - provided flag name and source context. - - -TYPES - -type BoolFlag struct { - *cli.BoolFlag - // Has unexported fields. -} - BoolFlag is the flag type that wraps cli.BoolFlag to allow for other values - to be specified - -func NewBoolFlag(fl *cli.BoolFlag) *BoolFlag - NewBoolFlag creates a new BoolFlag - -func (f *BoolFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - BoolFlag.Apply - -func (f *BoolFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Bool value to the flagSet if required - -type DurationFlag struct { - *cli.DurationFlag - // Has unexported fields. -} - DurationFlag is the flag type that wraps cli.DurationFlag to allow for other - values to be specified - -func NewDurationFlag(fl *cli.DurationFlag) *DurationFlag - NewDurationFlag creates a new DurationFlag - -func (f *DurationFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - DurationFlag.Apply - -func (f *DurationFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Duration value to the flagSet if required - -type FlagInputSourceExtension interface { - cli.Flag - ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error -} - FlagInputSourceExtension is an extension interface of cli.Flag that allows a - value to be set on the existing parsed flags. - -type Float64Flag struct { - *cli.Float64Flag - // Has unexported fields. -} - Float64Flag is the flag type that wraps cli.Float64Flag to allow for other - values to be specified - -func NewFloat64Flag(fl *cli.Float64Flag) *Float64Flag - NewFloat64Flag creates a new Float64Flag - -func (f *Float64Flag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Float64Flag.Apply - -func (f *Float64Flag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Float64 value to the flagSet if required - -type Float64SliceFlag struct { - *cli.Float64SliceFlag - // Has unexported fields. -} - Float64SliceFlag is the flag type that wraps cli.Float64SliceFlag to allow - for other values to be specified - -func NewFloat64SliceFlag(fl *cli.Float64SliceFlag) *Float64SliceFlag - NewFloat64SliceFlag creates a new Float64SliceFlag - -func (f *Float64SliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Float64SliceFlag.Apply - -type GenericFlag struct { - *cli.GenericFlag - // Has unexported fields. -} - GenericFlag is the flag type that wraps cli.GenericFlag to allow for other - values to be specified - -func NewGenericFlag(fl *cli.GenericFlag) *GenericFlag - NewGenericFlag creates a new GenericFlag - -func (f *GenericFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - GenericFlag.Apply - -func (f *GenericFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a generic value to the flagSet if required - -type InputSourceContext interface { - Source() string - - Int(name string) (int, error) - Duration(name string) (time.Duration, error) - Float64(name string) (float64, error) - String(name string) (string, error) - StringSlice(name string) ([]string, error) - IntSlice(name string) ([]int, error) - Int64Slice(name string) ([]int64, error) - Generic(name string) (cli.Generic, error) - Bool(name string) (bool, error) - - // Has unexported methods. -} - InputSourceContext is an interface used to allow other input sources to be - implemented as needed. - - Source returns an identifier for the input source. In case of file source it - should return path to the file. - -func NewJSONSource(data []byte) (InputSourceContext, error) - NewJSONSource returns an InputSourceContext suitable for retrieving config - variables from raw JSON data. - -func NewJSONSourceFromFile(f string) (InputSourceContext, error) - NewJSONSourceFromFile returns an InputSourceContext suitable for retrieving - config variables from a file (or url) containing JSON data. - -func NewJSONSourceFromReader(r io.Reader) (InputSourceContext, error) - NewJSONSourceFromReader returns an InputSourceContext suitable for - retrieving config variables from an io.Reader that returns JSON data. - -func NewTomlSourceFromFile(file string) (InputSourceContext, error) - NewTomlSourceFromFile creates a new TOML InputSourceContext from a filepath. - -func NewYamlSourceFromFile(file string) (InputSourceContext, error) - NewYamlSourceFromFile creates a new Yaml InputSourceContext from a filepath. - -type Int64Flag struct { - *cli.Int64Flag - // Has unexported fields. -} - Int64Flag is the flag type that wraps cli.Int64Flag to allow for other - values to be specified - -func NewInt64Flag(fl *cli.Int64Flag) *Int64Flag - NewInt64Flag creates a new Int64Flag - -func (f *Int64Flag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Int64Flag.Apply - -type Int64SliceFlag struct { - *cli.Int64SliceFlag - // Has unexported fields. -} - Int64SliceFlag is the flag type that wraps cli.Int64SliceFlag to allow for - other values to be specified - -func NewInt64SliceFlag(fl *cli.Int64SliceFlag) *Int64SliceFlag - NewInt64SliceFlag creates a new Int64SliceFlag - -func (f *Int64SliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Int64SliceFlag.Apply - -func (f *Int64SliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Int64Slice value if required - -type IntFlag struct { - *cli.IntFlag - // Has unexported fields. -} - IntFlag is the flag type that wraps cli.IntFlag to allow for other values to - be specified - -func NewIntFlag(fl *cli.IntFlag) *IntFlag - NewIntFlag creates a new IntFlag - -func (f *IntFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - IntFlag.Apply - -func (f *IntFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a int value to the flagSet if required - -type IntSliceFlag struct { - *cli.IntSliceFlag - // Has unexported fields. -} - IntSliceFlag is the flag type that wraps cli.IntSliceFlag to allow for other - values to be specified - -func NewIntSliceFlag(fl *cli.IntSliceFlag) *IntSliceFlag - NewIntSliceFlag creates a new IntSliceFlag - -func (f *IntSliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - IntSliceFlag.Apply - -func (f *IntSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a IntSlice value if required - -type MapInputSource struct { - // Has unexported fields. -} - MapInputSource implements InputSourceContext to return data from the map - that is loaded. - -func NewMapInputSource(file string, valueMap map[interface{}]interface{}) *MapInputSource - NewMapInputSource creates a new MapInputSource for implementing custom input - sources. - -func (fsm *MapInputSource) Bool(name string) (bool, error) - Bool returns an bool from the map otherwise returns false - -func (fsm *MapInputSource) Duration(name string) (time.Duration, error) - Duration returns a duration from the map if it exists otherwise returns 0 - -func (fsm *MapInputSource) Float64(name string) (float64, error) - Float64 returns an float64 from the map if it exists otherwise returns 0 - -func (fsm *MapInputSource) Generic(name string) (cli.Generic, error) - Generic returns an cli.Generic from the map if it exists otherwise returns - nil - -func (fsm *MapInputSource) Int(name string) (int, error) - Int returns an int from the map if it exists otherwise returns 0 - -func (fsm *MapInputSource) Int64Slice(name string) ([]int64, error) - Int64Slice returns an []int64 from the map if it exists otherwise returns - nil - -func (fsm *MapInputSource) IntSlice(name string) ([]int, error) - IntSlice returns an []int from the map if it exists otherwise returns nil - -func (fsm *MapInputSource) Source() string - Source returns the path of the source file - -func (fsm *MapInputSource) String(name string) (string, error) - String returns a string from the map if it exists otherwise returns an empty - string - -func (fsm *MapInputSource) StringSlice(name string) ([]string, error) - StringSlice returns an []string from the map if it exists otherwise returns - nil - -type PathFlag struct { - *cli.PathFlag - // Has unexported fields. -} - PathFlag is the flag type that wraps cli.PathFlag to allow for other values - to be specified - -func NewPathFlag(fl *cli.PathFlag) *PathFlag - NewPathFlag creates a new PathFlag - -func (f *PathFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - PathFlag.Apply - -func (f *PathFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a Path value to the flagSet if required - -type StringFlag struct { - *cli.StringFlag - // Has unexported fields. -} - StringFlag is the flag type that wraps cli.StringFlag to allow for other - values to be specified - -func NewStringFlag(fl *cli.StringFlag) *StringFlag - NewStringFlag creates a new StringFlag - -func (f *StringFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - StringFlag.Apply - -func (f *StringFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a String value to the flagSet if required - -type StringSliceFlag struct { - *cli.StringSliceFlag - // Has unexported fields. -} - StringSliceFlag is the flag type that wraps cli.StringSliceFlag to allow for - other values to be specified - -func NewStringSliceFlag(fl *cli.StringSliceFlag) *StringSliceFlag - NewStringSliceFlag creates a new StringSliceFlag - -func (f *StringSliceFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - StringSliceFlag.Apply - -func (f *StringSliceFlag) ApplyInputSourceValue(cCtx *cli.Context, isc InputSourceContext) error - ApplyInputSourceValue applies a StringSlice value to the flagSet if required - -type Uint64Flag struct { - *cli.Uint64Flag - // Has unexported fields. -} - Uint64Flag is the flag type that wraps cli.Uint64Flag to allow for other - values to be specified - -func NewUint64Flag(fl *cli.Uint64Flag) *Uint64Flag - NewUint64Flag creates a new Uint64Flag - -func (f *Uint64Flag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - Uint64Flag.Apply - -type UintFlag struct { - *cli.UintFlag - // Has unexported fields. -} - UintFlag is the flag type that wraps cli.UintFlag to allow for other values - to be specified - -func NewUintFlag(fl *cli.UintFlag) *UintFlag - NewUintFlag creates a new UintFlag - -func (f *UintFlag) Apply(set *flag.FlagSet) error - Apply saves the flagSet for later usage calls, then calls the wrapped - UintFlag.Apply -