Unbreak README.
This commit is contained in:
@@ -2,7 +2,6 @@
|
|||||||
<p align="center"><img width="90%" src="kong.png" /></p>
|
<p align="center"><img width="90%" src="kong.png" /></p>
|
||||||
|
|
||||||
# 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 -->
|
<!-- TOC depthFrom:2 updateOnSave:true withLinks:true -->
|
||||||
@@ -26,14 +25,6 @@
|
|||||||
- [Plugins](#plugins)
|
- [Plugins](#plugins)
|
||||||
- [Variable interpolation](#variable-interpolation)
|
- [Variable interpolation](#variable-interpolation)
|
||||||
- [Validation](#validation)
|
- [Validation](#validation)
|
||||||
- [Modifying Kong's behaviour](#modifying-kongs-behaviour)
|
|
||||||
- [`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)
|
|
||||||
- [`Bind(...)` - bind values for callback hooks and Run() methods](#bind---bind-values-for-callback-hooks-and-run-methods)
|
|
||||||
- [Other options](#other-options)
|
|
||||||
|
|
||||||
<!-- /TOC -->
|
<!-- /TOC -->
|
||||||
|
|
||||||
@@ -41,8 +32,7 @@
|
|||||||
|
|
||||||
Kong aims to support arbitrarily complex command-line structures with as little developer effort as possible.
|
Kong aims to support arbitrarily complex command-line structures with as little developer effort as possible.
|
||||||
|
|
||||||
To achieve that, command-lines are expressed as Go types, with the structure and tags directing how the command line is
|
To achieve that, command-lines are expressed as Go types, with the structure and tags directing how the command line is mapped onto the struct.
|
||||||
mapped onto the struct.
|
|
||||||
|
|
||||||
For example, the following command-line:
|
For example, the following command-line:
|
||||||
|
|
||||||
@@ -57,33 +47,32 @@ package main
|
|||||||
import "github.com/alecthomas/kong"
|
import "github.com/alecthomas/kong"
|
||||||
|
|
||||||
var CLI struct {
|
var CLI struct {
|
||||||
Rm struct {
|
Rm struct {
|
||||||
Force bool `help:"Force removal."`
|
Force bool `help:"Force removal."`
|
||||||
Recursive bool `help:"Recursively remove files."`
|
Recursive bool `help:"Recursively remove files."`
|
||||||
|
|
||||||
Paths []string `arg name:"path" help:"Paths to remove." type:"path"`
|
Paths []string `arg name:"path" help:"Paths to remove." type:"path"`
|
||||||
} `cmd help:"Remove files."`
|
} `cmd help:"Remove files."`
|
||||||
|
|
||||||
Ls struct {
|
Ls struct {
|
||||||
Paths []string `arg optional name:"path" help:"Paths to list." type:"path"`
|
Paths []string `arg optional name:"path" help:"Paths to list." type:"path"`
|
||||||
} `cmd help:"List paths."`
|
} `cmd help:"List paths."`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ctx := kong.Parse(&CLI)
|
ctx := kong.Parse(&CLI)
|
||||||
switch ctx.Command() {
|
switch ctx.Command() {
|
||||||
case "rm <path>":
|
case "rm <path>":
|
||||||
case "ls":
|
case "ls":
|
||||||
default:
|
default:
|
||||||
panic(ctx.Command())
|
panic(ctx.Command())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Help
|
## Help
|
||||||
|
|
||||||
Help is automatically generated. With no other arguments provided, help will display a full summary of all available
|
Help is automatically generated. With no other arguments provided, help will display a full summary of all available commands.
|
||||||
commands.
|
|
||||||
|
|
||||||
eg.
|
eg.
|
||||||
|
|
||||||
@@ -121,8 +110,9 @@ eg.
|
|||||||
-f, --force Force removal.
|
-f, --force Force removal.
|
||||||
-r, --recursive Recursively remove files.
|
-r, --recursive Recursively remove files.
|
||||||
|
|
||||||
For flags with associated environment variables, the variable `${env}` can be interpolated into the help string. In the
|
For flags with associated environment variables, the variable `${env}` can be
|
||||||
absence of this variable in the help,
|
interpolated into the help string. In the absence of this variable in the help,
|
||||||
|
|
||||||
|
|
||||||
## Command handling
|
## Command handling
|
||||||
|
|
||||||
@@ -130,9 +120,7 @@ There are two ways to handle commands in Kong.
|
|||||||
|
|
||||||
### Switch on the command string
|
### Switch on the command string
|
||||||
|
|
||||||
When you call `kong.Parse()` it will return a unique string representation of the command. Each command branch in the
|
When you call `kong.Parse()` it will return a unique string representation of the command. Each command branch in the hierarchy will be a bare word and each branching argument or required positional argument will be the name surrounded by angle brackets. Here's an example:
|
||||||
hierarchy will be a bare word and each branching argument or required positional argument will be the name surrounded by
|
|
||||||
angle brackets. Here's an example:
|
|
||||||
|
|
||||||
There's an example of this pattern [here](https://github.com/alecthomas/kong/blob/master/_examples/shell/main.go).
|
There's an example of this pattern [here](https://github.com/alecthomas/kong/blob/master/_examples/shell/main.go).
|
||||||
|
|
||||||
@@ -144,31 +132,30 @@ package main
|
|||||||
import "github.com/alecthomas/kong"
|
import "github.com/alecthomas/kong"
|
||||||
|
|
||||||
var CLI struct {
|
var CLI struct {
|
||||||
Rm struct {
|
Rm struct {
|
||||||
Force bool `help:"Force removal."`
|
Force bool `help:"Force removal."`
|
||||||
Recursive bool `help:"Recursively remove files."`
|
Recursive bool `help:"Recursively remove files."`
|
||||||
|
|
||||||
Paths []string `arg name:"path" help:"Paths to remove." type:"path"`
|
Paths []string `arg name:"path" help:"Paths to remove." type:"path"`
|
||||||
} `cmd help:"Remove files."`
|
} `cmd help:"Remove files."`
|
||||||
|
|
||||||
Ls struct {
|
Ls struct {
|
||||||
Paths []string `arg optional name:"path" help:"Paths to list." type:"path"`
|
Paths []string `arg optional name:"path" help:"Paths to list." type:"path"`
|
||||||
} `cmd help:"List paths."`
|
} `cmd help:"List paths."`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ctx := kong.Parse(&CLI)
|
ctx := kong.Parse(&CLI)
|
||||||
switch ctx.Command() {
|
switch ctx.Command() {
|
||||||
case "rm <path>":
|
case "rm <path>":
|
||||||
case "ls":
|
case "ls":
|
||||||
default:
|
default:
|
||||||
panic(ctx.Command())
|
panic(ctx.Command())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
This has the advantage that it is convenient, but the downside that if you modify your CLI structure, the strings may
|
This has the advantage that it is convenient, but the downside that if you modify your CLI structure, the strings may change. This can be fragile.
|
||||||
change. This can be fragile.
|
|
||||||
|
|
||||||
### Attach a `Run(...) error` method to each command
|
### Attach a `Run(...) error` method to each command
|
||||||
|
|
||||||
@@ -179,71 +166,69 @@ A more robust approach is to break each command out into their own structs:
|
|||||||
3. Call `kong.Kong.Parse()` to obtain a `kong.Context`.
|
3. Call `kong.Kong.Parse()` to obtain a `kong.Context`.
|
||||||
4. Call `kong.Context.Run(bindings...)` to call the selected parsed command.
|
4. Call `kong.Context.Run(bindings...)` to call the selected parsed command.
|
||||||
|
|
||||||
Once a command node is selected by Kong it will search from that node back to the root. Each encountered command node
|
Once a command node is selected by Kong it will search from that node back to the root. Each
|
||||||
with a `Run(...) error` will be called in reverse order. This allows sub-trees to be re-used fairly conveniently.
|
encountered command node with a `Run(...) error` will be called in reverse order. This allows
|
||||||
|
sub-trees to be re-used fairly conveniently.
|
||||||
|
|
||||||
In addition to values bound with the `kong.Bind(...)` option, any values passed through to `kong.Context.Run(...)` are
|
In addition to values bound with the `kong.Bind(...)` option, any values
|
||||||
also bindable to the target's
|
passed through to `kong.Context.Run(...)` are also bindable to the target's
|
||||||
`Run()` arguments.
|
`Run()` arguments.
|
||||||
|
|
||||||
Finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.
|
Finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.
|
||||||
|
|
||||||
There's a full example emulating part of the Docker
|
There's a full example emulating part of the Docker CLI [here](https://github.com/alecthomas/kong/tree/master/_examples/docker).
|
||||||
CLI [here](https://github.com/alecthomas/kong/tree/master/_examples/docker).
|
|
||||||
|
|
||||||
eg.
|
eg.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Context struct {
|
type Context struct {
|
||||||
Debug bool
|
Debug bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type RmCmd struct {
|
type RmCmd struct {
|
||||||
Force bool `help:"Force removal."`
|
Force bool `help:"Force removal."`
|
||||||
Recursive bool `help:"Recursively remove files."`
|
Recursive bool `help:"Recursively remove files."`
|
||||||
|
|
||||||
Paths []string `arg name:"path" help:"Paths to remove." type:"path"`
|
Paths []string `arg name:"path" help:"Paths to remove." type:"path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RmCmd) Run(ctx *Context) error {
|
func (r *RmCmd) Run(ctx *Context) error {
|
||||||
fmt.Println("rm", r.Paths)
|
fmt.Println("rm", r.Paths)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type LsCmd struct {
|
type LsCmd struct {
|
||||||
Paths []string `arg optional name:"path" help:"Paths to list." type:"path"`
|
Paths []string `arg optional name:"path" help:"Paths to list." type:"path"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (l *LsCmd) Run(ctx *Context) error {
|
func (l *LsCmd) Run(ctx *Context) error {
|
||||||
fmt.Println("ls", l.Paths)
|
fmt.Println("ls", l.Paths)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var cli struct {
|
var cli struct {
|
||||||
Debug bool `help:"Enable debug mode."`
|
Debug bool `help:"Enable debug mode."`
|
||||||
|
|
||||||
Rm RmCmd `cmd help:"Remove files."`
|
Rm RmCmd `cmd help:"Remove files."`
|
||||||
Ls LsCmd `cmd help:"List paths."`
|
Ls LsCmd `cmd help:"List paths."`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
ctx := kong.Parse(&cli)
|
ctx := kong.Parse(&cli)
|
||||||
// Call the Run() method of the selected parsed command.
|
// Call the Run() method of the selected parsed command.
|
||||||
err := ctx.Run(&Context{Debug: cli.Debug})
|
err := ctx.Run(&Context{Debug: cli.Debug})
|
||||||
ctx.FatalIfErrorf(err)
|
ctx.FatalIfErrorf(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Hooks: BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option
|
## Hooks: BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option
|
||||||
|
|
||||||
If a node in the grammar has a `BeforeResolve(...)`, `BeforeApply(...) error` and/or `AfterApply(...) error` method,
|
If a node in the grammar has a `BeforeResolve(...)`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those methods will be called before validation/assignment and after validation/assignment, respectively.
|
||||||
those methods will be called before validation/assignment and after validation/assignment, respectively.
|
|
||||||
|
|
||||||
The `--help` flag is implemented with a `BeforeApply` hook.
|
The `--help` flag is implemented with a `BeforeApply` hook.
|
||||||
|
|
||||||
Arguments to hooks are provided via the `Run(...)` method or `Bind(...)` option. `*Kong`, `*Context` and `*Path` are
|
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()`.
|
||||||
also bound and finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`.
|
|
||||||
|
|
||||||
eg.
|
eg.
|
||||||
|
|
||||||
@@ -252,34 +237,33 @@ eg.
|
|||||||
type debugFlag bool
|
type debugFlag bool
|
||||||
|
|
||||||
func (d debugFlag) BeforeApply(logger *log.Logger) error {
|
func (d debugFlag) BeforeApply(logger *log.Logger) error {
|
||||||
logger.SetOutput(os.Stdout)
|
logger.SetOutput(os.Stdout)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var cli struct {
|
var cli struct {
|
||||||
Debug debugFlag `help:"Enable debug logging."`
|
Debug debugFlag `help:"Enable debug logging."`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
// Debug logger going to discard.
|
// Debug logger going to discard.
|
||||||
logger := log.New(ioutil.Discard, "", log.LstdFlags)
|
logger := log.New(ioutil.Discard, "", log.LstdFlags)
|
||||||
|
|
||||||
ctx := kong.Parse(&cli, kong.Bind(logger))
|
ctx := kong.Parse(&cli, kong.Bind(logger))
|
||||||
|
|
||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Flags
|
## Flags
|
||||||
|
|
||||||
Any [mapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) field in the command structure *not*
|
Any [mapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) field in the command structure *not* tagged with `cmd` or `arg` will be a flag. Flags are optional by default.
|
||||||
tagged with `cmd` or `arg` will be a flag. Flags are optional by default.
|
|
||||||
|
|
||||||
eg. The command-line `app [--flag="foo"]` can be represented by the following.
|
eg. The command-line `app [--flag="foo"]` can be represented by the following.
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type CLI struct {
|
type CLI struct {
|
||||||
Flag string
|
Flag string
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -291,12 +275,12 @@ eg. The following struct represents the CLI structure `command [--flag="str"] su
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type CLI struct {
|
type CLI struct {
|
||||||
Command struct {
|
Command struct {
|
||||||
Flag string
|
Flag string
|
||||||
|
|
||||||
SubCommand struct {
|
SubCommand struct {
|
||||||
} `cmd`
|
} `cmd`
|
||||||
} `cmd`
|
} `cmd`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -306,9 +290,7 @@ If a sub-command is tagged with `default:"1"` it will be selected if there are n
|
|||||||
|
|
||||||
In addition to sub-commands, structs can also be configured as branching positional arguments.
|
In addition to sub-commands, structs can also be configured as branching positional arguments.
|
||||||
|
|
||||||
This is achieved by tagging an [unmapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) nested
|
This is achieved by tagging an [unmapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) nested struct field with `arg`, then including a positional argument field inside that struct _with the same name_. For example, the following command structure:
|
||||||
struct field with `arg`, then including a positional argument field inside that struct _with the same name_. For
|
|
||||||
example, the following command structure:
|
|
||||||
|
|
||||||
app rename <name> to <name>
|
app rename <name> to <name>
|
||||||
|
|
||||||
@@ -316,16 +298,16 @@ Can be represented with the following:
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
var CLI struct {
|
var CLI struct {
|
||||||
Rename struct {
|
Rename struct {
|
||||||
Name struct {
|
Name struct {
|
||||||
Name string `arg` // <-- NOTE: identical name to enclosing struct field.
|
Name string `arg` // <-- NOTE: identical name to enclosing struct field.
|
||||||
To struct {
|
To struct {
|
||||||
Name struct {
|
Name struct {
|
||||||
Name string `arg`
|
Name string `arg`
|
||||||
} `arg`
|
} `arg`
|
||||||
} `cmd`
|
} `cmd`
|
||||||
} `arg`
|
} `arg`
|
||||||
} `cmd`
|
} `cmd`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -333,16 +315,13 @@ This looks a little verbose in this contrived example, but typically this will n
|
|||||||
|
|
||||||
## Terminating positional arguments
|
## Terminating positional arguments
|
||||||
|
|
||||||
If a [mapped type](#mapper---customising-how-the-command-line-is-mapped-to-go-values) is tagged with `arg` it will be
|
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.
|
||||||
treated as the final positional values to be parsed on the command line.
|
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
Slice values are treated specially. First the input is split on the `sep:"<rune>"` tag (defaults to `,`), then each
|
Slice values are treated specially. First the input is split on the `sep:"<rune>"` tag (defaults to `,`), then each element is parsed by the slice element type and appended to the slice. If the same value is encountered multiple times, elements continue to be appended.
|
||||||
element is parsed by the slice element type and appended to the slice. If the same value is encountered multiple times,
|
|
||||||
elements continue to be appended.
|
|
||||||
|
|
||||||
To represent the following command-line:
|
To represent the following command-line:
|
||||||
|
|
||||||
@@ -352,16 +331,15 @@ You would use the following:
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
var CLI struct {
|
var CLI struct {
|
||||||
Ls struct {
|
Ls struct {
|
||||||
Files []string `arg type:"existingfile"`
|
Files []string `arg type:"existingfile"`
|
||||||
} `cmd`
|
} `cmd`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Maps
|
## Maps
|
||||||
|
|
||||||
Maps are similar to slices except that only one key/value pair can be assigned per value, and the `sep` tag denotes the
|
Maps are similar to slices except that only one key/value pair can be assigned per value, and the `sep` tag denotes the assignment character and defaults to `=`.
|
||||||
assignment character and defaults to `=`.
|
|
||||||
|
|
||||||
To represent the following command-line:
|
To represent the following command-line:
|
||||||
|
|
||||||
@@ -371,21 +349,21 @@ You would use the following:
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
var CLI struct {
|
var CLI struct {
|
||||||
Config struct {
|
Config struct {
|
||||||
Set struct {
|
Set struct {
|
||||||
Config map[string]float64 `arg type:"file:"`
|
Config map[string]float64 `arg type:"file:"`
|
||||||
} `cmd`
|
} `cmd`
|
||||||
} `cmd`
|
} `cmd`
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
For flags, multiple key+value pairs should be separated by `mapsep:"rune"` tag (defaults to `;`)
|
For flags, multiple key+value pairs should be separated by `mapsep:"rune"` tag (defaults to `;`) eg. `--set="key1=value1;key2=value2"`.
|
||||||
eg. `--set="key1=value1;key2=value2"`.
|
|
||||||
|
|
||||||
## Custom named decoders
|
## Custom named decoders
|
||||||
|
|
||||||
Kong includes a number of builtin custom type mappers. These can be used by specifying the tag `type:"<type>"`. They are
|
Kong includes a number of builtin custom type mappers. These can be used by
|
||||||
registered with the option function `NamedMapper(name, mapper)`.
|
specifying the tag `type:"<type>"`. They are registered with the option
|
||||||
|
function `NamedMapper(name, mapper)`.
|
||||||
|
|
||||||
| Name | Description
|
| Name | Description
|
||||||
|-------------------|---------------------------------------------------
|
|-------------------|---------------------------------------------------
|
||||||
@@ -394,16 +372,19 @@ registered with the option function `NamedMapper(name, mapper)`.
|
|||||||
| `existingdir` | An existing directory. ~ expansion is applied.
|
| `existingdir` | An existing directory. ~ expansion is applied.
|
||||||
| `counter` | Increment a numeric field. Useful for `-vvv`. Can accept `-s`, `--long` or `--long=N`.
|
| `counter` | Increment a numeric field. Useful for `-vvv`. Can accept `-s`, `--long` or `--long=N`.
|
||||||
|
|
||||||
Slices and maps treat type tags specially. For slices, the `type:""` tag specifies the element type. For maps, the tag
|
|
||||||
has the format
|
Slices and maps treat type tags specially. For slices, the `type:""` tag
|
||||||
|
specifies the element type. For maps, the tag has the format
|
||||||
`tag:"[<key>]:[<value>]"` where either may be omitted.
|
`tag:"[<key>]:[<value>]"` where either may be omitted.
|
||||||
|
|
||||||
## Supported field types
|
## Supported field types
|
||||||
|
|
||||||
|
|
||||||
## Custom decoders (mappers)
|
## Custom decoders (mappers)
|
||||||
|
|
||||||
Any field implementing `encoding.TextUnmarshaler` or `json.Unmarshaler` will use those interfaces for decoding values.
|
|
||||||
Kong also includes builtin support for many common Go types:
|
Any field implementing `encoding.TextUnmarshaler` or `json.Unmarshaler` will use those interfaces
|
||||||
|
for decoding values. Kong also includes builtin support for many common Go types:
|
||||||
|
|
||||||
| Type | Description
|
| Type | Description
|
||||||
|---------------------|--------------------------------------------
|
|---------------------|--------------------------------------------
|
||||||
@@ -453,19 +434,18 @@ Tag | Description
|
|||||||
|
|
||||||
## Plugins
|
## Plugins
|
||||||
|
|
||||||
Kong CLI's can be extended by embedding the `kong.Plugin` type and populating it with pointers to Kong annotated
|
Kong CLI's can be extended by embedding the `kong.Plugin` type and populating it with pointers to Kong annotated structs. For example:
|
||||||
structs. For example:
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var pluginOne struct {
|
var pluginOne struct {
|
||||||
PluginOneFlag string
|
PluginOneFlag string
|
||||||
}
|
}
|
||||||
var pluginTwo struct {
|
var pluginTwo struct {
|
||||||
PluginTwoFlag string
|
PluginTwoFlag string
|
||||||
}
|
}
|
||||||
var cli struct {
|
var cli struct {
|
||||||
BaseFlag string
|
BaseFlag string
|
||||||
kong.Plugins
|
kong.Plugins
|
||||||
}
|
}
|
||||||
cli.Plugins = kong.Plugins{&pluginOne, &pluginTwo}
|
cli.Plugins = kong.Plugins{&pluginOne, &pluginTwo}
|
||||||
```
|
```
|
||||||
@@ -474,20 +454,23 @@ Additionally if an interface type is embedded, it can also be populated with a K
|
|||||||
|
|
||||||
## Variable interpolation
|
## Variable interpolation
|
||||||
|
|
||||||
Kong supports limited variable interpolation into help strings, enum lists and default values.
|
Kong supports limited variable interpolation into help strings, enum lists and
|
||||||
|
default values.
|
||||||
|
|
||||||
Variables are in the form:
|
Variables are in the form:
|
||||||
|
|
||||||
${<name>}
|
${<name>}
|
||||||
${<name>=<default>}
|
${<name>=<default>}
|
||||||
|
|
||||||
Variables are set with the `Vars{"key": "value", ...}` option. Undefined variable references in the grammar without a
|
Variables are set with the `Vars{"key": "value", ...}` option. Undefined
|
||||||
default will result in an error at construction time.
|
variable references in the grammar without a default will result in an error at
|
||||||
|
construction time.
|
||||||
|
|
||||||
Variables can also be set via the `set:"K=V"` tag. In this case, those variables will be available for that node and all
|
Variables can also be set via the `set:"K=V"` tag. In this case, those variables will be available for that
|
||||||
children. This is useful for composition by allowing the same struct to be reused.
|
node and all children. This is useful for composition by allowing the same struct to be reused.
|
||||||
|
|
||||||
When interpolating into flag or argument help strings, some extra variables are defined from the value itself:
|
When interpolating into flag or argument help strings, some extra variables
|
||||||
|
are defined from the value itself:
|
||||||
|
|
||||||
${default}
|
${default}
|
||||||
${enum}
|
${enum}
|
||||||
@@ -496,17 +479,16 @@ eg.
|
|||||||
|
|
||||||
```go
|
```go
|
||||||
type cli struct {
|
type cli struct {
|
||||||
Config string `type:"path" default:"${config_file}"`
|
Config string `type:"path" default:"${config_file}"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
kong.Parse(&cli,
|
kong.Parse(&cli,
|
||||||
kong.Vars{
|
kong.Vars{
|
||||||
"config_file": "~/.app.conf",
|
"config_file": "~/.app.conf",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
Kong does validation on the structure of a command-line, but also supports
|
Kong does validation on the structure of a command-line, but also supports
|
||||||
@@ -516,11 +498,11 @@ interface:
|
|||||||
```go
|
```go
|
||||||
type Validatable interface {
|
type Validatable interface {
|
||||||
Validate() error
|
Validate() error
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If one of these nodes is in the active command-line it will be called during
|
+If one of these nodes is in the active command-line it will be called during
|
||||||
normal validation.
|
+normal validation.
|
||||||
|
|
||||||
## Modifying Kong's behaviour
|
## Modifying Kong's behaviour
|
||||||
|
|
||||||
@@ -538,8 +520,7 @@ As with all help in Kong, text will be wrapped to the terminal.
|
|||||||
|
|
||||||
### `Configuration(loader, paths...)` - load defaults from configuration files
|
### `Configuration(loader, paths...)` - load defaults from configuration files
|
||||||
|
|
||||||
This option provides Kong with support for loading defaults from a set of configuration files. Each file is opened, if
|
This option provides Kong with support for loading defaults from a set of configuration files. Each file is opened, if possible, and the loader called to create a resolver for that file.
|
||||||
possible, and the loader called to create a resolver for that file.
|
|
||||||
|
|
||||||
eg.
|
eg.
|
||||||
|
|
||||||
@@ -547,14 +528,11 @@ eg.
|
|||||||
kong.Parse(&cli, kong.Configuration(kong.JSON, "/etc/myapp.json", "~/.myapp.json"))
|
kong.Parse(&cli, kong.Configuration(kong.JSON, "/etc/myapp.json", "~/.myapp.json"))
|
||||||
```
|
```
|
||||||
|
|
||||||
[See the tests](https://github.com/alecthomas/kong/blob/master/resolver_test.go#L103) for an example of how the JSON
|
[See the tests](https://github.com/alecthomas/kong/blob/master/resolver_test.go#L103) for an example of how the JSON file is structured.
|
||||||
file is structured.
|
|
||||||
|
|
||||||
### `Resolver(...)` - support for default values from external sources
|
### `Resolver(...)` - support for default values from external sources
|
||||||
|
|
||||||
Resolvers are Kong's extension point for providing default values from external sources. As an example, support for
|
Resolvers are Kong's extension point for providing default values from external sources. As an example, support for environment variables via the `env` tag is provided by a resolver. There's also a builtin resolver for JSON configuration files.
|
||||||
environment variables via the `env` tag is provided by a resolver. There's also a builtin resolver for JSON
|
|
||||||
configuration files.
|
|
||||||
|
|
||||||
Example resolvers can be found in [resolver.go](https://github.com/alecthomas/kong/blob/master/resolver.go).
|
Example resolvers can be found in [resolver.go](https://github.com/alecthomas/kong/blob/master/resolver.go).
|
||||||
|
|
||||||
@@ -573,8 +551,7 @@ type Mapper interface {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
All builtin Go types (as well as a bunch of useful stdlib types like `time.Time`) have mappers registered by default.
|
All builtin Go types (as well as a bunch of useful stdlib types like `time.Time`) have mappers registered by default. Mappers for custom types can be added using `kong.??Mapper(...)` options. Mappers are applied to fields in four ways:
|
||||||
Mappers for custom types can be added using `kong.??Mapper(...)` options. Mappers are applied to fields in four ways:
|
|
||||||
|
|
||||||
1. `NamedMapper(string, Mapper)` and using the tag key `type:"<name>"`.
|
1. `NamedMapper(string, Mapper)` and using the tag key `type:"<name>"`.
|
||||||
2. `KindMapper(reflect.Kind, Mapper)`.
|
2. `KindMapper(reflect.Kind, Mapper)`.
|
||||||
@@ -585,12 +562,9 @@ Mappers for custom types can be added using `kong.??Mapper(...)` options. Mapper
|
|||||||
|
|
||||||
The default help output is usually sufficient, but if not there are two solutions.
|
The default help output is usually sufficient, but if not there are two solutions.
|
||||||
|
|
||||||
1. Use `ConfigureHelp(HelpOptions)` to configure how help is formatted (
|
1. Use `ConfigureHelp(HelpOptions)` to configure how help is formatted (see [HelpOptions](https://godoc.org/github.com/alecthomas/kong#HelpOptions) for details).
|
||||||
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
|
3. Use `HelpFormatter(HelpValueFormatter)` if you want to just customize the help text that is accompanied by flags and arguments.
|
||||||
contains the parsed context for the current command-line. See the implementation of `PrintHelp` for an example.
|
|
||||||
3. Use `HelpFormatter(HelpValueFormatter)` if you want to just customize the help text that is accompanied by flags and
|
|
||||||
arguments.
|
|
||||||
|
|
||||||
### `Bind(...)` - bind values for callback hooks and Run() methods
|
### `Bind(...)` - bind values for callback hooks and Run() methods
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user