More enum fixes.
This commit is contained in:
@@ -4,40 +4,42 @@
|
|||||||
# Kong is a command-line parser for Go
|
# Kong is a command-line parser for Go
|
||||||
[](http://godoc.org/github.com/alecthomas/kong) [](https://circleci.com/gh/alecthomas/kong) [](https://goreportcard.com/report/github.com/alecthomas/kong) [](https://gophers.slack.com/messages/CN9DS8YF3)
|
[](http://godoc.org/github.com/alecthomas/kong) [](https://circleci.com/gh/alecthomas/kong) [](https://goreportcard.com/report/github.com/alecthomas/kong) [](https://gophers.slack.com/messages/CN9DS8YF3)
|
||||||
|
|
||||||
<!-- TOC depthfrom:2 updateonsave:true withlinks:true -->
|
<!-- https://github.com/naokazuterada/MarkdownTOC -->
|
||||||
|
|
||||||
- [Introduction](#introduction)
|
<!-- MarkdownTOC autolink="true" style="ordered" indent=" " -->
|
||||||
- [Help](#help)
|
|
||||||
- [Help as a user of a Kong application](#help-as-a-user-of-a-kong-application)
|
|
||||||
- [Defining help in Kong](#defining-help-in-kong)
|
|
||||||
- [Command handling](#command-handling)
|
|
||||||
- [Switch on the command string](#switch-on-the-command-string)
|
|
||||||
- [Attach a Run... error method to each command](#attach-a-run-error-method-to-each-command)
|
|
||||||
- [Hooks: BeforeResolve, BeforeApply, AfterApply and the Bind option](#hooks-beforeresolve-beforeapply-afterapply-and-the-bind-option)
|
|
||||||
- [Flags](#flags)
|
|
||||||
- [Commands and sub-commands](#commands-and-sub-commands)
|
|
||||||
- [Branching positional arguments](#branching-positional-arguments)
|
|
||||||
- [Terminating positional arguments](#terminating-positional-arguments)
|
|
||||||
- [Slices](#slices)
|
|
||||||
- [Maps](#maps)
|
|
||||||
- [Custom named decoders](#custom-named-decoders)
|
|
||||||
- [Supported field types](#supported-field-types)
|
|
||||||
- [Custom decoders mappers](#custom-decoders-mappers)
|
|
||||||
- [Supported tags](#supported-tags)
|
|
||||||
- [Plugins](#plugins)
|
|
||||||
- [Dynamic Commands](#dynamic-commands)
|
|
||||||
- [Variable interpolation](#variable-interpolation)
|
|
||||||
- [Validation](#validation)
|
|
||||||
- [Modifying Kong's behaviour](#modifying-kongs-behaviour)
|
|
||||||
- [Namehelp and Descriptionhelp - set the application name description](#namehelp-and-descriptionhelp---set-the-application-name-description)
|
|
||||||
- [Configurationloader, paths... - load defaults from configuration files](#configurationloader-paths---load-defaults-from-configuration-files)
|
|
||||||
- [Resolver... - support for default values from external sources](#resolver---support-for-default-values-from-external-sources)
|
|
||||||
- [*Mapper... - customising how the command-line is mapped to Go values](#mapper---customising-how-the-command-line-is-mapped-to-go-values)
|
|
||||||
- [ConfigureHelpHelpOptions and HelpHelpFunc - customising help](#configurehelphelpoptions-and-helphelpfunc---customising-help)
|
|
||||||
- [Bind... - bind values for callback hooks and Run methods](#bind---bind-values-for-callback-hooks-and-run-methods)
|
|
||||||
- [Other options](#other-options)
|
|
||||||
|
|
||||||
<!-- /TOC -->
|
1. [Introduction](#introduction)
|
||||||
|
1. [Help](#help)
|
||||||
|
1. [Help as a user of a Kong application](#help-as-a-user-of-a-kong-application)
|
||||||
|
1. [Defining help in Kong](#defining-help-in-kong)
|
||||||
|
1. [Command handling](#command-handling)
|
||||||
|
1. [Switch on the command string](#switch-on-the-command-string)
|
||||||
|
1. [Attach a `Run(...) error` method to each command](#attach-a-run-error-method-to-each-command)
|
||||||
|
1. [Hooks: BeforeResolve\(\), BeforeApply\(\), AfterApply\(\) and the Bind\(\) option](#hooks-beforeresolve-beforeapply-afterapply-and-the-bind-option)
|
||||||
|
1. [Flags](#flags)
|
||||||
|
1. [Commands and sub-commands](#commands-and-sub-commands)
|
||||||
|
1. [Branching positional arguments](#branching-positional-arguments)
|
||||||
|
1. [Positional arguments](#positional-arguments)
|
||||||
|
1. [Slices](#slices)
|
||||||
|
1. [Maps](#maps)
|
||||||
|
1. [Custom named decoders](#custom-named-decoders)
|
||||||
|
1. [Supported field types](#supported-field-types)
|
||||||
|
1. [Custom decoders \(mappers\)](#custom-decoders-mappers)
|
||||||
|
1. [Supported tags](#supported-tags)
|
||||||
|
1. [Plugins](#plugins)
|
||||||
|
1. [Dynamic Commands](#dynamic-commands)
|
||||||
|
1. [Variable interpolation](#variable-interpolation)
|
||||||
|
1. [Validation](#validation)
|
||||||
|
1. [Modifying Kong's behaviour](#modifying-kongs-behaviour)
|
||||||
|
1. [`Name(help)` and `Description(help)` - set the application name description](#namehelp-and-descriptionhelp---set-the-application-name-description)
|
||||||
|
1. [`Configuration(loader, paths...)` - load defaults from configuration files](#configurationloader-paths---load-defaults-from-configuration-files)
|
||||||
|
1. [`Resolver(...)` - support for default values from external sources](#resolver---support-for-default-values-from-external-sources)
|
||||||
|
1. [`*Mapper(...)` - customising how the command-line is mapped to Go values](#mapper---customising-how-the-command-line-is-mapped-to-go-values)
|
||||||
|
1. [`ConfigureHelp(HelpOptions)` and `Help(HelpFunc)` - customising help](#configurehelphelpoptions-and-helphelpfunc---customising-help)
|
||||||
|
1. [`Bind(...)` - bind values for callback hooks and Run\(\) methods](#bind---bind-values-for-callback-hooks-and-run-methods)
|
||||||
|
1. [Other options](#other-options)
|
||||||
|
|
||||||
|
<!-- /MarkdownTOC -->
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
@@ -333,11 +335,14 @@ var CLI struct {
|
|||||||
|
|
||||||
This looks a little verbose in this contrived example, but typically this will not be the case.
|
This looks a little verbose in this contrived example, but typically this will not be the case.
|
||||||
|
|
||||||
## Terminating positional arguments
|
## Positional arguments
|
||||||
|
|
||||||
If a [mapped type](#mapper---customising-how-the-command-line-is-mapped-to-go-values) is tagged with `arg` it will be treated as the final positional values to be parsed on the command line.
|
If a field is tagged with `arg:""` it will be treated as the final positional
|
||||||
|
value to be parsed on the command line. By default positional arguments are
|
||||||
|
required, but specifying `optional:""` will alter this.
|
||||||
|
|
||||||
If a positional argument is a slice, all remaining arguments will be appended to that slice.
|
If a positional argument is a slice, all remaining arguments will be appended
|
||||||
|
to that slice.
|
||||||
|
|
||||||
## Slices
|
## Slices
|
||||||
|
|
||||||
@@ -429,7 +434,7 @@ Both can coexist with standard Tag parsing.
|
|||||||
Tag | Description
|
Tag | Description
|
||||||
-----------------------| -------------------------------------------
|
-----------------------| -------------------------------------------
|
||||||
`cmd:""` | If present, struct is a command.
|
`cmd:""` | If present, struct is a command.
|
||||||
`arg:""` | If present, field is an argument.
|
`arg:""` | If present, field is an argument. Required by default.
|
||||||
`env:"X"` | Specify envar to use for default value.
|
`env:"X"` | Specify envar to use for default value.
|
||||||
`name:"X"` | Long name, for overriding field name.
|
`name:"X"` | Long name, for overriding field name.
|
||||||
`help:"X"` | Help text.
|
`help:"X"` | Help text.
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
module github.com/alecthomas/kong
|
module github.com/alecthomas/kong
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48=
|
||||||
|
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
|||||||
+58
-11
@@ -10,6 +10,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/alecthomas/kong"
|
"github.com/alecthomas/kong"
|
||||||
|
"github.com/alecthomas/repr"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mustNew(t *testing.T, cli interface{}, options ...kong.Option) *kong.Kong {
|
func mustNew(t *testing.T, cli interface{}, options ...kong.Option) *kong.Kong {
|
||||||
@@ -1384,17 +1385,63 @@ func TestOptionReturnsErr(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestEnumValidation(t *testing.T) {
|
func TestEnumValidation(t *testing.T) {
|
||||||
var cli struct {
|
tests := []struct {
|
||||||
Enum string `arg:"" enum:"one,two"`
|
name string
|
||||||
|
cli interface{}
|
||||||
|
fail bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
"Arg",
|
||||||
|
&struct {
|
||||||
|
Enum string `arg:"" enum:"one,two"`
|
||||||
|
}{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"RequiredArg",
|
||||||
|
&struct {
|
||||||
|
Enum string `required:"" arg:"" enum:"one,two"`
|
||||||
|
}{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OptionalArg",
|
||||||
|
&struct {
|
||||||
|
Enum string `optional:"" arg:"" enum:"one,two"`
|
||||||
|
}{},
|
||||||
|
true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"RepeatedArgs",
|
||||||
|
&struct {
|
||||||
|
Enum []string `arg:"" enum:"one,two"`
|
||||||
|
}{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"RequiredRepeatedArgs",
|
||||||
|
&struct {
|
||||||
|
Enum []string `required:"" arg:"" enum:"one,two"`
|
||||||
|
}{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"OptionalRepeatedArgs",
|
||||||
|
&struct {
|
||||||
|
Enum []string `optional:"" arg:"" enum:"one,two"`
|
||||||
|
}{},
|
||||||
|
false,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
_, err := kong.New(&cli)
|
for _, test := range tests {
|
||||||
require.Error(t, err)
|
test := test
|
||||||
}
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
_, err := kong.New(test.cli)
|
||||||
func TestEnumValidationSlice(t *testing.T) {
|
if test.fail {
|
||||||
var cli struct {
|
require.Error(t, err, repr.String(test.cli))
|
||||||
Enum []string `arg:"" enum:"one,two"`
|
} else {
|
||||||
|
require.NoError(t, err, repr.String(test.cli))
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
_, err := kong.New(&cli)
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -186,6 +186,8 @@ func hydrateTag(t *Tag, typ reflect.Type) error { // nolint: gocyclo
|
|||||||
// Arguments with defaults are always optional.
|
// Arguments with defaults are always optional.
|
||||||
if t.Arg && t.Default != "" {
|
if t.Arg && t.Default != "" {
|
||||||
t.Optional = true
|
t.Optional = true
|
||||||
|
} else if t.Arg && !optional { // Arguments are required unless explicitly made optional.
|
||||||
|
t.Required = true
|
||||||
}
|
}
|
||||||
t.Name = t.Get("name")
|
t.Name = t.Get("name")
|
||||||
t.Help = t.Get("help")
|
t.Help = t.Get("help")
|
||||||
|
|||||||
Reference in New Issue
Block a user