From 1f1e9d0f0f86b9d40cccceb925da84f8333e188b Mon Sep 17 00:00:00 2001 From: Alec Thomas Date: Tue, 3 Jul 2018 22:56:22 +1000 Subject: [PATCH] Convert Option to an interface and make Vars a map conforming to the interface. --- .circleci/config.yml | 2 +- .golangci.yml | 1 + README.md | 6 ++--- kong.go | 4 +-- kong_test.go | 4 +-- mapper.go | 2 +- options.go | 60 +++++++++++++++++++++++++------------------- 7 files changed, 44 insertions(+), 35 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7122cbc..53f457b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -12,7 +12,7 @@ jobs: command: | go get -v github.com/jstemmer/go-junit-report go get -v -t -d ./... - curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s latest + curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | bash -s v1.8 mkdir ~/report when: always - run: diff --git a/.golangci.yml b/.golangci.yml index 0e0401b..8e056c9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -8,6 +8,7 @@ linters: enable-all: true disable: - maligned + - lll linters-settings: govet: diff --git a/README.md b/README.md index 224c205..4022a27 100644 --- a/README.md +++ b/README.md @@ -366,7 +366,7 @@ Variables are in the form: ${} -Variables are set with the `Vars(map[string]string)` option. Undefined +Variables are set with the `Vars{"key": "value", ...}` option. Undefined variable references in the grammar will result in an error at construction time. @@ -385,9 +385,9 @@ type cli struct { func main() { kong.Parse(&cli, - kong.Vars(map[string]string{ + kong.Vars{ "config_file": "~/.app.conf", - })) + }) } ``` diff --git a/kong.go b/kong.go index 0771fe9..8ff4bcb 100644 --- a/kong.go +++ b/kong.go @@ -72,7 +72,7 @@ func New(grammar interface{}, options ...Option) (*Kong, error) { } for _, option := range options { - if err := option(k); err != nil { + if err := option.Apply(k); err != nil { return nil, err } } @@ -90,7 +90,7 @@ func New(grammar interface{}, options ...Option) (*Kong, error) { k.Model.HelpFlag = k.helpFlag for _, option := range k.postBuildOptions { - if err = option(k); err != nil { + if err = option.Apply(k); err != nil { return nil, err } } diff --git a/kong_test.go b/kong_test.go index 90cf24a..2f11c40 100644 --- a/kong_test.go +++ b/kong_test.go @@ -520,11 +520,11 @@ func TestInterpolationIntoModel(t *testing.T) { } _, err := kong.New(&cli) require.Error(t, err) - p, err := kong.New(&cli, kong.Vars(map[string]string{ + p, err := kong.New(&cli, kong.Vars{ "default": "Some default value.", "somebody": "chickens!", "enum": "a,b,c,d", - })) + }) require.NoError(t, err) flag := p.Model.Flags[1] flag2 := p.Model.Flags[2] diff --git a/mapper.go b/mapper.go index ba40b12..03acc02 100644 --- a/mapper.go +++ b/mapper.go @@ -150,7 +150,7 @@ func (r *Registry) RegisterKind(kind reflect.Kind, mapper Mapper) *Registry { return r } -// RegisterName registeres a mapper to be used if the value mapper has a "type" tag matching name. +// RegisterName registers a mapper to be used if the value mapper has a "type" tag matching name. // // eg. // diff --git a/options.go b/options.go index 4b99281..0db6d23 100644 --- a/options.go +++ b/options.go @@ -10,20 +10,28 @@ import ( ) // An Option applies optional changes to the Kong application. -type Option func(k *Kong) error +type Option interface { + Apply(k *Kong) error +} + +// OptionFunc is function that adheres to the Option interface. +type OptionFunc func(k *Kong) error + +func (o OptionFunc) Apply(k *Kong) error { return o(k) } // nolint: golint // Vars sets the variables to use for interpolation into help strings and default values. // // See README for details. -func Vars(vars map[string]string) Option { - return func(k *Kong) error { - k.vars = vars - return nil - } +type Vars map[string]string + +// Apply lets Vars act as an Option. +func (v Vars) Apply(k *Kong) error { + k.vars = v + return nil } // Exit overrides the function used to terminate. This is useful for testing or interactive use. -func Exit(exit func(int)) Option { +func Exit(exit func(int)) OptionFunc { return func(k *Kong) error { k.Exit = exit return nil @@ -31,7 +39,7 @@ func Exit(exit func(int)) Option { } // NoDefaultHelp disables the default help flags. -func NoDefaultHelp() Option { +func NoDefaultHelp() OptionFunc { return func(k *Kong) error { k.noDefaultHelp = true return nil @@ -39,29 +47,29 @@ func NoDefaultHelp() Option { } // Name overrides the application name. -func Name(name string) Option { +func Name(name string) OptionFunc { return func(k *Kong) error { - k.postBuildOptions = append(k.postBuildOptions, func(k *Kong) error { + k.postBuildOptions = append(k.postBuildOptions, OptionFunc(func(k *Kong) error { k.Model.Name = name return nil - }) + })) return nil } } // Description sets the application description. -func Description(description string) Option { +func Description(description string) OptionFunc { return func(k *Kong) error { - k.postBuildOptions = append(k.postBuildOptions, func(k *Kong) error { + k.postBuildOptions = append(k.postBuildOptions, OptionFunc(func(k *Kong) error { k.Model.Help = description return nil - }) + })) return nil } } // TypeMapper registers a mapper to a type. -func TypeMapper(typ reflect.Type, mapper Mapper) Option { +func TypeMapper(typ reflect.Type, mapper Mapper) OptionFunc { return func(k *Kong) error { k.registry.RegisterType(typ, mapper) return nil @@ -69,7 +77,7 @@ func TypeMapper(typ reflect.Type, mapper Mapper) Option { } // KindMapper registers a mapper to a kind. -func KindMapper(kind reflect.Kind, mapper Mapper) Option { +func KindMapper(kind reflect.Kind, mapper Mapper) OptionFunc { return func(k *Kong) error { k.registry.RegisterKind(kind, mapper) return nil @@ -77,7 +85,7 @@ func KindMapper(kind reflect.Kind, mapper Mapper) Option { } // ValueMapper registers a mapper to a field value. -func ValueMapper(ptr interface{}, mapper Mapper) Option { +func ValueMapper(ptr interface{}, mapper Mapper) OptionFunc { return func(k *Kong) error { k.registry.RegisterValue(ptr, mapper) return nil @@ -85,7 +93,7 @@ func ValueMapper(ptr interface{}, mapper Mapper) Option { } // NamedMapper registers a mapper to a name. -func NamedMapper(name string, mapper Mapper) Option { +func NamedMapper(name string, mapper Mapper) OptionFunc { return func(k *Kong) error { k.registry.RegisterName(name, mapper) return nil @@ -93,7 +101,7 @@ func NamedMapper(name string, mapper Mapper) Option { } // Writers overrides the default writers. Useful for testing or interactive use. -func Writers(stdout, stderr io.Writer) Option { +func Writers(stdout, stderr io.Writer) OptionFunc { return func(k *Kong) error { k.Stdout = stdout k.Stderr = stderr @@ -112,7 +120,7 @@ type HookFunc func(ctx *Context, path *Path) error // // Note that the hook will be called once for each time the corresponding node is encountered. This means that if a flag // is passed twice, its hook will be called twice. -func Hook(ptr interface{}, hook HookFunc) Option { +func Hook(ptr interface{}, hook HookFunc) OptionFunc { key := reflect.ValueOf(ptr) if key.Kind() != reflect.Ptr { panic("expected a pointer") @@ -124,7 +132,7 @@ func Hook(ptr interface{}, hook HookFunc) Option { } // Help printer to use. -func Help(help HelpPrinter) Option { +func Help(help HelpPrinter) OptionFunc { return func(k *Kong) error { k.help = help return nil @@ -132,7 +140,7 @@ func Help(help HelpPrinter) Option { } // ConfigureHelp sets the HelpOptions to use for printing help. -func ConfigureHelp(options HelpOptions) Option { +func ConfigureHelp(options HelpOptions) OptionFunc { return func(k *Kong) error { k.helpOptions = options return nil @@ -140,7 +148,7 @@ func ConfigureHelp(options HelpOptions) Option { } // UsageOnError configures Kong to display context-sensitive usage if FatalIfErrorf is called with an error. -func UsageOnError() Option { +func UsageOnError() OptionFunc { return func(k *Kong) error { k.usageOnError = true return nil @@ -148,7 +156,7 @@ func UsageOnError() Option { } // ClearResolvers clears all existing resolvers. -func ClearResolvers() Option { +func ClearResolvers() OptionFunc { return func(k *Kong) error { k.resolvers = nil return nil @@ -156,7 +164,7 @@ func ClearResolvers() Option { } // Resolver registers flag resolvers. -func Resolver(resolvers ...ResolverFunc) Option { +func Resolver(resolvers ...ResolverFunc) OptionFunc { return func(k *Kong) error { k.resolvers = append(k.resolvers, resolvers...) return nil @@ -173,7 +181,7 @@ type ConfigurationFunc func(r io.Reader) (ResolverFunc, error) // Note: The JSON function is a ConfigurationFunc. // // ~ expansion will occur on the provided paths. -func Configuration(loader ConfigurationFunc, paths ...string) Option { +func Configuration(loader ConfigurationFunc, paths ...string) OptionFunc { return func(k *Kong) error { for _, path := range paths { path = expandPath(path)