Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -5,16 +5,16 @@
|
||||
|
||||
[](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 depthto:3 -->
|
||||
|
||||
- [Version 1.0.0 Release](#version-100-release)
|
||||
- [Introduction](#introduction)
|
||||
- [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: BeforeReset, BeforeResolve, BeforeApply, AfterApply and the Bind option](#hooks-beforereset-beforeresolve-beforeapply-afterapply-and-the-bind-option)
|
||||
- [Attach a `Run(...) error` method to each command](#attach-a-run-error-method-to-each-command)
|
||||
- [Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply()](#hooks-beforereset-beforeresolve-beforeapply-afterapply)
|
||||
- [The Bind() option](#the-bind-option)
|
||||
- [Flags](#flags)
|
||||
- [Commands and sub-commands](#commands-and-sub-commands)
|
||||
- [Branching positional arguments](#branching-positional-arguments)
|
||||
@@ -25,22 +25,26 @@
|
||||
- [Nested data structure](#nested-data-structure)
|
||||
- [Custom named decoders](#custom-named-decoders)
|
||||
- [Supported field types](#supported-field-types)
|
||||
- [Custom decoders mappers](#custom-decoders-mappers)
|
||||
- [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)
|
||||
- [`Name(help)` and `Description(help)` - set the application name description](#namehelp-and-descriptionhelp---set-the-application-name-description)
|
||||
- [`Configuration(loader, 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)
|
||||
- [`ConfigureHelp(HelpOptions)` and `Help(HelpFunc)` - customising help](#configurehelphelpoptions-and-helphelpfunc---customising-help)
|
||||
- [Injecting values into `Run()` methods](#injecting-values-into-run-methods)
|
||||
- [Other options](#other-options)
|
||||
|
||||
<!-- /TOC -->
|
||||
## Version 1.0.0 Release
|
||||
|
||||
Kong has been stable for a long time, so it seemed appropriate to cut a 1.0 release.
|
||||
|
||||
There is one breaking change, [#436](https://github.com/alecthomas/kong/pull/436), which should effect relatively few users.
|
||||
|
||||
## Introduction
|
||||
|
||||
@@ -177,7 +181,7 @@ Flags:
|
||||
|
||||
#### Showing an _argument_'s detailed help
|
||||
|
||||
Custom help will only be shown for _positional arguments with named fields_ ([see the README section on positional arguments for more details on what that means](../../../README.md#branching-positional-arguments))
|
||||
Custom help will only be shown for _positional arguments with named fields_ ([see the README section on positional arguments for more details on what that means](#branching-positional-arguments))
|
||||
|
||||
**Contextual argument help**
|
||||
|
||||
@@ -302,17 +306,21 @@ func main() {
|
||||
|
||||
```
|
||||
|
||||
## Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option
|
||||
## Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply()
|
||||
|
||||
If a node in the grammar has a `BeforeReset(...)`, `BeforeResolve
|
||||
(...)`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those
|
||||
methods will be called before values are reset, before validation/assignment,
|
||||
and after validation/assignment, respectively.
|
||||
If a node in the CLI, or any of its embedded fields, implements a `BeforeReset(...) error`, `BeforeResolve
|
||||
(...) error`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those will be called as Kong
|
||||
resets, resolves, validates, and assigns values to the node.
|
||||
|
||||
| Hook | Description |
|
||||
| --------------- | ----------------------------------------------------------------------------------------------- |
|
||||
| `BeforeReset` | Invoked before values are reset to their defaults (as defined by the grammar) or to zero values |
|
||||
| `BeforeResolve` | Invoked before resolvers are applied to a node |
|
||||
| `BeforeApply` | Invoked before the traced command line arguments are applied to the grammar |
|
||||
| `AfterApply` | Invoked after command line arguments are applied to the grammar **and validated**` |
|
||||
|
||||
The `--help` flag is implemented with a `BeforeReset` hook.
|
||||
|
||||
Arguments to hooks are provided via the `Run(...)` method or `Bind(...)` option. `*Kong`, `*Context` and `*Path` are also bound and finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.
|
||||
|
||||
eg.
|
||||
|
||||
```go
|
||||
@@ -338,38 +346,42 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
Another example of using hooks is load the env-file:
|
||||
It's also possible to register these hooks with the functional options
|
||||
`kong.WithBeforeReset`, `kong.WithBeforeResolve`, `kong.WithBeforeApply`, and
|
||||
`kong.WithAfterApply`.
|
||||
|
||||
## The Bind() option
|
||||
|
||||
Arguments to hooks are provided via the `Run(...)` method or `Bind(...)` option. `*Kong`, `*Context`, `*Path` and parent commands are also bound and finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.
|
||||
|
||||
eg:
|
||||
|
||||
```go
|
||||
package main
|
||||
type CLI struct {
|
||||
Debug bool `help:"Enable debug mode."`
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"git.company.lan/gopkg/kong"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
Rm RmCmd `cmd:"" help:"Remove files."`
|
||||
Ls LsCmd `cmd:"" help:"List paths."`
|
||||
}
|
||||
|
||||
type EnvFlag string
|
||||
type AuthorName string
|
||||
|
||||
// BeforeResolve loads env file.
|
||||
func (c EnvFlag) BeforeReset(ctx *kong.Context, trace *kong.Path) error {
|
||||
path := string(ctx.FlagValue(trace.Flag).(EnvFlag)) // nolint
|
||||
path = kong.ExpandPath(path)
|
||||
if err := godotenv.Load(path); err != nil {
|
||||
return err
|
||||
}
|
||||
// ...
|
||||
func (l *LsCmd) Run(cli *CLI) error {
|
||||
// use cli.Debug here !!
|
||||
return nil
|
||||
}
|
||||
|
||||
var CLI struct {
|
||||
EnvFile EnvFlag
|
||||
Flag `env:"FLAG"`
|
||||
func (r *RmCmD) Run(author AuthorName) error{
|
||||
// use binded author here
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
_ = kong.Parse(&CLI)
|
||||
fmt.Println(CLI.Flag)
|
||||
}
|
||||
var cli CLI
|
||||
|
||||
ctx := kong.Parse(&cli, Bind(AuthorName("penguin")))
|
||||
err := ctx.Run()
|
||||
```
|
||||
|
||||
## Flags
|
||||
@@ -553,36 +565,44 @@ Tags can be in two forms:
|
||||
|
||||
Both can coexist with standard Tag parsing.
|
||||
|
||||
| Tag | Description |
|
||||
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `cmd:""` | If present, struct is a command. |
|
||||
| `arg:""` | If present, field is an argument. Required by default. |
|
||||
| `env:"X,Y,..."` | Specify envars to use for default value. The envs are resolved in the declared order. The first value found is used. |
|
||||
| `name:"X"` | Long name, for overriding field name. |
|
||||
| `help:"X"` | Help text. |
|
||||
| `type:"X"` | Specify [named types](#custom-named-decoders) to use. |
|
||||
| `placeholder:"X"` | Placeholder text. |
|
||||
| `default:"X"` | Default value. |
|
||||
| `default:"1"` | On a command, make it the default. |
|
||||
| `default:"withargs"` | On a command, make it the default and allow args/flags from that command |
|
||||
| `short:"X"` | Short name, if flag. |
|
||||
| `aliases:"X,Y"` | One or more aliases (for cmd or flag). |
|
||||
| `required:""` | If present, flag/arg is required. |
|
||||
| `optional:""` | If present, flag/arg is optional. |
|
||||
| `hidden:""` | If present, command or flag is hidden. |
|
||||
| `negatable:""` | If present on a `bool` field, supports prefixing a flag with `--no-` to invert the default value |
|
||||
| `format:"X"` | Format for parsing input, if supported. |
|
||||
| `sep:"X"` | Separator for sequences (defaults to ","). May be `none` to disable splitting. |
|
||||
| `mapsep:"X"` | Separator for maps (defaults to ";"). May be `none` to disable splitting. |
|
||||
| `enum:"X,Y,..."` | Set of valid values allowed for this flag. An enum field must be `required` or have a valid `default`. |
|
||||
| `group:"X"` | Logical group for a flag or command. |
|
||||
| `xor:"X,Y,..."` | Exclusive OR groups for flags. Only one flag in the group can be used which is restricted within the same command. When combined with `required`, at least one of the `xor` group will be required. |
|
||||
| `prefix:"X"` | Prefix for all sub-flags. |
|
||||
| `envprefix:"X"` | Envar prefix for all sub-flags. |
|
||||
| `set:"K=V"` | Set a variable for expansion by child elements. Multiples can occur. |
|
||||
| `embed:""` | If present, this field's children will be embedded in the parent. Useful for composition. |
|
||||
| `passthrough:""` | If present on a positional argument, it stops flag parsing when encountered, as if `--` was processed before. Useful for external command wrappers, like `exec`. On a command it requires that the command contains only one argument of type `[]string` which is then filled with everything following the command, unparsed. |
|
||||
| `-` | Ignore the field. Useful for adding non-CLI fields to a configuration struct. e.g `` `kong:"-"` `` |
|
||||
| Tag | Description |
|
||||
| -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `cmd:""` | If present, struct is a command. |
|
||||
| `arg:""` | If present, field is an argument. Required by default. |
|
||||
| `env:"X,Y,..."` | Specify envars to use for default value. The envs are resolved in the declared order. The first value found is used. |
|
||||
| `name:"X"` | Long name, for overriding field name. |
|
||||
| `help:"X"` | Help text. |
|
||||
| `type:"X"` | Specify [named types](#custom-named-decoders) to use. |
|
||||
| `placeholder:"X"` | Placeholder input, if flag. e.g. `` `placeholder:"<the-placeholder>"` `` will show `--flag-name=<the-placeholder>` when displaying help. |
|
||||
| `default:"X"` | Default value. |
|
||||
| `default:"1"` | On a command, make it the default. |
|
||||
| `default:"withargs"` | On a command, make it the default and allow args/flags from that command |
|
||||
| `short:"X"` | Short name, if flag. |
|
||||
| `aliases:"X,Y"` | One or more aliases (for cmd or flag). |
|
||||
| `required:""` | If present, flag/arg is required. |
|
||||
| `optional:""` | If present, flag/arg is optional. |
|
||||
| `hidden:""` | If present, command or flag is hidden. |
|
||||
| `negatable:""` | If present on a `bool` field, supports prefixing a flag with `--no-` to invert the default value |
|
||||
| `negatable:"X"` | If present on a `bool` field, supports `--X` to invert the default value |
|
||||
| `format:"X"` | Format for parsing input, if supported. |
|
||||
| `sep:"X"` | Separator for sequences (defaults to ","). May be `none` to disable splitting. |
|
||||
| `mapsep:"X"` | Separator for maps (defaults to ";"). May be `none` to disable splitting. |
|
||||
| `enum:"X,Y,..."` | Set of valid values allowed for this flag. An enum field must be `required` or have a valid `default`. |
|
||||
| `group:"X"` | Logical group for a flag or command. |
|
||||
| `xor:"X,Y,..."` | Exclusive OR groups for flags. Only one flag in the group can be used which is restricted within the same command. When combined with `required`, at least one of the `xor` group will be required. |
|
||||
| `and:"X,Y,..."` | AND groups for flags. All flags in the group must be used in the same command. When combined with `required`, all flags in the group will be required. |
|
||||
| `prefix:"X"` | Prefix for all sub-flags. |
|
||||
| `envprefix:"X"` | Envar prefix for all sub-flags. |
|
||||
| `xorprefix:"X"` | Prefix for all sub-flags in XOR/AND groups. |
|
||||
| `set:"K=V"` | Set a variable for expansion by child elements. Multiples can occur. |
|
||||
| `embed:""` | If present, this field's children will be embedded in the parent. Useful for composition. |
|
||||
| `passthrough:"<mode>"`[^1] | If present on a positional argument, it stops flag parsing when encountered, as if `--` was processed before. Useful for external command wrappers, like `exec`. On a command it requires that the command contains only one argument of type `[]string` which is then filled with everything following the command, unparsed. |
|
||||
| `-` | Ignore the field. Useful for adding non-CLI fields to a configuration struct. e.g `` `kong:"-"` `` |
|
||||
|
||||
[^1]:
|
||||
`<mode>` can be `partial` or `all` (the default). `all` will pass through all arguments including flags, including
|
||||
flags. `partial` will validate flags until the first positional argument is encountered, then pass through all remaining
|
||||
positional arguments.
|
||||
|
||||
## Plugins
|
||||
|
||||
@@ -611,8 +631,8 @@ also supports dynamically adding commands via `kong.DynamicCommand()`.
|
||||
|
||||
## Variable interpolation
|
||||
|
||||
Kong supports limited variable interpolation into help strings, enum lists and
|
||||
default values.
|
||||
Kong supports limited variable interpolation into help strings, placeholder strings,
|
||||
enum lists and default values.
|
||||
|
||||
Variables are in the form:
|
||||
|
||||
@@ -654,8 +674,7 @@ func main() {
|
||||
## Validation
|
||||
|
||||
Kong does validation on the structure of a command-line, but also supports
|
||||
extensible validation. Any node in the tree may implement the following
|
||||
interface:
|
||||
extensible validation. Any node in the tree may implement either of the following interfaces:
|
||||
|
||||
```go
|
||||
type Validatable interface {
|
||||
@@ -663,12 +682,18 @@ type Validatable interface {
|
||||
}
|
||||
```
|
||||
|
||||
```go
|
||||
type Validatable interface {
|
||||
Validate(kctx *kong.Context) error
|
||||
}
|
||||
```
|
||||
|
||||
If one of these nodes is in the active command-line it will be called during
|
||||
normal validation.
|
||||
|
||||
## Modifying Kong's behaviour
|
||||
|
||||
Each Kong parser can be configured via functional options passed to `New(cli interface{}, options...Option)`.
|
||||
Each Kong parser can be configured via functional options passed to `New(cli any, options...Option)`.
|
||||
|
||||
The full set of options can be found [here](https://godoc.org/github.com/alecthomas/kong#Option).
|
||||
|
||||
@@ -726,20 +751,25 @@ All builtin Go types (as well as a bunch of useful stdlib types like `time.Time`
|
||||
1. `NamedMapper(string, Mapper)` and using the tag key `type:"<name>"`.
|
||||
2. `KindMapper(reflect.Kind, Mapper)`.
|
||||
3. `TypeMapper(reflect.Type, Mapper)`.
|
||||
4. `ValueMapper(interface{}, Mapper)`, passing in a pointer to a field of the grammar.
|
||||
4. `ValueMapper(any, Mapper)`, passing in a pointer to a field of the grammar.
|
||||
|
||||
### `ConfigureHelp(HelpOptions)` and `Help(HelpFunc)` - customising help
|
||||
|
||||
The default help output is usually sufficient, but if not there are two solutions.
|
||||
|
||||
1. Use `ConfigureHelp(HelpOptions)` to configure how help is formatted (see [HelpOptions](https://godoc.org/github.com/alecthomas/kong#HelpOptions) for details).
|
||||
2. Custom help can be wired into Kong via the `Help(HelpFunc)` option. The `HelpFunc` is passed a `Context`, which contains the parsed context for the current command-line. See the implementation of `PrintHelp` for an example.
|
||||
2. Custom help can be wired into Kong via the `Help(HelpFunc)` option. The `HelpFunc` is passed a `Context`, which contains the parsed context for the current command-line. See the implementation of `DefaultHelpPrinter` for an example.
|
||||
3. Use `ValueFormatter(HelpValueFormatter)` if you want to just customize the help text that is accompanied by flags and arguments.
|
||||
4. Use `Groups([]Group)` if you want to customize group titles or add a header.
|
||||
|
||||
### `Bind(...)` - bind values for callback hooks and Run() methods
|
||||
### Injecting values into `Run()` methods
|
||||
|
||||
See the [section on hooks](#hooks-beforeresolve-beforeapply-afterapply-and-the-bind-option) for details.
|
||||
There are several ways to inject values into `Run()` methods:
|
||||
|
||||
1. Use `Bind()` to bind values directly.
|
||||
2. Use `BindTo()` to bind values to an interface type.
|
||||
3. Use `BindToProvider()` to bind values to a function that provides the value.
|
||||
4. Implement `Provide<Type>() error` methods on the command structure.
|
||||
|
||||
### Other options
|
||||
|
||||
|
||||
Reference in New Issue
Block a user