Convert Option to an interface and make Vars a map conforming to the interface.

This commit is contained in:
Alec Thomas
2018-07-03 22:56:22 +10:00
parent b2cab08684
commit 1f1e9d0f0f
7 changed files with 44 additions and 35 deletions
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
command: | command: |
go get -v github.com/jstemmer/go-junit-report go get -v github.com/jstemmer/go-junit-report
go get -v -t -d ./... 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 mkdir ~/report
when: always when: always
- run: - run:
+1
View File
@@ -8,6 +8,7 @@ linters:
enable-all: true enable-all: true
disable: disable:
- maligned - maligned
- lll
linters-settings: linters-settings:
govet: govet:
+3 -3
View File
@@ -366,7 +366,7 @@ Variables are in the form:
${<name>} ${<name>}
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 variable references in the grammar will result in an error at construction
time. time.
@@ -385,9 +385,9 @@ type cli struct {
func main() { func main() {
kong.Parse(&cli, kong.Parse(&cli,
kong.Vars(map[string]string{ kong.Vars{
"config_file": "~/.app.conf", "config_file": "~/.app.conf",
})) })
} }
``` ```
+2 -2
View File
@@ -72,7 +72,7 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
} }
for _, option := range options { for _, option := range options {
if err := option(k); err != nil { if err := option.Apply(k); err != nil {
return nil, err return nil, err
} }
} }
@@ -90,7 +90,7 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
k.Model.HelpFlag = k.helpFlag k.Model.HelpFlag = k.helpFlag
for _, option := range k.postBuildOptions { for _, option := range k.postBuildOptions {
if err = option(k); err != nil { if err = option.Apply(k); err != nil {
return nil, err return nil, err
} }
} }
+2 -2
View File
@@ -520,11 +520,11 @@ func TestInterpolationIntoModel(t *testing.T) {
} }
_, err := kong.New(&cli) _, err := kong.New(&cli)
require.Error(t, err) 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.", "default": "Some default value.",
"somebody": "chickens!", "somebody": "chickens!",
"enum": "a,b,c,d", "enum": "a,b,c,d",
})) })
require.NoError(t, err) require.NoError(t, err)
flag := p.Model.Flags[1] flag := p.Model.Flags[1]
flag2 := p.Model.Flags[2] flag2 := p.Model.Flags[2]
+1 -1
View File
@@ -150,7 +150,7 @@ func (r *Registry) RegisterKind(kind reflect.Kind, mapper Mapper) *Registry {
return r 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. // eg.
// //
+34 -26
View File
@@ -10,20 +10,28 @@ import (
) )
// An Option applies optional changes to the Kong application. // 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. // Vars sets the variables to use for interpolation into help strings and default values.
// //
// See README for details. // See README for details.
func Vars(vars map[string]string) Option { type Vars map[string]string
return func(k *Kong) error {
k.vars = vars // Apply lets Vars act as an Option.
return nil 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. // 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 { return func(k *Kong) error {
k.Exit = exit k.Exit = exit
return nil return nil
@@ -31,7 +39,7 @@ func Exit(exit func(int)) Option {
} }
// NoDefaultHelp disables the default help flags. // NoDefaultHelp disables the default help flags.
func NoDefaultHelp() Option { func NoDefaultHelp() OptionFunc {
return func(k *Kong) error { return func(k *Kong) error {
k.noDefaultHelp = true k.noDefaultHelp = true
return nil return nil
@@ -39,29 +47,29 @@ func NoDefaultHelp() Option {
} }
// Name overrides the application name. // Name overrides the application name.
func Name(name string) Option { func Name(name string) OptionFunc {
return func(k *Kong) error { 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 k.Model.Name = name
return nil return nil
}) }))
return nil return nil
} }
} }
// Description sets the application description. // Description sets the application description.
func Description(description string) Option { func Description(description string) OptionFunc {
return func(k *Kong) error { 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 k.Model.Help = description
return nil return nil
}) }))
return nil return nil
} }
} }
// TypeMapper registers a mapper to a type. // 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 { return func(k *Kong) error {
k.registry.RegisterType(typ, mapper) k.registry.RegisterType(typ, mapper)
return nil return nil
@@ -69,7 +77,7 @@ func TypeMapper(typ reflect.Type, mapper Mapper) Option {
} }
// KindMapper registers a mapper to a kind. // 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 { return func(k *Kong) error {
k.registry.RegisterKind(kind, mapper) k.registry.RegisterKind(kind, mapper)
return nil return nil
@@ -77,7 +85,7 @@ func KindMapper(kind reflect.Kind, mapper Mapper) Option {
} }
// ValueMapper registers a mapper to a field value. // 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 { return func(k *Kong) error {
k.registry.RegisterValue(ptr, mapper) k.registry.RegisterValue(ptr, mapper)
return nil return nil
@@ -85,7 +93,7 @@ func ValueMapper(ptr interface{}, mapper Mapper) Option {
} }
// NamedMapper registers a mapper to a name. // 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 { return func(k *Kong) error {
k.registry.RegisterName(name, mapper) k.registry.RegisterName(name, mapper)
return nil return nil
@@ -93,7 +101,7 @@ func NamedMapper(name string, mapper Mapper) Option {
} }
// Writers overrides the default writers. Useful for testing or interactive use. // 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 { return func(k *Kong) error {
k.Stdout = stdout k.Stdout = stdout
k.Stderr = stderr 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 // 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. // 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) key := reflect.ValueOf(ptr)
if key.Kind() != reflect.Ptr { if key.Kind() != reflect.Ptr {
panic("expected a pointer") panic("expected a pointer")
@@ -124,7 +132,7 @@ func Hook(ptr interface{}, hook HookFunc) Option {
} }
// Help printer to use. // Help printer to use.
func Help(help HelpPrinter) Option { func Help(help HelpPrinter) OptionFunc {
return func(k *Kong) error { return func(k *Kong) error {
k.help = help k.help = help
return nil return nil
@@ -132,7 +140,7 @@ func Help(help HelpPrinter) Option {
} }
// ConfigureHelp sets the HelpOptions to use for printing help. // ConfigureHelp sets the HelpOptions to use for printing help.
func ConfigureHelp(options HelpOptions) Option { func ConfigureHelp(options HelpOptions) OptionFunc {
return func(k *Kong) error { return func(k *Kong) error {
k.helpOptions = options k.helpOptions = options
return nil 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. // 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 { return func(k *Kong) error {
k.usageOnError = true k.usageOnError = true
return nil return nil
@@ -148,7 +156,7 @@ func UsageOnError() Option {
} }
// ClearResolvers clears all existing resolvers. // ClearResolvers clears all existing resolvers.
func ClearResolvers() Option { func ClearResolvers() OptionFunc {
return func(k *Kong) error { return func(k *Kong) error {
k.resolvers = nil k.resolvers = nil
return nil return nil
@@ -156,7 +164,7 @@ func ClearResolvers() Option {
} }
// Resolver registers flag resolvers. // Resolver registers flag resolvers.
func Resolver(resolvers ...ResolverFunc) Option { func Resolver(resolvers ...ResolverFunc) OptionFunc {
return func(k *Kong) error { return func(k *Kong) error {
k.resolvers = append(k.resolvers, resolvers...) k.resolvers = append(k.resolvers, resolvers...)
return nil return nil
@@ -173,7 +181,7 @@ type ConfigurationFunc func(r io.Reader) (ResolverFunc, error)
// Note: The JSON function is a ConfigurationFunc. // Note: The JSON function is a ConfigurationFunc.
// //
// ~ expansion will occur on the provided paths. // ~ 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 { return func(k *Kong) error {
for _, path := range paths { for _, path := range paths {
path = expandPath(path) path = expandPath(path)