mirror of
https://github.com/crazy-max/diun.git
synced 2025-03-18 13:12:54 +00:00
Merge pull request #1298 from crazy-max/dependabot/go_modules/github.com/alecthomas/kong-1.6.0
chore(deps): bump github.com/alecthomas/kong from 0.9.0 to 1.6.0
This commit is contained in:
commit
c9d62874f2
17 changed files with 461 additions and 214 deletions
2
go.mod
2
go.mod
|
@ -5,7 +5,7 @@ go 1.23.0
|
||||||
require (
|
require (
|
||||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||||
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30
|
github.com/PaulSonOfLars/gotgbot/v2 v2.0.0-rc.30
|
||||||
github.com/alecthomas/kong v0.9.0
|
github.com/alecthomas/kong v1.6.0
|
||||||
github.com/bmatcuk/doublestar/v3 v3.0.0
|
github.com/bmatcuk/doublestar/v3 v3.0.0
|
||||||
github.com/containerd/platforms v0.2.1
|
github.com/containerd/platforms v0.2.1
|
||||||
github.com/containers/image/v5 v5.33.0
|
github.com/containers/image/v5 v5.33.0
|
||||||
|
|
8
go.sum
8
go.sum
|
@ -20,10 +20,10 @@ github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAc
|
||||||
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ=
|
||||||
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||||
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||||
github.com/alecthomas/assert/v2 v2.6.0 h1:o3WJwILtexrEUk3cUVal3oiQY2tfgr/FHWiz/v2n4FU=
|
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||||
github.com/alecthomas/assert/v2 v2.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||||
github.com/alecthomas/kong v0.9.0 h1:G5diXxc85KvoV2f0ZRVuMsi45IrBgx9zDNGNj165aPA=
|
github.com/alecthomas/kong v1.6.0 h1:mwOzbdMR7uv2vul9J0FU3GYxE7ls/iX1ieMg5WIM6gE=
|
||||||
github.com/alecthomas/kong v0.9.0/go.mod h1:Y47y5gKfHp1hDc7CH7OeXgLIpp+Q2m1Ni0L5s3bI8Os=
|
github.com/alecthomas/kong v1.6.0/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU=
|
||||||
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc=
|
||||||
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
github.com/alecthomas/repr v0.4.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||||
|
|
19
vendor/github.com/alecthomas/kong/.golangci.yml
generated
vendored
19
vendor/github.com/alecthomas/kong/.golangci.yml
generated
vendored
|
@ -7,7 +7,6 @@ output:
|
||||||
linters:
|
linters:
|
||||||
enable-all: true
|
enable-all: true
|
||||||
disable:
|
disable:
|
||||||
- maligned
|
|
||||||
- lll
|
- lll
|
||||||
- gochecknoglobals
|
- gochecknoglobals
|
||||||
- wsl
|
- wsl
|
||||||
|
@ -17,11 +16,8 @@ linters:
|
||||||
- goprintffuncname
|
- goprintffuncname
|
||||||
- paralleltest
|
- paralleltest
|
||||||
- nlreturn
|
- nlreturn
|
||||||
- goerr113
|
|
||||||
- ifshort
|
|
||||||
- testpackage
|
- testpackage
|
||||||
- wrapcheck
|
- wrapcheck
|
||||||
- exhaustivestruct
|
|
||||||
- forbidigo
|
- forbidigo
|
||||||
- gci
|
- gci
|
||||||
- godot
|
- godot
|
||||||
|
@ -29,9 +25,6 @@ linters:
|
||||||
- cyclop
|
- cyclop
|
||||||
- errorlint
|
- errorlint
|
||||||
- nestif
|
- nestif
|
||||||
- golint
|
|
||||||
- scopelint
|
|
||||||
- interfacer
|
|
||||||
- tagliatelle
|
- tagliatelle
|
||||||
- thelper
|
- thelper
|
||||||
- godox
|
- godox
|
||||||
|
@ -41,16 +34,17 @@ linters:
|
||||||
- exhaustruct
|
- exhaustruct
|
||||||
- nonamedreturns
|
- nonamedreturns
|
||||||
- nilnil
|
- nilnil
|
||||||
- nosnakecase # deprecated since v1.48.1
|
|
||||||
- structcheck # deprecated since v1.49.0
|
|
||||||
- deadcode # deprecated since v1.49.0
|
|
||||||
- varcheck # deprecated since v1.49.0
|
|
||||||
- depguard # nothing to guard against yet
|
- depguard # nothing to guard against yet
|
||||||
- tagalign # hurts readability of kong tags
|
- tagalign # hurts readability of kong tags
|
||||||
|
- mnd
|
||||||
|
- perfsprint
|
||||||
|
- err113
|
||||||
|
- copyloopvar
|
||||||
|
- intrange
|
||||||
|
- execinquery
|
||||||
|
|
||||||
linters-settings:
|
linters-settings:
|
||||||
govet:
|
govet:
|
||||||
check-shadowing: true
|
|
||||||
# These govet checks are disabled by default, but they're useful.
|
# These govet checks are disabled by default, but they're useful.
|
||||||
enable:
|
enable:
|
||||||
- niliness
|
- niliness
|
||||||
|
@ -76,6 +70,7 @@ issues:
|
||||||
- 'bad syntax for struct tag key'
|
- 'bad syntax for struct tag key'
|
||||||
- 'bad syntax for struct tag pair'
|
- 'bad syntax for struct tag pair'
|
||||||
- 'result .* \(error\) is always nil'
|
- 'result .* \(error\) is always nil'
|
||||||
|
- 'Error return value of `fmt.Fprintln` is not checked'
|
||||||
|
|
||||||
exclude-rules:
|
exclude-rules:
|
||||||
# Don't warn on unused parameters.
|
# Don't warn on unused parameters.
|
||||||
|
|
104
vendor/github.com/alecthomas/kong/README.md
generated
vendored
104
vendor/github.com/alecthomas/kong/README.md
generated
vendored
|
@ -5,42 +5,46 @@
|
||||||
|
|
||||||
[](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 depthto:3 -->
|
- [Kong is a command-line parser for Go](#kong-is-a-command-line-parser-for-go)
|
||||||
|
- [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)
|
||||||
|
- [Flags](#flags)
|
||||||
|
- [Commands and sub-commands](#commands-and-sub-commands)
|
||||||
|
- [Branching positional arguments](#branching-positional-arguments)
|
||||||
|
- [Positional arguments](#positional-arguments)
|
||||||
|
- [Slices](#slices)
|
||||||
|
- [Maps](#maps)
|
||||||
|
- [Pointers](#pointers)
|
||||||
|
- [Nested data structure](#nested-data-structure)
|
||||||
|
- [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)
|
||||||
|
- [`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)
|
||||||
|
|
||||||
- [Introduction](#introduction)
|
## Version 1.0.0 Release
|
||||||
- [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)
|
|
||||||
- [Flags](#flags)
|
|
||||||
- [Commands and sub-commands](#commands-and-sub-commands)
|
|
||||||
- [Branching positional arguments](#branching-positional-arguments)
|
|
||||||
- [Positional arguments](#positional-arguments)
|
|
||||||
- [Slices](#slices)
|
|
||||||
- [Maps](#maps)
|
|
||||||
- [Pointers](#pointers)
|
|
||||||
- [Nested data structure](#nested-data-structure)
|
|
||||||
- [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 -->
|
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
|
## Introduction
|
||||||
|
|
||||||
|
@ -561,29 +565,35 @@ Both can coexist with standard Tag parsing.
|
||||||
| `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 input, if flag. e.g. `` `placeholder:"<the-placeholder>"` `` will show `--flag-name=<the-placeholder>` when displaying help. |
|
||||||
| `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 or flag). |
|
| `aliases:"X,Y"` | One or more aliases (for cmd or flag). |
|
||||||
| `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 |
|
||||||
|
| `negatable:"X"` | If present on a `bool` field, supports `--X` 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. |
|
||||||
|
| `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. |
|
| `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:"<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:"-"` `` |
|
| `-` | 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
|
## Plugins
|
||||||
|
|
||||||
Kong CLI's can be extended by embedding the `kong.Plugin` type and populating it with pointers to Kong annotated structs. For example:
|
Kong CLI's can be extended by embedding the `kong.Plugin` type and populating it with pointers to Kong annotated structs. For example:
|
||||||
|
@ -654,8 +664,7 @@ func main() {
|
||||||
## 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
|
||||||
extensible validation. Any node in the tree may implement the following
|
extensible validation. Any node in the tree may implement either of the following interfaces:
|
||||||
interface:
|
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Validatable interface {
|
type Validatable interface {
|
||||||
|
@ -663,6 +672,12 @@ 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
|
If one of these nodes is in the active command-line it will be called during
|
||||||
normal validation.
|
normal validation.
|
||||||
|
|
||||||
|
@ -733,13 +748,18 @@ All builtin Go types (as well as a bunch of useful stdlib types like `time.Time`
|
||||||
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 (see [HelpOptions](https://godoc.org/github.com/alecthomas/kong#HelpOptions) for details).
|
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.
|
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.
|
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
|
### Other options
|
||||||
|
|
||||||
|
|
40
vendor/github.com/alecthomas/kong/build.go
generated
vendored
40
vendor/github.com/alecthomas/kong/build.go
generated
vendored
|
@ -51,6 +51,9 @@ type flattenedField struct {
|
||||||
|
|
||||||
func flattenedFields(v reflect.Value, ptag *Tag) (out []flattenedField, err error) {
|
func flattenedFields(v reflect.Value, ptag *Tag) (out []flattenedField, err error) {
|
||||||
v = reflect.Indirect(v)
|
v = reflect.Indirect(v)
|
||||||
|
if v.Kind() != reflect.Struct {
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
for i := 0; i < v.NumField(); i++ {
|
for i := 0; i < v.NumField(); i++ {
|
||||||
ft := v.Type().Field(i)
|
ft := v.Type().Field(i)
|
||||||
fv := v.Field(i)
|
fv := v.Field(i)
|
||||||
|
@ -170,6 +173,12 @@ MAIN:
|
||||||
if flag.Short != 0 {
|
if flag.Short != 0 {
|
||||||
delete(seenFlags, "-"+string(flag.Short))
|
delete(seenFlags, "-"+string(flag.Short))
|
||||||
}
|
}
|
||||||
|
if negFlag := negatableFlagName(flag.Name, flag.Tag.Negatable); negFlag != "" {
|
||||||
|
delete(seenFlags, negFlag)
|
||||||
|
}
|
||||||
|
for _, aflag := range flag.Aliases {
|
||||||
|
delete(seenFlags, "--"+aflag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := validatePositionalArguments(node); err != nil {
|
if err := validatePositionalArguments(node); err != nil {
|
||||||
|
@ -272,17 +281,18 @@ func buildField(k *Kong, node *Node, v reflect.Value, ft reflect.StructField, fv
|
||||||
}
|
}
|
||||||
|
|
||||||
value := &Value{
|
value := &Value{
|
||||||
Name: name,
|
Name: name,
|
||||||
Help: tag.Help,
|
Help: tag.Help,
|
||||||
OrigHelp: tag.Help,
|
OrigHelp: tag.Help,
|
||||||
HasDefault: tag.HasDefault,
|
HasDefault: tag.HasDefault,
|
||||||
Default: tag.Default,
|
Default: tag.Default,
|
||||||
DefaultValue: reflect.New(fv.Type()).Elem(),
|
DefaultValue: reflect.New(fv.Type()).Elem(),
|
||||||
Mapper: mapper,
|
Mapper: mapper,
|
||||||
Tag: tag,
|
Tag: tag,
|
||||||
Target: fv,
|
Target: fv,
|
||||||
Enum: tag.Enum,
|
Enum: tag.Enum,
|
||||||
Passthrough: tag.Passthrough,
|
Passthrough: tag.Passthrough,
|
||||||
|
PassthroughMode: tag.PassthroughMode,
|
||||||
|
|
||||||
// Flags are optional by default, and args are required by default.
|
// Flags are optional by default, and args are required by default.
|
||||||
Required: (!tag.Arg && tag.Required) || (tag.Arg && !tag.Optional),
|
Required: (!tag.Arg && tag.Required) || (tag.Arg && !tag.Optional),
|
||||||
|
@ -309,6 +319,13 @@ func buildField(k *Kong, node *Node, v reflect.Value, ft reflect.StructField, fv
|
||||||
}
|
}
|
||||||
seenFlags["-"+string(tag.Short)] = true
|
seenFlags["-"+string(tag.Short)] = true
|
||||||
}
|
}
|
||||||
|
if tag.Negatable != "" {
|
||||||
|
negFlag := negatableFlagName(value.Name, tag.Negatable)
|
||||||
|
if seenFlags[negFlag] {
|
||||||
|
return failField(v, ft, "duplicate negation flag %s", negFlag)
|
||||||
|
}
|
||||||
|
seenFlags[negFlag] = true
|
||||||
|
}
|
||||||
flag := &Flag{
|
flag := &Flag{
|
||||||
Value: value,
|
Value: value,
|
||||||
Aliases: tag.Aliases,
|
Aliases: tag.Aliases,
|
||||||
|
@ -317,6 +334,7 @@ func buildField(k *Kong, node *Node, v reflect.Value, ft reflect.StructField, fv
|
||||||
Envs: tag.Envs,
|
Envs: tag.Envs,
|
||||||
Group: buildGroupForKey(k, tag.Group),
|
Group: buildGroupForKey(k, tag.Group),
|
||||||
Xor: tag.Xor,
|
Xor: tag.Xor,
|
||||||
|
And: tag.And,
|
||||||
Hidden: tag.Hidden,
|
Hidden: tag.Hidden,
|
||||||
}
|
}
|
||||||
value.Flag = flag
|
value.Flag = flag
|
||||||
|
|
63
vendor/github.com/alecthomas/kong/callbacks.go
generated
vendored
63
vendor/github.com/alecthomas/kong/callbacks.go
generated
vendored
|
@ -6,7 +6,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type bindings map[reflect.Type]func() (reflect.Value, error)
|
// A map of type to function that returns a value of that type.
|
||||||
|
//
|
||||||
|
// The function should have the signature func(...) (T, error). Arguments are recursively resolved.
|
||||||
|
type bindings map[reflect.Type]any
|
||||||
|
|
||||||
func (b bindings) String() string {
|
func (b bindings) String() string {
|
||||||
out := []string{}
|
out := []string{}
|
||||||
|
@ -19,32 +22,23 @@ func (b bindings) String() string {
|
||||||
func (b bindings) add(values ...interface{}) bindings {
|
func (b bindings) add(values ...interface{}) bindings {
|
||||||
for _, v := range values {
|
for _, v := range values {
|
||||||
v := v
|
v := v
|
||||||
b[reflect.TypeOf(v)] = func() (reflect.Value, error) { return reflect.ValueOf(v), nil }
|
b[reflect.TypeOf(v)] = func() (any, error) { return v, nil }
|
||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b bindings) addTo(impl, iface interface{}) {
|
func (b bindings) addTo(impl, iface interface{}) {
|
||||||
valueOf := reflect.ValueOf(impl)
|
b[reflect.TypeOf(iface).Elem()] = func() (any, error) { return impl, nil }
|
||||||
b[reflect.TypeOf(iface).Elem()] = func() (reflect.Value, error) { return valueOf, nil }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b bindings) addProvider(provider interface{}) error {
|
func (b bindings) addProvider(provider interface{}) error {
|
||||||
pv := reflect.ValueOf(provider)
|
pv := reflect.ValueOf(provider)
|
||||||
t := pv.Type()
|
t := pv.Type()
|
||||||
if t.Kind() != reflect.Func || t.NumIn() != 0 || t.NumOut() != 2 || t.Out(1) != reflect.TypeOf((*error)(nil)).Elem() {
|
if t.Kind() != reflect.Func || t.NumOut() != 2 || t.Out(1) != reflect.TypeOf((*error)(nil)).Elem() {
|
||||||
return fmt.Errorf("%T must be a function with the signature func()(T, error)", provider)
|
return fmt.Errorf("%T must be a function with the signature func(...)(T, error)", provider)
|
||||||
}
|
}
|
||||||
rt := pv.Type().Out(0)
|
rt := pv.Type().Out(0)
|
||||||
b[rt] = func() (reflect.Value, error) {
|
b[rt] = provider
|
||||||
out := pv.Call(nil)
|
|
||||||
errv := out[1]
|
|
||||||
var err error
|
|
||||||
if !errv.IsNil() {
|
|
||||||
err = errv.Interface().(error) //nolint
|
|
||||||
}
|
|
||||||
return out[0], err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,28 +72,19 @@ func callFunction(f reflect.Value, bindings bindings) error {
|
||||||
if f.Kind() != reflect.Func {
|
if f.Kind() != reflect.Func {
|
||||||
return fmt.Errorf("expected function, got %s", f.Type())
|
return fmt.Errorf("expected function, got %s", f.Type())
|
||||||
}
|
}
|
||||||
in := []reflect.Value{}
|
|
||||||
t := f.Type()
|
t := f.Type()
|
||||||
if t.NumOut() != 1 || !t.Out(0).Implements(callbackReturnSignature) {
|
if t.NumOut() != 1 || !t.Out(0).Implements(callbackReturnSignature) {
|
||||||
return fmt.Errorf("return value of %s must implement \"error\"", t)
|
return fmt.Errorf("return value of %s must implement \"error\"", t)
|
||||||
}
|
}
|
||||||
for i := 0; i < t.NumIn(); i++ {
|
out, err := callAnyFunction(f, bindings)
|
||||||
pt := t.In(i)
|
if err != nil {
|
||||||
if argf, ok := bindings[pt]; ok {
|
return err
|
||||||
argv, err := argf()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
in = append(in, argv)
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("couldn't find binding of type %s for parameter %d of %s(), use kong.Bind(%s)", pt, i, t, pt)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out := f.Call(in)
|
ferr := out[0]
|
||||||
if out[0].IsNil() {
|
if ferrv := reflect.ValueOf(ferr); !ferrv.IsValid() || ((ferrv.Kind() == reflect.Interface || ferrv.Kind() == reflect.Pointer) && ferrv.IsNil()) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return out[0].Interface().(error) //nolint
|
return ferr.(error) //nolint:forcetypeassert
|
||||||
}
|
}
|
||||||
|
|
||||||
func callAnyFunction(f reflect.Value, bindings bindings) (out []any, err error) {
|
func callAnyFunction(f reflect.Value, bindings bindings) (out []any, err error) {
|
||||||
|
@ -110,15 +95,19 @@ func callAnyFunction(f reflect.Value, bindings bindings) (out []any, err error)
|
||||||
t := f.Type()
|
t := f.Type()
|
||||||
for i := 0; i < t.NumIn(); i++ {
|
for i := 0; i < t.NumIn(); i++ {
|
||||||
pt := t.In(i)
|
pt := t.In(i)
|
||||||
if argf, ok := bindings[pt]; ok {
|
argf, ok := bindings[pt]
|
||||||
argv, err := argf()
|
if !ok {
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
in = append(in, argv)
|
|
||||||
} else {
|
|
||||||
return nil, fmt.Errorf("couldn't find binding of type %s for parameter %d of %s(), use kong.Bind(%s)", pt, i, t, pt)
|
return nil, fmt.Errorf("couldn't find binding of type %s for parameter %d of %s(), use kong.Bind(%s)", pt, i, t, pt)
|
||||||
}
|
}
|
||||||
|
// Recursively resolve binding functions.
|
||||||
|
argv, err := callAnyFunction(reflect.ValueOf(argf), bindings)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("%s: %w", pt, err)
|
||||||
|
}
|
||||||
|
if ferrv := reflect.ValueOf(argv[len(argv)-1]); ferrv.IsValid() && !ferrv.IsNil() {
|
||||||
|
return nil, ferrv.Interface().(error) //nolint:forcetypeassert
|
||||||
|
}
|
||||||
|
in = append(in, reflect.ValueOf(argv[0]))
|
||||||
}
|
}
|
||||||
outv := f.Call(in)
|
outv := f.Call(in)
|
||||||
out = make([]any, len(outv))
|
out = make([]any, len(outv))
|
||||||
|
|
176
vendor/github.com/alecthomas/kong/context.go
generated
vendored
176
vendor/github.com/alecthomas/kong/context.go
generated
vendored
|
@ -208,7 +208,7 @@ func (c *Context) Validate() error { //nolint: gocyclo
|
||||||
desc = node.Path()
|
desc = node.Path()
|
||||||
}
|
}
|
||||||
if validate := isValidatable(value); validate != nil {
|
if validate := isValidatable(value); validate != nil {
|
||||||
if err := validate.Validate(); err != nil {
|
if err := validate.Validate(c); err != nil {
|
||||||
if desc != "" {
|
if desc != "" {
|
||||||
return fmt.Errorf("%s: %w", desc, err)
|
return fmt.Errorf("%s: %w", desc, err)
|
||||||
}
|
}
|
||||||
|
@ -259,7 +259,7 @@ func (c *Context) Validate() error { //nolint: gocyclo
|
||||||
if err := checkMissingPositionals(positionals, node.Positional); err != nil {
|
if err := checkMissingPositionals(positionals, node.Positional); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := checkXorDuplicates(c.Path); err != nil {
|
if err := checkXorDuplicatedAndAndMissing(c.Path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,6 +347,7 @@ func (c *Context) endParsing() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:maintidx
|
||||||
func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
|
func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
|
||||||
positional := 0
|
positional := 0
|
||||||
node.Active = true
|
node.Active = true
|
||||||
|
@ -383,9 +384,13 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
|
||||||
|
|
||||||
// Indicates end of parsing. All remaining arguments are treated as positional arguments only.
|
// Indicates end of parsing. All remaining arguments are treated as positional arguments only.
|
||||||
case v == "--":
|
case v == "--":
|
||||||
c.scan.Pop()
|
|
||||||
c.endParsing()
|
c.endParsing()
|
||||||
|
|
||||||
|
// Pop the -- token unless the next positional argument accepts passthrough arguments.
|
||||||
|
if !(positional < len(node.Positional) && node.Positional[positional].Passthrough) {
|
||||||
|
c.scan.Pop()
|
||||||
|
}
|
||||||
|
|
||||||
// Long flag.
|
// Long flag.
|
||||||
case strings.HasPrefix(v, "--"):
|
case strings.HasPrefix(v, "--"):
|
||||||
c.scan.Pop()
|
c.scan.Pop()
|
||||||
|
@ -420,12 +425,22 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
|
||||||
|
|
||||||
case FlagToken:
|
case FlagToken:
|
||||||
if err := c.parseFlag(flags, token.String()); err != nil {
|
if err := c.parseFlag(flags, token.String()); err != nil {
|
||||||
return err
|
if isUnknownFlagError(err) && positional < len(node.Positional) && node.Positional[positional].PassthroughMode == PassThroughModeAll {
|
||||||
|
c.scan.Pop()
|
||||||
|
c.scan.PushTyped(token.String(), PositionalArgumentToken)
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case ShortFlagToken:
|
case ShortFlagToken:
|
||||||
if err := c.parseFlag(flags, token.String()); err != nil {
|
if err := c.parseFlag(flags, token.String()); err != nil {
|
||||||
return err
|
if isUnknownFlagError(err) && positional < len(node.Positional) && node.Positional[positional].PassthroughMode == PassThroughModeAll {
|
||||||
|
c.scan.Pop()
|
||||||
|
c.scan.PushTyped(token.String(), PositionalArgumentToken)
|
||||||
|
} else {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
case FlagValueToken:
|
case FlagValueToken:
|
||||||
|
@ -700,13 +715,13 @@ func (c *Context) parseFlag(flags []*Flag, match string) (err error) {
|
||||||
candidates = append(candidates, alias)
|
candidates = append(candidates, alias)
|
||||||
}
|
}
|
||||||
|
|
||||||
neg := "--no-" + flag.Name
|
neg := negatableFlagName(flag.Name, flag.Tag.Negatable)
|
||||||
if !matched && !(match == neg && flag.Tag.Negatable) {
|
if !matched && match != neg {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// Found a matching flag.
|
// Found a matching flag.
|
||||||
c.scan.Pop()
|
c.scan.Pop()
|
||||||
if match == neg && flag.Tag.Negatable {
|
if match == neg && flag.Tag.Negatable != "" {
|
||||||
flag.Negated = true
|
flag.Negated = true
|
||||||
}
|
}
|
||||||
err := flag.Parse(c.scan, c.getValue(flag.Value))
|
err := flag.Parse(c.scan, c.getValue(flag.Value))
|
||||||
|
@ -728,13 +743,23 @@ func (c *Context) parseFlag(flags []*Flag, match string) (err error) {
|
||||||
c.Path = append(c.Path, &Path{Flag: flag})
|
c.Path = append(c.Path, &Path{Flag: flag})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return findPotentialCandidates(match, candidates, "unknown flag %s", match)
|
return &unknownFlagError{Cause: findPotentialCandidates(match, candidates, "unknown flag %s", match)}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isUnknownFlagError(err error) bool {
|
||||||
|
var unknown *unknownFlagError
|
||||||
|
return errors.As(err, &unknown)
|
||||||
|
}
|
||||||
|
|
||||||
|
type unknownFlagError struct{ Cause error }
|
||||||
|
|
||||||
|
func (e *unknownFlagError) Unwrap() error { return e.Cause }
|
||||||
|
func (e *unknownFlagError) Error() string { return e.Cause.Error() }
|
||||||
|
|
||||||
// Call an arbitrary function filling arguments with bound values.
|
// Call an arbitrary function filling arguments with bound values.
|
||||||
func (c *Context) Call(fn any, binds ...interface{}) (out []interface{}, err error) {
|
func (c *Context) Call(fn any, binds ...interface{}) (out []interface{}, err error) {
|
||||||
fv := reflect.ValueOf(fn)
|
fv := reflect.ValueOf(fn)
|
||||||
bindings := c.Kong.bindings.clone().add(binds...).add(c).merge(c.bindings) //nolint:govet
|
bindings := c.Kong.bindings.clone().add(binds...).add(c).merge(c.bindings)
|
||||||
return callAnyFunction(fv, bindings)
|
return callAnyFunction(fv, bindings)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -757,6 +782,19 @@ func (c *Context) RunNode(node *Node, binds ...interface{}) (err error) {
|
||||||
methodBinds = methodBinds.clone()
|
methodBinds = methodBinds.clone()
|
||||||
for p := node; p != nil; p = p.Parent {
|
for p := node; p != nil; p = p.Parent {
|
||||||
methodBinds = methodBinds.add(p.Target.Addr().Interface())
|
methodBinds = methodBinds.add(p.Target.Addr().Interface())
|
||||||
|
// Try value and pointer to value.
|
||||||
|
for _, p := range []reflect.Value{p.Target, p.Target.Addr()} {
|
||||||
|
t := p.Type()
|
||||||
|
for i := 0; i < p.NumMethod(); i++ {
|
||||||
|
methodt := t.Method(i)
|
||||||
|
if strings.HasPrefix(methodt.Name, "Provide") {
|
||||||
|
method := p.Method(i)
|
||||||
|
if err := methodBinds.addProvider(method.Interface()); err != nil {
|
||||||
|
return fmt.Errorf("%s.%s: %w", t.Name(), methodt.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if method.IsValid() {
|
if method.IsValid() {
|
||||||
methods = append(methods, targetMethod{node, method, methodBinds})
|
methods = append(methods, targetMethod{node, method, methodBinds})
|
||||||
|
@ -785,18 +823,22 @@ func (c *Context) RunNode(node *Node, binds ...interface{}) (err error) {
|
||||||
func (c *Context) Run(binds ...interface{}) (err error) {
|
func (c *Context) Run(binds ...interface{}) (err error) {
|
||||||
node := c.Selected()
|
node := c.Selected()
|
||||||
if node == nil {
|
if node == nil {
|
||||||
if len(c.Path) > 0 {
|
if len(c.Path) == 0 {
|
||||||
selected := c.Path[0].Node()
|
return fmt.Errorf("no command selected")
|
||||||
if selected.Type == ApplicationNode {
|
}
|
||||||
method := getMethod(selected.Target, "Run")
|
selected := c.Path[0].Node()
|
||||||
if method.IsValid() {
|
if selected.Type == ApplicationNode {
|
||||||
return c.RunNode(selected, binds...)
|
method := getMethod(selected.Target, "Run")
|
||||||
}
|
if method.IsValid() {
|
||||||
}
|
node = selected
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("no command selected")
|
||||||
}
|
}
|
||||||
return fmt.Errorf("no command selected")
|
|
||||||
}
|
}
|
||||||
return c.RunNode(node, binds...)
|
runErr := c.RunNode(node, binds...)
|
||||||
|
err = c.Kong.applyHook(c, "AfterRun")
|
||||||
|
return errors.Join(runErr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrintUsage to Kong's stdout.
|
// PrintUsage to Kong's stdout.
|
||||||
|
@ -811,23 +853,35 @@ func (c *Context) PrintUsage(summary bool) error {
|
||||||
func checkMissingFlags(flags []*Flag) error {
|
func checkMissingFlags(flags []*Flag) error {
|
||||||
xorGroupSet := map[string]bool{}
|
xorGroupSet := map[string]bool{}
|
||||||
xorGroup := map[string][]string{}
|
xorGroup := map[string][]string{}
|
||||||
|
andGroupSet := map[string]bool{}
|
||||||
|
andGroup := map[string][]string{}
|
||||||
missing := []string{}
|
missing := []string{}
|
||||||
|
andGroupRequired := getRequiredAndGroupMap(flags)
|
||||||
for _, flag := range flags {
|
for _, flag := range flags {
|
||||||
|
for _, and := range flag.And {
|
||||||
|
flag.Required = andGroupRequired[and]
|
||||||
|
}
|
||||||
if flag.Set {
|
if flag.Set {
|
||||||
for _, xor := range flag.Xor {
|
for _, xor := range flag.Xor {
|
||||||
xorGroupSet[xor] = true
|
xorGroupSet[xor] = true
|
||||||
}
|
}
|
||||||
|
for _, and := range flag.And {
|
||||||
|
andGroupSet[and] = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if !flag.Required || flag.Set {
|
if !flag.Required || flag.Set {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if len(flag.Xor) > 0 {
|
if len(flag.Xor) > 0 || len(flag.And) > 0 {
|
||||||
for _, xor := range flag.Xor {
|
for _, xor := range flag.Xor {
|
||||||
if xorGroupSet[xor] {
|
if xorGroupSet[xor] {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
xorGroup[xor] = append(xorGroup[xor], flag.Summary())
|
xorGroup[xor] = append(xorGroup[xor], flag.Summary())
|
||||||
}
|
}
|
||||||
|
for _, and := range flag.And {
|
||||||
|
andGroup[and] = append(andGroup[and], flag.Summary())
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
missing = append(missing, flag.Summary())
|
missing = append(missing, flag.Summary())
|
||||||
}
|
}
|
||||||
|
@ -837,6 +891,11 @@ func checkMissingFlags(flags []*Flag) error {
|
||||||
missing = append(missing, strings.Join(flags, " or "))
|
missing = append(missing, strings.Join(flags, " or "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for _, flags := range andGroup {
|
||||||
|
if len(flags) > 1 {
|
||||||
|
missing = append(missing, strings.Join(flags, " and "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(missing) == 0 {
|
if len(missing) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
@ -847,6 +906,18 @@ func checkMissingFlags(flags []*Flag) error {
|
||||||
return fmt.Errorf("missing flags: %s", strings.Join(missing, ", "))
|
return fmt.Errorf("missing flags: %s", strings.Join(missing, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getRequiredAndGroupMap(flags []*Flag) map[string]bool {
|
||||||
|
andGroupRequired := map[string]bool{}
|
||||||
|
for _, flag := range flags {
|
||||||
|
for _, and := range flag.And {
|
||||||
|
if flag.Required {
|
||||||
|
andGroupRequired[and] = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return andGroupRequired
|
||||||
|
}
|
||||||
|
|
||||||
func checkMissingChildren(node *Node) error {
|
func checkMissingChildren(node *Node) error {
|
||||||
missing := []string{}
|
missing := []string{}
|
||||||
|
|
||||||
|
@ -883,7 +954,7 @@ func checkMissingChildren(node *Node) error {
|
||||||
if len(missing) == 1 {
|
if len(missing) == 1 {
|
||||||
return fmt.Errorf("expected %s", missing[0])
|
return fmt.Errorf("expected %s", missing[0])
|
||||||
}
|
}
|
||||||
return fmt.Errorf("expected one of %s", strings.Join(missing, ", "))
|
return fmt.Errorf("expected one of %s", strings.Join(missing, ", "))
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we're missing any positionals and they're required, return an error.
|
// If we're missing any positionals and they're required, return an error.
|
||||||
|
@ -943,7 +1014,7 @@ func checkEnum(value *Value, target reflect.Value) error {
|
||||||
}
|
}
|
||||||
enums = append(enums, fmt.Sprintf("%q", enum))
|
enums = append(enums, fmt.Sprintf("%q", enum))
|
||||||
}
|
}
|
||||||
return fmt.Errorf("%s must be one of %s but got %q", value.ShortSummary(), strings.Join(enums, ","), target.Interface())
|
return fmt.Errorf("%s must be one of %s but got %q", value.ShortSummary(), strings.Join(enums, ","), fmt.Sprintf("%v", target.Interface()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -957,6 +1028,20 @@ func checkPassthroughArg(target reflect.Value) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkXorDuplicatedAndAndMissing(paths []*Path) error {
|
||||||
|
errs := []string{}
|
||||||
|
if err := checkXorDuplicates(paths); err != nil {
|
||||||
|
errs = append(errs, err.Error())
|
||||||
|
}
|
||||||
|
if err := checkAndMissing(paths); err != nil {
|
||||||
|
errs = append(errs, err.Error())
|
||||||
|
}
|
||||||
|
if len(errs) > 0 {
|
||||||
|
return errors.New(strings.Join(errs, ", "))
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func checkXorDuplicates(paths []*Path) error {
|
func checkXorDuplicates(paths []*Path) error {
|
||||||
for _, path := range paths {
|
for _, path := range paths {
|
||||||
seen := map[string]*Flag{}
|
seen := map[string]*Flag{}
|
||||||
|
@ -975,6 +1060,38 @@ func checkXorDuplicates(paths []*Path) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkAndMissing(paths []*Path) error {
|
||||||
|
for _, path := range paths {
|
||||||
|
missingMsgs := []string{}
|
||||||
|
andGroups := map[string][]*Flag{}
|
||||||
|
for _, flag := range path.Flags {
|
||||||
|
for _, and := range flag.And {
|
||||||
|
andGroups[and] = append(andGroups[and], flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, flags := range andGroups {
|
||||||
|
oneSet := false
|
||||||
|
notSet := []*Flag{}
|
||||||
|
flagNames := []string{}
|
||||||
|
for _, flag := range flags {
|
||||||
|
flagNames = append(flagNames, flag.Name)
|
||||||
|
if flag.Set {
|
||||||
|
oneSet = true
|
||||||
|
} else {
|
||||||
|
notSet = append(notSet, flag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(notSet) > 0 && oneSet {
|
||||||
|
missingMsgs = append(missingMsgs, fmt.Sprintf("--%s must be used together", strings.Join(flagNames, " and --")))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(missingMsgs) > 0 {
|
||||||
|
return fmt.Errorf("%s", strings.Join(missingMsgs, ", "))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func findPotentialCandidates(needle string, haystack []string, format string, args ...interface{}) error {
|
func findPotentialCandidates(needle string, haystack []string, format string, args ...interface{}) error {
|
||||||
if len(haystack) == 0 {
|
if len(haystack) == 0 {
|
||||||
return fmt.Errorf(format, args...)
|
return fmt.Errorf(format, args...)
|
||||||
|
@ -995,12 +1112,23 @@ func findPotentialCandidates(needle string, haystack []string, format string, ar
|
||||||
}
|
}
|
||||||
|
|
||||||
type validatable interface{ Validate() error }
|
type validatable interface{ Validate() error }
|
||||||
|
type extendedValidatable interface {
|
||||||
|
Validate(kctx *Context) error
|
||||||
|
}
|
||||||
|
|
||||||
func isValidatable(v reflect.Value) validatable {
|
// Proxy a validatable function to the extendedValidatable interface
|
||||||
|
type validatableFunc func() error
|
||||||
|
|
||||||
|
func (f validatableFunc) Validate(kctx *Context) error { return f() }
|
||||||
|
|
||||||
|
func isValidatable(v reflect.Value) extendedValidatable {
|
||||||
if !v.IsValid() || (v.Kind() == reflect.Ptr || v.Kind() == reflect.Slice || v.Kind() == reflect.Map) && v.IsNil() {
|
if !v.IsValid() || (v.Kind() == reflect.Ptr || v.Kind() == reflect.Slice || v.Kind() == reflect.Map) && v.IsNil() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if validate, ok := v.Interface().(validatable); ok {
|
if validate, ok := v.Interface().(validatable); ok {
|
||||||
|
return validatableFunc(validate.Validate)
|
||||||
|
}
|
||||||
|
if validate, ok := v.Interface().(extendedValidatable); ok {
|
||||||
return validate
|
return validate
|
||||||
}
|
}
|
||||||
if v.CanAddr() {
|
if v.CanAddr() {
|
||||||
|
|
33
vendor/github.com/alecthomas/kong/help.go
generated
vendored
33
vendor/github.com/alecthomas/kong/help.go
generated
vendored
|
@ -491,27 +491,22 @@ func formatFlag(haveShort bool, flag *Flag) string {
|
||||||
name := flag.Name
|
name := flag.Name
|
||||||
isBool := flag.IsBool()
|
isBool := flag.IsBool()
|
||||||
isCounter := flag.IsCounter()
|
isCounter := flag.IsCounter()
|
||||||
|
|
||||||
|
short := ""
|
||||||
if flag.Short != 0 {
|
if flag.Short != 0 {
|
||||||
if isBool && flag.Tag.Negatable {
|
short = "-" + string(flag.Short) + ", "
|
||||||
flagString += fmt.Sprintf("-%c, --[no-]%s", flag.Short, name)
|
} else if haveShort {
|
||||||
} else {
|
short = " "
|
||||||
flagString += fmt.Sprintf("-%c, --%s", flag.Short, name)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if isBool && flag.Tag.Negatable {
|
|
||||||
if haveShort {
|
|
||||||
flagString = fmt.Sprintf(" --[no-]%s", name)
|
|
||||||
} else {
|
|
||||||
flagString = fmt.Sprintf("--[no-]%s", name)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if haveShort {
|
|
||||||
flagString += fmt.Sprintf(" --%s", name)
|
|
||||||
} else {
|
|
||||||
flagString += fmt.Sprintf("--%s", name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if isBool && flag.Tag.Negatable == negatableDefault {
|
||||||
|
name = "[no-]" + name
|
||||||
|
} else if isBool && flag.Tag.Negatable != "" {
|
||||||
|
name += "/" + flag.Tag.Negatable
|
||||||
|
}
|
||||||
|
|
||||||
|
flagString += fmt.Sprintf("%s--%s", short, name)
|
||||||
|
|
||||||
if !isBool && !isCounter {
|
if !isBool && !isCounter {
|
||||||
flagString += fmt.Sprintf("=%s", flag.FormatPlaceHolder())
|
flagString += fmt.Sprintf("=%s", flag.FormatPlaceHolder())
|
||||||
}
|
}
|
||||||
|
|
13
vendor/github.com/alecthomas/kong/hooks.go
generated
vendored
13
vendor/github.com/alecthomas/kong/hooks.go
generated
vendored
|
@ -3,17 +3,24 @@ package kong
|
||||||
// BeforeResolve is a documentation-only interface describing hooks that run before resolvers are applied.
|
// BeforeResolve is a documentation-only interface describing hooks that run before resolvers are applied.
|
||||||
type BeforeResolve interface {
|
type BeforeResolve interface {
|
||||||
// This is not the correct signature - see README for details.
|
// This is not the correct signature - see README for details.
|
||||||
BeforeResolve(args ...interface{}) error
|
BeforeResolve(args ...any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeforeApply is a documentation-only interface describing hooks that run before values are set.
|
// BeforeApply is a documentation-only interface describing hooks that run before values are set.
|
||||||
type BeforeApply interface {
|
type BeforeApply interface {
|
||||||
// This is not the correct signature - see README for details.
|
// This is not the correct signature - see README for details.
|
||||||
BeforeApply(args ...interface{}) error
|
BeforeApply(args ...any) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// AfterApply is a documentation-only interface describing hooks that run after values are set.
|
// AfterApply is a documentation-only interface describing hooks that run after values are set.
|
||||||
type AfterApply interface {
|
type AfterApply interface {
|
||||||
// This is not the correct signature - see README for details.
|
// This is not the correct signature - see README for details.
|
||||||
AfterApply(args ...interface{}) error
|
AfterApply(args ...any) error
|
||||||
|
}
|
||||||
|
|
||||||
|
// AfterRun is a documentation-only interface describing hooks that run after Run() returns.
|
||||||
|
type AfterRun interface {
|
||||||
|
// This is not the correct signature - see README for details.
|
||||||
|
// AfterRun is called after Run() returns.
|
||||||
|
AfterRun(args ...any) error
|
||||||
}
|
}
|
||||||
|
|
47
vendor/github.com/alecthomas/kong/kong.go
generated
vendored
47
vendor/github.com/alecthomas/kong/kong.go
generated
vendored
|
@ -117,7 +117,7 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
|
||||||
|
|
||||||
// Embed any embedded structs.
|
// Embed any embedded structs.
|
||||||
for _, embed := range k.embedded {
|
for _, embed := range k.embedded {
|
||||||
tag, err := parseTagString(strings.Join(embed.tags, " ")) //nolint:govet
|
tag, err := parseTagString(strings.Join(embed.tags, " "))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -167,9 +167,42 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
|
||||||
|
|
||||||
k.bindings.add(k.vars)
|
k.bindings.add(k.vars)
|
||||||
|
|
||||||
|
if err = checkOverlappingXorAnd(k); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return k, nil
|
return k, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func checkOverlappingXorAnd(k *Kong) error {
|
||||||
|
xorGroups := map[string][]string{}
|
||||||
|
andGroups := map[string][]string{}
|
||||||
|
for _, flag := range k.Model.Node.Flags {
|
||||||
|
for _, xor := range flag.Xor {
|
||||||
|
xorGroups[xor] = append(xorGroups[xor], flag.Name)
|
||||||
|
}
|
||||||
|
for _, and := range flag.And {
|
||||||
|
andGroups[and] = append(andGroups[and], flag.Name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for xor, xorSet := range xorGroups {
|
||||||
|
for and, andSet := range andGroups {
|
||||||
|
overlappingEntries := []string{}
|
||||||
|
for _, xorTag := range xorSet {
|
||||||
|
for _, andTag := range andSet {
|
||||||
|
if xorTag == andTag {
|
||||||
|
overlappingEntries = append(overlappingEntries, xorTag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if len(overlappingEntries) > 1 {
|
||||||
|
return fmt.Errorf("invalid xor and combination, %s and %s overlap with more than one: %s", xor, and, overlappingEntries)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
type varStack []Vars
|
type varStack []Vars
|
||||||
|
|
||||||
func (v *varStack) head() Vars { return (*v)[len(*v)-1] }
|
func (v *varStack) head() Vars { return (*v)[len(*v)-1] }
|
||||||
|
@ -216,19 +249,19 @@ func (k *Kong) interpolateValue(value *Value, vars Vars) (err error) {
|
||||||
return fmt.Errorf("enum for %s: %s", value.Summary(), err)
|
return fmt.Errorf("enum for %s: %s", value.Summary(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedVars := map[string]string{
|
|
||||||
"default": value.Default,
|
|
||||||
"enum": value.Enum,
|
|
||||||
}
|
|
||||||
if value.Default, err = interpolate(value.Default, vars, nil); err != nil {
|
if value.Default, err = interpolate(value.Default, vars, nil); err != nil {
|
||||||
return fmt.Errorf("default value for %s: %s", value.Summary(), err)
|
return fmt.Errorf("default value for %s: %s", value.Summary(), err)
|
||||||
}
|
}
|
||||||
if value.Enum, err = interpolate(value.Enum, vars, nil); err != nil {
|
if value.Enum, err = interpolate(value.Enum, vars, nil); err != nil {
|
||||||
return fmt.Errorf("enum value for %s: %s", value.Summary(), err)
|
return fmt.Errorf("enum value for %s: %s", value.Summary(), err)
|
||||||
}
|
}
|
||||||
|
updatedVars := map[string]string{
|
||||||
|
"default": value.Default,
|
||||||
|
"enum": value.Enum,
|
||||||
|
}
|
||||||
if value.Flag != nil {
|
if value.Flag != nil {
|
||||||
for i, env := range value.Flag.Envs {
|
for i, env := range value.Flag.Envs {
|
||||||
if value.Flag.Envs[i], err = interpolate(env, vars, nil); err != nil {
|
if value.Flag.Envs[i], err = interpolate(env, vars, updatedVars); err != nil {
|
||||||
return fmt.Errorf("env value for %s: %s", value.Summary(), err)
|
return fmt.Errorf("env value for %s: %s", value.Summary(), err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -373,7 +406,7 @@ func (k *Kong) applyHookToDefaultFlags(ctx *Context, node *Node, name string) er
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatMultilineMessage(w io.Writer, leaders []string, format string, args ...interface{}) {
|
func formatMultilineMessage(w io.Writer, leaders []string, format string, args ...interface{}) {
|
||||||
lines := strings.Split(fmt.Sprintf(format, args...), "\n")
|
lines := strings.Split(strings.TrimRight(fmt.Sprintf(format, args...), "\n"), "\n")
|
||||||
leader := ""
|
leader := ""
|
||||||
for _, l := range leaders {
|
for _, l := range leaders {
|
||||||
if l == "" {
|
if l == "" {
|
||||||
|
|
2
vendor/github.com/alecthomas/kong/levenshtein.go
generated
vendored
2
vendor/github.com/alecthomas/kong/levenshtein.go
generated
vendored
|
@ -31,7 +31,7 @@ func levenshtein(a, b string) int {
|
||||||
return f[len(f)-1]
|
return f[len(f)-1]
|
||||||
}
|
}
|
||||||
|
|
||||||
func min(a, b int) int {
|
func min(a, b int) int { //nolint:predeclared
|
||||||
if a <= b {
|
if a <= b {
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
36
vendor/github.com/alecthomas/kong/model.go
generated
vendored
36
vendor/github.com/alecthomas/kong/model.go
generated
vendored
|
@ -239,23 +239,24 @@ func (n *Node) ClosestGroup() *Group {
|
||||||
|
|
||||||
// A Value is either a flag or a variable positional argument.
|
// A Value is either a flag or a variable positional argument.
|
||||||
type Value struct {
|
type Value struct {
|
||||||
Flag *Flag // Nil if positional argument.
|
Flag *Flag // Nil if positional argument.
|
||||||
Name string
|
Name string
|
||||||
Help string
|
Help string
|
||||||
OrigHelp string // Original help string, without interpolated variables.
|
OrigHelp string // Original help string, without interpolated variables.
|
||||||
HasDefault bool
|
HasDefault bool
|
||||||
Default string
|
Default string
|
||||||
DefaultValue reflect.Value
|
DefaultValue reflect.Value
|
||||||
Enum string
|
Enum string
|
||||||
Mapper Mapper
|
Mapper Mapper
|
||||||
Tag *Tag
|
Tag *Tag
|
||||||
Target reflect.Value
|
Target reflect.Value
|
||||||
Required bool
|
Required bool
|
||||||
Set bool // Set to true when this value is set through some mechanism.
|
Set bool // Set to true when this value is set through some mechanism.
|
||||||
Format string // Formatting directive, if applicable.
|
Format string // Formatting directive, if applicable.
|
||||||
Position int // Position (for positional arguments).
|
Position int // Position (for positional arguments).
|
||||||
Passthrough bool // Set to true to stop flag parsing when encountered.
|
Passthrough bool // Deprecated: Use PassthroughMode instead. Set to true to stop flag parsing when encountered.
|
||||||
Active bool // Denotes the value is part of an active branch in the CLI.
|
PassthroughMode PassthroughMode //
|
||||||
|
Active bool // Denotes the value is part of an active branch in the CLI.
|
||||||
}
|
}
|
||||||
|
|
||||||
// EnumMap returns a map of the enums in this value.
|
// EnumMap returns a map of the enums in this value.
|
||||||
|
@ -405,6 +406,7 @@ type Flag struct {
|
||||||
*Value
|
*Value
|
||||||
Group *Group // Logical grouping when displaying. May also be used by configuration loaders to group options logically.
|
Group *Group // Logical grouping when displaying. May also be used by configuration loaders to group options logically.
|
||||||
Xor []string
|
Xor []string
|
||||||
|
And []string
|
||||||
PlaceHolder string
|
PlaceHolder string
|
||||||
Envs []string
|
Envs []string
|
||||||
Aliases []string
|
Aliases []string
|
||||||
|
|
19
vendor/github.com/alecthomas/kong/negatable.go
generated
vendored
Normal file
19
vendor/github.com/alecthomas/kong/negatable.go
generated
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
package kong
|
||||||
|
|
||||||
|
// negatableDefault is a placeholder value for the Negatable tag to indicate
|
||||||
|
// the negated flag is --no-<flag-name>. This is needed as at the time of
|
||||||
|
// parsing a tag, the field's flag name is not yet known.
|
||||||
|
const negatableDefault = "_"
|
||||||
|
|
||||||
|
// negatableFlagName returns the name of the flag for a negatable field, or
|
||||||
|
// an empty string if the field is not negatable.
|
||||||
|
func negatableFlagName(name, negation string) string {
|
||||||
|
switch negation {
|
||||||
|
case "":
|
||||||
|
return ""
|
||||||
|
case negatableDefault:
|
||||||
|
return "--no-" + name
|
||||||
|
default:
|
||||||
|
return "--" + negation
|
||||||
|
}
|
||||||
|
}
|
10
vendor/github.com/alecthomas/kong/options.go
generated
vendored
10
vendor/github.com/alecthomas/kong/options.go
generated
vendored
|
@ -89,6 +89,10 @@ type dynamicCommand struct {
|
||||||
// "tags" is a list of extra tag strings to parse, in the form <key>:"<value>".
|
// "tags" is a list of extra tag strings to parse, in the form <key>:"<value>".
|
||||||
func DynamicCommand(name, help, group string, cmd interface{}, tags ...string) Option {
|
func DynamicCommand(name, help, group string, cmd interface{}, tags ...string) Option {
|
||||||
return OptionFunc(func(k *Kong) error {
|
return OptionFunc(func(k *Kong) error {
|
||||||
|
if run := getMethod(reflect.Indirect(reflect.ValueOf(cmd)), "Run"); !run.IsValid() {
|
||||||
|
return fmt.Errorf("kong: DynamicCommand %q must be a type with a 'Run' method; got %T", name, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
k.dynamicCommands = append(k.dynamicCommands, &dynamicCommand{
|
k.dynamicCommands = append(k.dynamicCommands, &dynamicCommand{
|
||||||
name: name,
|
name: name,
|
||||||
help: help,
|
help: help,
|
||||||
|
@ -204,7 +208,11 @@ func BindTo(impl, iface interface{}) Option {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BindToProvider allows binding of provider functions.
|
// BindToProvider binds an injected value to a provider function.
|
||||||
|
//
|
||||||
|
// The provider function must have the signature:
|
||||||
|
//
|
||||||
|
// func() (interface{}, error)
|
||||||
//
|
//
|
||||||
// This is useful when the Run() function of different commands require different values that may
|
// This is useful when the Run() function of different commands require different values that may
|
||||||
// not all be initialisable from the main() function.
|
// not all be initialisable from the main() function.
|
||||||
|
|
2
vendor/github.com/alecthomas/kong/resolver.go
generated
vendored
2
vendor/github.com/alecthomas/kong/resolver.go
generated
vendored
|
@ -63,6 +63,6 @@ func JSON(r io.Reader) (Resolver, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func snakeCase(name string) string {
|
func snakeCase(name string) string {
|
||||||
name = strings.Join(strings.Split(strings.Title(name), "-"), "") //nolint: staticcheck
|
name = strings.Join(strings.Split(strings.Title(name), "-"), "")
|
||||||
return strings.ToLower(name[:1]) + name[1:]
|
return strings.ToLower(name[:1]) + name[1:]
|
||||||
}
|
}
|
||||||
|
|
97
vendor/github.com/alecthomas/kong/tag.go
generated
vendored
97
vendor/github.com/alecthomas/kong/tag.go
generated
vendored
|
@ -9,36 +9,50 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// PassthroughMode indicates how parameters are passed through when "passthrough" is set.
|
||||||
|
type PassthroughMode int
|
||||||
|
|
||||||
|
const (
|
||||||
|
// PassThroughModeNone indicates passthrough mode is disabled.
|
||||||
|
PassThroughModeNone PassthroughMode = iota
|
||||||
|
// PassThroughModeAll indicates that all parameters, including flags, are passed through. It is the default.
|
||||||
|
PassThroughModeAll
|
||||||
|
// PassThroughModePartial will validate flags until the first positional argument is encountered, then pass through all remaining positional arguments.
|
||||||
|
PassThroughModePartial
|
||||||
|
)
|
||||||
|
|
||||||
// Tag represents the parsed state of Kong tags in a struct field tag.
|
// Tag represents the parsed state of Kong tags in a struct field tag.
|
||||||
type Tag struct {
|
type Tag struct {
|
||||||
Ignored bool // Field is ignored by Kong. ie. kong:"-"
|
Ignored bool // Field is ignored by Kong. ie. kong:"-"
|
||||||
Cmd bool
|
Cmd bool
|
||||||
Arg bool
|
Arg bool
|
||||||
Required bool
|
Required bool
|
||||||
Optional bool
|
Optional bool
|
||||||
Name string
|
Name string
|
||||||
Help string
|
Help string
|
||||||
Type string
|
Type string
|
||||||
TypeName string
|
TypeName string
|
||||||
HasDefault bool
|
HasDefault bool
|
||||||
Default string
|
Default string
|
||||||
Format string
|
Format string
|
||||||
PlaceHolder string
|
PlaceHolder string
|
||||||
Envs []string
|
Envs []string
|
||||||
Short rune
|
Short rune
|
||||||
Hidden bool
|
Hidden bool
|
||||||
Sep rune
|
Sep rune
|
||||||
MapSep rune
|
MapSep rune
|
||||||
Enum string
|
Enum string
|
||||||
Group string
|
Group string
|
||||||
Xor []string
|
Xor []string
|
||||||
Vars Vars
|
And []string
|
||||||
Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix.
|
Vars Vars
|
||||||
EnvPrefix string
|
Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix.
|
||||||
Embed bool
|
EnvPrefix string
|
||||||
Aliases []string
|
Embed bool
|
||||||
Negatable bool
|
Aliases []string
|
||||||
Passthrough bool
|
Negatable string
|
||||||
|
Passthrough bool // Deprecated: use PassthroughMode instead.
|
||||||
|
PassthroughMode PassthroughMode
|
||||||
|
|
||||||
// Storage for all tag keys for arbitrary lookups.
|
// Storage for all tag keys for arbitrary lookups.
|
||||||
items map[string][]string
|
items map[string][]string
|
||||||
|
@ -249,14 +263,22 @@ func hydrateTag(t *Tag, typ reflect.Type) error { //nolint: gocyclo
|
||||||
for _, xor := range t.GetAll("xor") {
|
for _, xor := range t.GetAll("xor") {
|
||||||
t.Xor = append(t.Xor, strings.FieldsFunc(xor, tagSplitFn)...)
|
t.Xor = append(t.Xor, strings.FieldsFunc(xor, tagSplitFn)...)
|
||||||
}
|
}
|
||||||
|
for _, and := range t.GetAll("and") {
|
||||||
|
t.And = append(t.And, strings.FieldsFunc(and, tagSplitFn)...)
|
||||||
|
}
|
||||||
t.Prefix = t.Get("prefix")
|
t.Prefix = t.Get("prefix")
|
||||||
t.EnvPrefix = t.Get("envprefix")
|
t.EnvPrefix = t.Get("envprefix")
|
||||||
t.Embed = t.Has("embed")
|
t.Embed = t.Has("embed")
|
||||||
negatable := t.Has("negatable")
|
if t.Has("negatable") {
|
||||||
if negatable && !isBool && !isBoolPtr {
|
if !isBool && !isBoolPtr {
|
||||||
return fmt.Errorf("negatable can only be set on booleans")
|
return fmt.Errorf("negatable can only be set on booleans")
|
||||||
|
}
|
||||||
|
negatable := t.Get("negatable")
|
||||||
|
if negatable == "" {
|
||||||
|
negatable = negatableDefault // placeholder for default negation of --no-<flag>
|
||||||
|
}
|
||||||
|
t.Negatable = negatable
|
||||||
}
|
}
|
||||||
t.Negatable = negatable
|
|
||||||
aliases := t.Get("aliases")
|
aliases := t.Get("aliases")
|
||||||
if len(aliases) > 0 {
|
if len(aliases) > 0 {
|
||||||
t.Aliases = append(t.Aliases, strings.FieldsFunc(aliases, tagSplitFn)...)
|
t.Aliases = append(t.Aliases, strings.FieldsFunc(aliases, tagSplitFn)...)
|
||||||
|
@ -280,6 +302,17 @@ func hydrateTag(t *Tag, typ reflect.Type) error { //nolint: gocyclo
|
||||||
return fmt.Errorf("passthrough only makes sense for positional arguments or commands")
|
return fmt.Errorf("passthrough only makes sense for positional arguments or commands")
|
||||||
}
|
}
|
||||||
t.Passthrough = passthrough
|
t.Passthrough = passthrough
|
||||||
|
if t.Passthrough {
|
||||||
|
passthroughMode := t.Get("passthrough")
|
||||||
|
switch passthroughMode {
|
||||||
|
case "partial":
|
||||||
|
t.PassthroughMode = PassThroughModePartial
|
||||||
|
case "all", "":
|
||||||
|
t.PassthroughMode = PassThroughModeAll
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("invalid passthrough mode %q, must be one of 'partial' or 'all'", passthroughMode)
|
||||||
|
}
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
|
@ -31,8 +31,8 @@ github.com/PuerkitoBio/goquery
|
||||||
# github.com/agext/levenshtein v1.2.3
|
# github.com/agext/levenshtein v1.2.3
|
||||||
## explicit
|
## explicit
|
||||||
github.com/agext/levenshtein
|
github.com/agext/levenshtein
|
||||||
# github.com/alecthomas/kong v0.9.0
|
# github.com/alecthomas/kong v1.6.0
|
||||||
## explicit; go 1.18
|
## explicit; go 1.20
|
||||||
github.com/alecthomas/kong
|
github.com/alecthomas/kong
|
||||||
# github.com/andybalholm/cascadia v1.3.2
|
# github.com/andybalholm/cascadia v1.3.2
|
||||||
## explicit; go 1.16
|
## explicit; go 1.16
|
||||||
|
|
Loading…
Reference in a new issue