github.com/alecthomas/kong@v0.9.1-0.20240410131203-2ab5733f1179/README.md (about) 1 <!-- markdownlint-disable MD013 MD033 --> 2 <p align="center"><img width="90%" src="kong.png" /></p> 3 4 # Kong is a command-line parser for Go 5 6 [![](https://godoc.org/github.com/alecthomas/kong?status.svg)](http://godoc.org/github.com/alecthomas/kong) [![CircleCI](https://img.shields.io/circleci/project/github/alecthomas/kong.svg)](https://circleci.com/gh/alecthomas/kong) [![Go Report Card](https://goreportcard.com/badge/github.com/alecthomas/kong)](https://goreportcard.com/report/github.com/alecthomas/kong) [![Slack chat](https://img.shields.io/static/v1?logo=slack&style=flat&label=slack&color=green&message=gophers)](https://gophers.slack.com/messages/CN9DS8YF3) 7 8 <!-- TOC depthfrom:2 depthto:3 --> 9 10 - [Introduction](#introduction) 11 - [Help](#help) 12 - [Help as a user of a Kong application](#help-as-a-user-of-a-kong-application) 13 - [Defining help in Kong](#defining-help-in-kong) 14 - [Command handling](#command-handling) 15 - [Switch on the command string](#switch-on-the-command-string) 16 - [Attach a Run... error method to each command](#attach-a-run-error-method-to-each-command) 17 - [Hooks: BeforeReset, BeforeResolve, BeforeApply, AfterApply and the Bind option](#hooks-beforereset-beforeresolve-beforeapply-afterapply-and-the-bind-option) 18 - [Flags](#flags) 19 - [Commands and sub-commands](#commands-and-sub-commands) 20 - [Branching positional arguments](#branching-positional-arguments) 21 - [Positional arguments](#positional-arguments) 22 - [Slices](#slices) 23 - [Maps](#maps) 24 - [Pointers](#pointers) 25 - [Nested data structure](#nested-data-structure) 26 - [Custom named decoders](#custom-named-decoders) 27 - [Supported field types](#supported-field-types) 28 - [Custom decoders mappers](#custom-decoders-mappers) 29 - [Supported tags](#supported-tags) 30 - [Plugins](#plugins) 31 - [Dynamic Commands](#dynamic-commands) 32 - [Variable interpolation](#variable-interpolation) 33 - [Validation](#validation) 34 - [Modifying Kong's behaviour](#modifying-kongs-behaviour) 35 - [Namehelp and Descriptionhelp - set the application name description](#namehelp-and-descriptionhelp---set-the-application-name-description) 36 - [Configurationloader, paths... - load defaults from configuration files](#configurationloader-paths---load-defaults-from-configuration-files) 37 - [Resolver... - support for default values from external sources](#resolver---support-for-default-values-from-external-sources) 38 - [\*Mapper... - customising how the command-line is mapped to Go values](#mapper---customising-how-the-command-line-is-mapped-to-go-values) 39 - [ConfigureHelpHelpOptions and HelpHelpFunc - customising help](#configurehelphelpoptions-and-helphelpfunc---customising-help) 40 - [Bind... - bind values for callback hooks and Run methods](#bind---bind-values-for-callback-hooks-and-run-methods) 41 - [Other options](#other-options) 42 43 <!-- /TOC --> 44 45 ## Introduction 46 47 Kong aims to support arbitrarily complex command-line structures with as little developer effort as possible. 48 49 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. 50 51 For example, the following command-line: 52 53 shell rm [-f] [-r] <paths> ... 54 shell ls [<paths> ...] 55 56 Can be represented by the following command-line structure: 57 58 ```go 59 package main 60 61 import "github.com/alecthomas/kong" 62 63 var CLI struct { 64 Rm struct { 65 Force bool `help:"Force removal."` 66 Recursive bool `help:"Recursively remove files."` 67 68 Paths []string `arg:"" name:"path" help:"Paths to remove." type:"path"` 69 } `cmd:"" help:"Remove files."` 70 71 Ls struct { 72 Paths []string `arg:"" optional:"" name:"path" help:"Paths to list." type:"path"` 73 } `cmd:"" help:"List paths."` 74 } 75 76 func main() { 77 ctx := kong.Parse(&CLI) 78 switch ctx.Command() { 79 case "rm <path>": 80 case "ls": 81 default: 82 panic(ctx.Command()) 83 } 84 } 85 ``` 86 87 ## Help 88 89 ### Help as a user of a Kong application 90 91 Every Kong application includes a `--help` flag that will display auto-generated help. 92 93 eg. 94 95 $ shell --help 96 usage: shell <command> 97 98 A shell-like example app. 99 100 Flags: 101 --help Show context-sensitive help. 102 --debug Debug mode. 103 104 Commands: 105 rm <path> ... 106 Remove files. 107 108 ls [<path> ...] 109 List paths. 110 111 If a command is provided, the help will show full detail on the command including all available flags. 112 113 eg. 114 115 $ shell --help rm 116 usage: shell rm <paths> ... 117 118 Remove files. 119 120 Arguments: 121 <paths> ... Paths to remove. 122 123 Flags: 124 --debug Debug mode. 125 126 -f, --force Force removal. 127 -r, --recursive Recursively remove files. 128 129 ### Defining help in Kong 130 131 Help is automatically generated from the command-line structure itself, 132 including `help:""` and other tags. [Variables](#variable-interpolation) will 133 also be interpolated into the help string. 134 135 Finally, any command, or argument type implementing the interface 136 `Help() string` will have this function called to retrieve more detail to 137 augment the help tag. This allows for much more descriptive text than can 138 fit in Go tags. [See \_examples/shell/help](./_examples/shell/help) 139 140 #### Showing the _command_'s detailed help 141 142 A command's additional help text is _not_ shown from top-level help, but can be displayed within contextual help: 143 144 **Top level help** 145 146 ```bash 147 $ go run ./_examples/shell/help --help 148 Usage: help <command> 149 150 An app demonstrating HelpProviders 151 152 Flags: 153 -h, --help Show context-sensitive help. 154 --flag Regular flag help 155 156 Commands: 157 echo Regular command help 158 ``` 159 160 **Contextual** 161 162 ```bash 163 $ go run ./_examples/shell/help echo --help 164 Usage: help echo <msg> 165 166 Regular command help 167 168 🚀 additional command help 169 170 Arguments: 171 <msg> Regular argument help 172 173 Flags: 174 -h, --help Show context-sensitive help. 175 --flag Regular flag help 176 ``` 177 178 #### Showing an _argument_'s detailed help 179 180 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)) 181 182 **Contextual argument help** 183 184 ```bash 185 $ go run ./_examples/shell/help msg --help 186 Usage: help echo <msg> 187 188 Regular argument help 189 190 📣 additional argument help 191 192 Flags: 193 -h, --help Show context-sensitive help. 194 --flag Regular flag help 195 ``` 196 197 ## Command handling 198 199 There are two ways to handle commands in Kong. 200 201 ### Switch on the command string 202 203 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: 204 205 There's an example of this pattern [here](https://github.com/alecthomas/kong/blob/master/_examples/shell/commandstring/main.go). 206 207 eg. 208 209 ```go 210 package main 211 212 import "github.com/alecthomas/kong" 213 214 var CLI struct { 215 Rm struct { 216 Force bool `help:"Force removal."` 217 Recursive bool `help:"Recursively remove files."` 218 219 Paths []string `arg:"" name:"path" help:"Paths to remove." type:"path"` 220 } `cmd:"" help:"Remove files."` 221 222 Ls struct { 223 Paths []string `arg:"" optional:"" name:"path" help:"Paths to list." type:"path"` 224 } `cmd:"" help:"List paths."` 225 } 226 227 func main() { 228 ctx := kong.Parse(&CLI) 229 switch ctx.Command() { 230 case "rm <path>": 231 case "ls": 232 default: 233 panic(ctx.Command()) 234 } 235 } 236 ``` 237 238 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. 239 240 ### Attach a `Run(...) error` method to each command 241 242 A more robust approach is to break each command out into their own structs: 243 244 1. Break leaf commands out into separate structs. 245 2. Attach a `Run(...) error` method to all leaf commands. 246 3. Call `kong.Kong.Parse()` to obtain a `kong.Context`. 247 4. Call `kong.Context.Run(bindings...)` to call the selected parsed command. 248 249 Once a command node is selected by Kong it will search from that node back to the root. Each 250 encountered command node with a `Run(...) error` will be called in reverse order. This allows 251 sub-trees to be re-used fairly conveniently. 252 253 In addition to values bound with the `kong.Bind(...)` option, any values 254 passed through to `kong.Context.Run(...)` are also bindable to the target's 255 `Run()` arguments. 256 257 Finally, hooks can also contribute bindings via `kong.Context.Bind()` and `kong.Context.BindTo()`. 258 259 There's a full example emulating part of the Docker CLI [here](https://github.com/alecthomas/kong/tree/master/_examples/docker). 260 261 eg. 262 263 ```go 264 type Context struct { 265 Debug bool 266 } 267 268 type RmCmd struct { 269 Force bool `help:"Force removal."` 270 Recursive bool `help:"Recursively remove files."` 271 272 Paths []string `arg:"" name:"path" help:"Paths to remove." type:"path"` 273 } 274 275 func (r *RmCmd) Run(ctx *Context) error { 276 fmt.Println("rm", r.Paths) 277 return nil 278 } 279 280 type LsCmd struct { 281 Paths []string `arg:"" optional:"" name:"path" help:"Paths to list." type:"path"` 282 } 283 284 func (l *LsCmd) Run(ctx *Context) error { 285 fmt.Println("ls", l.Paths) 286 return nil 287 } 288 289 var cli struct { 290 Debug bool `help:"Enable debug mode."` 291 292 Rm RmCmd `cmd:"" help:"Remove files."` 293 Ls LsCmd `cmd:"" help:"List paths."` 294 } 295 296 func main() { 297 ctx := kong.Parse(&cli) 298 // Call the Run() method of the selected parsed command. 299 err := ctx.Run(&Context{Debug: cli.Debug}) 300 ctx.FatalIfErrorf(err) 301 } 302 303 ``` 304 305 ## Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option 306 307 If a node in the grammar has a `BeforeReset(...)`, `BeforeResolve 308 (...)`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those 309 methods will be called before values are reset, before validation/assignment, 310 and after validation/assignment, respectively. 311 312 The `--help` flag is implemented with a `BeforeReset` hook. 313 314 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()`. 315 316 eg. 317 318 ```go 319 // A flag with a hook that, if triggered, will set the debug loggers output to stdout. 320 type debugFlag bool 321 322 func (d debugFlag) BeforeApply(logger *log.Logger) error { 323 logger.SetOutput(os.Stdout) 324 return nil 325 } 326 327 var cli struct { 328 Debug debugFlag `help:"Enable debug logging."` 329 } 330 331 func main() { 332 // Debug logger going to discard. 333 logger := log.New(io.Discard, "", log.LstdFlags) 334 335 ctx := kong.Parse(&cli, kong.Bind(logger)) 336 337 // ... 338 } 339 ``` 340 341 Another example of using hooks is load the env-file: 342 343 ```go 344 package main 345 346 import ( 347 "fmt" 348 "github.com/alecthomas/kong" 349 "github.com/joho/godotenv" 350 ) 351 352 type EnvFlag string 353 354 // BeforeResolve loads env file. 355 func (c EnvFlag) BeforeReset(ctx *kong.Context, trace *kong.Path) error { 356 path := string(ctx.FlagValue(trace.Flag).(EnvFlag)) // nolint 357 path = kong.ExpandPath(path) 358 if err := godotenv.Load(path); err != nil { 359 return err 360 } 361 return nil 362 } 363 364 var CLI struct { 365 EnvFile EnvFlag 366 Flag `env:"FLAG"` 367 } 368 369 func main() { 370 _ = kong.Parse(&CLI) 371 fmt.Println(CLI.Flag) 372 } 373 ``` 374 375 ## Flags 376 377 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. 378 379 eg. The command-line `app [--flag="foo"]` can be represented by the following. 380 381 ```go 382 type CLI struct { 383 Flag string 384 } 385 ``` 386 387 ## Commands and sub-commands 388 389 Sub-commands are specified by tagging a struct field with `cmd`. Kong supports arbitrarily nested commands. 390 391 eg. The following struct represents the CLI structure `command [--flag="str"] sub-command`. 392 393 ```go 394 type CLI struct { 395 Command struct { 396 Flag string 397 398 SubCommand struct { 399 } `cmd` 400 } `cmd` 401 } 402 ``` 403 404 If a sub-command is tagged with `default:"1"` it will be selected if there are no further arguments. If a sub-command is tagged with `default:"withargs"` it will be selected even if there are further arguments or flags and those arguments or flags are valid for the sub-command. This allows the user to omit the sub-command name on the CLI if its arguments/flags are not ambiguous with the sibling commands or flags. 405 406 ## Branching positional arguments 407 408 In addition to sub-commands, structs can also be configured as branching positional arguments. 409 410 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: 411 412 app rename <name> to <name> 413 414 Can be represented with the following: 415 416 ```go 417 var CLI struct { 418 Rename struct { 419 Name struct { 420 Name string `arg` // <-- NOTE: identical name to enclosing struct field. 421 To struct { 422 Name struct { 423 Name string `arg` 424 } `arg` 425 } `cmd` 426 } `arg` 427 } `cmd` 428 } 429 ``` 430 431 This looks a little verbose in this contrived example, but typically this will not be the case. 432 433 ## Positional arguments 434 435 If a field is tagged with `arg:""` it will be treated as the final positional 436 value to be parsed on the command line. By default positional arguments are 437 required, but specifying `optional:""` will alter this. 438 439 If a positional argument is a slice, all remaining arguments will be appended 440 to that slice. 441 442 ## Slices 443 444 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. 445 446 To represent the following command-line: 447 448 cmd ls <file> <file> ... 449 450 You would use the following: 451 452 ```go 453 var CLI struct { 454 Ls struct { 455 Files []string `arg:"" type:"existingfile"` 456 } `cmd` 457 } 458 ``` 459 460 ## Maps 461 462 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 `=`. 463 464 To represent the following command-line: 465 466 cmd config set <key>=<value> <key>=<value> ... 467 468 You would use the following: 469 470 ```go 471 var CLI struct { 472 Config struct { 473 Set struct { 474 Config map[string]float64 `arg:"" type:"file:"` 475 } `cmd` 476 } `cmd` 477 } 478 ``` 479 480 For flags, multiple key+value pairs should be separated by `mapsep:"rune"` tag (defaults to `;`) eg. `--set="key1=value1;key2=value2"`. 481 482 ## Pointers 483 484 Pointers work like the underlying type, except that you can differentiate between the presence of the zero value and no value being supplied. 485 486 For example: 487 488 ```go 489 var CLI struct { 490 Foo *int 491 } 492 ``` 493 494 Would produce a nil value for `Foo` if no `--foo` argument is supplied, but would have a pointer to the value 0 if the argument `--foo=0` was supplied. 495 496 ## Nested data structure 497 498 Kong support a nested data structure as well with `embed:""`. You can combine `embed:""` with `prefix:""`: 499 500 ```go 501 var CLI struct { 502 Logging struct { 503 Level string `enum:"debug,info,warn,error" default:"info"` 504 Type string `enum:"json,console" default:"console"` 505 } `embed:"" prefix:"logging."` 506 } 507 ``` 508 509 This configures Kong to accept flags `--logging.level` and `--logging.type`. 510 511 ## Custom named decoders 512 513 Kong includes a number of builtin custom type mappers. These can be used by 514 specifying the tag `type:"<type>"`. They are registered with the option 515 function `NamedMapper(name, mapper)`. 516 517 | Name | Description | 518 | -------------- | ---------------------------------------------------------------------------------------------------------------------- | 519 | `path` | A path. ~ expansion is applied. `-` is accepted for stdout, and will be passed unaltered. | 520 | `existingfile` | An existing file. ~ expansion is applied. `-` is accepted for stdin, and will be passed unaltered. | 521 | `existingdir` | An existing directory. ~ expansion is applied. | 522 | `counter` | Increment a numeric field. Useful for `-vvv`. Can accept `-s`, `--long` or `--long=N`. | 523 | `filecontent` | Read the file at path into the field. ~ expansion is applied. `-` is accepted for stdin, and will be passed unaltered. | 524 525 Slices and maps treat type tags specially. For slices, the `type:""` tag 526 specifies the element type. For maps, the tag has the format 527 `tag:"[<key>]:[<value>]"` where either may be omitted. 528 529 ## Supported field types 530 531 ## Custom decoders (mappers) 532 533 Any field implementing `encoding.TextUnmarshaler` or `json.Unmarshaler` will use those interfaces 534 for decoding values. Kong also includes builtin support for many common Go types: 535 536 | Type | Description | 537 | --------------- | ----------------------------------------------------------------------------------------------------------- | 538 | `time.Duration` | Populated using `time.ParseDuration()`. | 539 | `time.Time` | Populated using `time.Parse()`. Format defaults to RFC3339 but can be overridden with the `format:"X"` tag. | 540 | `*os.File` | Path to a file that will be opened, or `-` for `os.Stdin`. File must be closed by the user. | 541 | `*url.URL` | Populated with `url.Parse()`. | 542 543 For more fine-grained control, if a field implements the 544 [MapperValue](https://godoc.org/github.com/alecthomas/kong#MapperValue) 545 interface it will be used to decode arguments into the field. 546 547 ## Supported tags 548 549 Tags can be in two forms: 550 551 1. Standard Go syntax, eg. `kong:"required,name='foo'"`. 552 2. Bare tags, eg. `required:"" name:"foo"` 553 554 Both can coexist with standard Tag parsing. 555 556 | Tag | Description | 557 | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 558 | `cmd:""` | If present, struct is a command. | 559 | `arg:""` | If present, field is an argument. Required by default. | 560 | `env:"X,Y,..."` | Specify envars to use for default value. The envs are resolved in the declared order. The first value found is used. | 561 | `name:"X"` | Long name, for overriding field name. | 562 | `help:"X"` | Help text. | 563 | `type:"X"` | Specify [named types](#custom-named-decoders) to use. | 564 | `placeholder:"X"` | Placeholder text. | 565 | `default:"X"` | Default value. | 566 | `default:"1"` | On a command, make it the default. | 567 | `default:"withargs"` | On a command, make it the default and allow args/flags from that command | 568 | `short:"X"` | Short name, if flag. | 569 | `aliases:"X,Y"` | One or more aliases (for cmd or flag). | 570 | `required:""` | If present, flag/arg is required. | 571 | `optional:""` | If present, flag/arg is optional. | 572 | `hidden:""` | If present, command or flag is hidden. | 573 | `negatable:""` | If present on a `bool` field, supports prefixing a flag with `--no-` to invert the default value | 574 | `format:"X"` | Format for parsing input, if supported. | 575 | `sep:"X"` | Separator for sequences (defaults to ","). May be `none` to disable splitting. | 576 | `mapsep:"X"` | Separator for maps (defaults to ";"). May be `none` to disable splitting. | 577 | `enum:"X,Y,..."` | Set of valid values allowed for this flag. An enum field must be `required` or have a valid `default`. | 578 | `group:"X"` | Logical group for a flag or command. | 579 | `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. | 580 | `prefix:"X"` | Prefix for all sub-flags. | 581 | `envprefix:"X"` | Envar prefix for all sub-flags. | 582 | `set:"K=V"` | Set a variable for expansion by child elements. Multiples can occur. | 583 | `embed:""` | If present, this field's children will be embedded in the parent. Useful for composition. | 584 | `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. | 585 | `-` | Ignore the field. Useful for adding non-CLI fields to a configuration struct. e.g `` `kong:"-"` `` | 586 587 ## Plugins 588 589 Kong CLI's can be extended by embedding the `kong.Plugin` type and populating it with pointers to Kong annotated structs. For example: 590 591 ```go 592 var pluginOne struct { 593 PluginOneFlag string 594 } 595 var pluginTwo struct { 596 PluginTwoFlag string 597 } 598 var cli struct { 599 BaseFlag string 600 kong.Plugins 601 } 602 cli.Plugins = kong.Plugins{&pluginOne, &pluginTwo} 603 ``` 604 605 Additionally if an interface type is embedded, it can also be populated with a Kong annotated struct. 606 607 ## Dynamic Commands 608 609 While plugins give complete control over extending command-line interfaces, Kong 610 also supports dynamically adding commands via `kong.DynamicCommand()`. 611 612 ## Variable interpolation 613 614 Kong supports limited variable interpolation into help strings, enum lists and 615 default values. 616 617 Variables are in the form: 618 619 ${<name>} 620 ${<name>=<default>} 621 622 Variables are set with the `Vars{"key": "value", ...}` option. Undefined 623 variable references in the grammar without a default will result in an error at 624 construction time. 625 626 Variables can also be set via the `set:"K=V"` tag. In this case, those variables will be available for that 627 node and all children. This is useful for composition by allowing the same struct to be reused. 628 629 When interpolating into flag or argument help strings, some extra variables 630 are defined from the value itself: 631 632 ${default} 633 ${enum} 634 635 For flags with associated environment variables, the variable `${env}` can be 636 interpolated into the help string. In the absence of this variable in the 637 help string, Kong will append `($$${env})` to the help string. 638 639 eg. 640 641 ```go 642 type cli struct { 643 Config string `type:"path" default:"${config_file}"` 644 } 645 646 func main() { 647 kong.Parse(&cli, 648 kong.Vars{ 649 "config_file": "~/.app.conf", 650 }) 651 } 652 ``` 653 654 ## Validation 655 656 Kong does validation on the structure of a command-line, but also supports 657 extensible validation. Any node in the tree may implement the following 658 interface: 659 660 ```go 661 type Validatable interface { 662 Validate() error 663 } 664 ``` 665 666 If one of these nodes is in the active command-line it will be called during 667 normal validation. 668 669 ## Modifying Kong's behaviour 670 671 Each Kong parser can be configured via functional options passed to `New(cli interface{}, options...Option)`. 672 673 The full set of options can be found [here](https://godoc.org/github.com/alecthomas/kong#Option). 674 675 ### `Name(help)` and `Description(help)` - set the application name description 676 677 Set the application name and/or description. 678 679 The name of the application will default to the binary name, but can be overridden with `Name(name)`. 680 681 As with all help in Kong, text will be wrapped to the terminal. 682 683 ### `Configuration(loader, paths...)` - load defaults from configuration files 684 685 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. 686 687 eg. 688 689 ```go 690 kong.Parse(&cli, kong.Configuration(kong.JSON, "/etc/myapp.json", "~/.myapp.json")) 691 ``` 692 693 [See the tests](https://github.com/alecthomas/kong/blob/master/resolver_test.go#L206) for an example of how the JSON file is structured. 694 695 #### List of Configuration Loaders 696 697 - [YAML](https://github.com/alecthomas/kong-yaml) 698 - [HCL](https://github.com/alecthomas/kong-hcl) 699 - [TOML](https://github.com/alecthomas/kong-toml) 700 - [JSON](https://github.com/alecthomas/kong) 701 702 ### `Resolver(...)` - support for default values from external sources 703 704 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. 705 706 Example resolvers can be found in [resolver.go](https://github.com/alecthomas/kong/blob/master/resolver.go). 707 708 ### `*Mapper(...)` - customising how the command-line is mapped to Go values 709 710 Command-line arguments are mapped to Go values via the Mapper interface: 711 712 ```go 713 // A Mapper represents how a field is mapped from command-line values to Go. 714 // 715 // Mappers can be associated with concrete fields via pointer, reflect.Type, reflect.Kind, or via a "type" tag. 716 // 717 // Additionally, if a type implements the MapperValue interface, it will be used. 718 type Mapper interface { 719 // Decode ctx.Value with ctx.Scanner into target. 720 Decode(ctx *DecodeContext, target reflect.Value) error 721 } 722 ``` 723 724 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: 725 726 1. `NamedMapper(string, Mapper)` and using the tag key `type:"<name>"`. 727 2. `KindMapper(reflect.Kind, Mapper)`. 728 3. `TypeMapper(reflect.Type, Mapper)`. 729 4. `ValueMapper(interface{}, Mapper)`, passing in a pointer to a field of the grammar. 730 731 ### `ConfigureHelp(HelpOptions)` and `Help(HelpFunc)` - customising help 732 733 The default help output is usually sufficient, but if not there are two solutions. 734 735 1. Use `ConfigureHelp(HelpOptions)` to configure how help is formatted (see [HelpOptions](https://godoc.org/github.com/alecthomas/kong#HelpOptions) for details). 736 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. 737 3. Use `ValueFormatter(HelpValueFormatter)` if you want to just customize the help text that is accompanied by flags and arguments. 738 4. Use `Groups([]Group)` if you want to customize group titles or add a header. 739 740 ### `Bind(...)` - bind values for callback hooks and Run() methods 741 742 See the [section on hooks](#hooks-beforeresolve-beforeapply-afterapply-and-the-bind-option) for details. 743 744 ### Other options 745 746 The full set of options can be found [here](https://godoc.org/github.com/alecthomas/kong#Option).