Add example of HelpProvider + README

Relocate detailed help docs to main README
This commit is contained in:
Keilin Olsen
2021-11-30 23:18:58 +11:00
committed by Alec Thomas
parent 1db2ea27af
commit 6042c4b10e
3 changed files with 159 additions and 43 deletions
+107 -43
View File
@@ -12,6 +12,9 @@
1. [Help](#help) 1. [Help](#help)
1. [Help as a user of a Kong application](#help-as-a-user-of-a-kong-application) 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. [Defining help in Kong](#defining-help-in-kong)
1. [Showing the _command_'s detailed help](#showing-the-commands-detailed-help)
1. [Showing an _argument_'s detailed help](#showing-an-arguments-detailed-help)
1. [Showing a _flag_'s detailed help](#showing-a-flags-detailed-help)
1. [Command handling](#command-handling) 1. [Command handling](#command-handling)
1. [Switch on the command string](#switch-on-the-command-string) 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. [Attach a `Run(...) error` method to each command](#attach-a-run-error-method-to-each-command)
@@ -134,7 +137,68 @@ also be interpolated into the help string.
Finally, any command, argument, or flag type implementing the interface Finally, any command, argument, or flag type implementing the interface
`Help() string` will have this function called to retrieve more detail to `Help() string` will have this function called to retrieve more detail to
augment the help tag. This allows for much more descriptive text than can augment the help tag. This allows for much more descriptive text than can
fit in Go tags. fit in Go tags. [See _examples/shell/help](./_examples/shell/help)
#### Showing the _command_'s detailed help
A command's additional help text is _not_ shown from top-level help, but can be displayed within contextual help:
**Top level help**
```bash
$ go run ./_examples/shell/help --help
Usage: help <command>
An app demonstrating HelpProviders
Flags:
-h, --help Show context-sensitive help.
--flag Regular flag help
Commands:
echo Regular command help
```
**Contextual**
```bash
$ go run ./_examples/shell/help echo --help
Usage: help echo <msg>
Regular command help
🚀 additional command help
Arguments:
<msg> Regular argument help
Flags:
-h, --help Show context-sensitive help.
--flag Regular flag help
```
#### 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))
**Contextual argument help**
```bash
$ go run ./_examples/shell/help msg --help
Usage: help echo <msg>
Regular argument help
📣 additional argument help
Flags:
-h, --help Show context-sensitive help.
--flag Regular flag help
```
#### Showing a _flag_'s detailed help
> **TODO** (not known how to elicit this behaviour)
Neither `go run ./main.go --help --flag` nor `go run ./main.go --flag --help` appear to work
## Command handling ## Command handling
@@ -405,12 +469,12 @@ Kong includes a number of builtin custom type mappers. These can be used by
specifying the tag `type:"<type>"`. They are registered with the option specifying the tag `type:"<type>"`. They are registered with the option
function `NamedMapper(name, mapper)`. function `NamedMapper(name, mapper)`.
| Name | Description | Name | Description |
|-------------------|--------------------------------------------------- | -------------- | -------------------------------------------------------------------------------------------------- |
| `path` | A path. ~ expansion is applied. `-` is accepted for stdout, and will be passed unaltered. | `path` | A path. ~ expansion is applied. `-` is accepted for stdout, and will be passed unaltered. |
| `existingfile` | An existing file. ~ expansion is applied. `-` is accepted for stdin, and will be passed unaltered. | `existingfile` | An existing file. ~ expansion is applied. `-` is accepted for stdin, and will be passed unaltered. |
| `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 Slices and maps treat type tags specially. For slices, the `type:""` tag
@@ -426,12 +490,12 @@ specifies the element type. For maps, the tag has the format
Any field implementing `encoding.TextUnmarshaler` or `json.Unmarshaler` will use those interfaces 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: for decoding values. Kong also includes builtin support for many common Go types:
| Type | Description | Type | Description |
|---------------------|-------------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------- |
| `time.Duration` | Populated using `time.ParseDuration()`. | `time.Duration` | Populated using `time.ParseDuration()`. |
| `time.Time` | Populated using `time.Parse()`. Format defaults to RFC3339 but can be overridden with the `format:"X"` tag. | `time.Time` | Populated using `time.Parse()`. Format defaults to RFC3339 but can be overridden with the `format:"X"` tag. |
| `*os.File` | Path to a file that will be opened, or `-` for `os.Stdin`. File must be closed by the user. | `*os.File` | Path to a file that will be opened, or `-` for `os.Stdin`. File must be closed by the user. |
| `*url.URL` | Populated with `url.Parse()`. | `*url.URL` | Populated with `url.Parse()`. |
For more fine-grained control, if a field implements the For more fine-grained control, if a field implements the
[MapperValue](https://godoc.org/github.com/alecthomas/kong#MapperValue) [MapperValue](https://godoc.org/github.com/alecthomas/kong#MapperValue)
@@ -446,36 +510,36 @@ Tags can be in two forms:
Both can coexist with standard Tag parsing. 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. Required by default. | `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. |
`type:"X"` | Specify [named types](#custom-named-decoders) to use. | `type:"X"` | Specify [named types](#custom-named-decoders) to use. |
`placeholder:"X"` | Placeholder text. | `placeholder:"X"` | Placeholder text. |
`default:"X"` | Default value. | `default:"X"` | Default value. |
`default:"1"` | On a command, make it the default. | `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 | `default:"withargs"` | On a command, make it the default and allow args/flags from that command |
`short:"X"` | Short name, if flag. | `short:"X"` | Short name, if flag. |
`aliases:"X,Y"` | One or more aliases (for cmd). | `aliases:"X,Y"` | One or more aliases (for cmd). |
`required:""` | If present, flag/arg is required. | `required:""` | If present, flag/arg is required. |
`optional:""` | If present, flag/arg is optional. | `optional:""` | If present, flag/arg is optional. |
`hidden:""` | If present, command or flag is hidden. | `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:""` | 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. | `format:"X"` | Format for parsing input, if supported. |
`sep:"X"` | Separator for sequences (defaults to ","). May be `none` to disable splitting. | `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. | `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`. | `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. | `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. | `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. | `prefix:"X"` | Prefix for all sub-flags. |
`envprefix:"X"` | Envar 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. | `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. | `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. | `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:"-"` `` | `-` | Ignore the field. Useful for adding non-CLI fields to a configuration struct. e.g `` `kong:"-"` `` |
## Plugins ## Plugins
+3
View File
@@ -0,0 +1,3 @@
# Example of custom help providers
This example demonstrates how to add `Help() string` functions (ie. the `HelpProvider` interface) to your commands, arguments, and flags to augment the help text provided using `help:""` style tagged annotations.
+49
View File
@@ -0,0 +1,49 @@
package main
import (
"fmt"
"github.com/alecthomas/kong"
)
var cli struct {
Flag flagWithHelp `help:"Regular flag help"`
Echo commandWithHelp `cmd:"" help:"Regular command help"`
}
type flagWithHelp bool
func (f *flagWithHelp) Help() string {
return "🏁 additional flag help"
}
type commandWithHelp struct {
Msg argumentWithHelp `arg:"" help:"Regular argument help"`
}
func (c *commandWithHelp) Help() string {
return "🚀 additional command help"
}
type argumentWithHelp struct {
Msg string `arg:""`
}
func (f *argumentWithHelp) Help() string {
return "📣 additional argument help"
}
func main() {
ctx := kong.Parse(&cli,
kong.Name("help"),
kong.Description("An app demonstrating HelpProviders"),
kong.UsageOnError(),
kong.ConfigureHelp(kong.HelpOptions{
Compact: true,
Summary: false,
}))
switch ctx.Command() {
case "echo <msg>":
fmt.Println(cli.Echo.Msg)
}
}