mirror of
https://github.com/crazy-max/diun.git
synced 2025-03-18 05:02:53 +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 (
|
||||
github.com/AlecAivazis/survey/v2 v2.3.7
|
||||
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/containerd/platforms v0.2.1
|
||||
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/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
|
||||
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.6.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/kong v0.9.0 h1:G5diXxc85KvoV2f0ZRVuMsi45IrBgx9zDNGNj165aPA=
|
||||
github.com/alecthomas/kong v0.9.0/go.mod h1:Y47y5gKfHp1hDc7CH7OeXgLIpp+Q2m1Ni0L5s3bI8Os=
|
||||
github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0=
|
||||
github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k=
|
||||
github.com/alecthomas/kong v1.6.0 h1:mwOzbdMR7uv2vul9J0FU3GYxE7ls/iX1ieMg5WIM6gE=
|
||||
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/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4=
|
||||
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:
|
||||
enable-all: true
|
||||
disable:
|
||||
- maligned
|
||||
- lll
|
||||
- gochecknoglobals
|
||||
- wsl
|
||||
|
@ -17,11 +16,8 @@ linters:
|
|||
- goprintffuncname
|
||||
- paralleltest
|
||||
- nlreturn
|
||||
- goerr113
|
||||
- ifshort
|
||||
- testpackage
|
||||
- wrapcheck
|
||||
- exhaustivestruct
|
||||
- forbidigo
|
||||
- gci
|
||||
- godot
|
||||
|
@ -29,9 +25,6 @@ linters:
|
|||
- cyclop
|
||||
- errorlint
|
||||
- nestif
|
||||
- golint
|
||||
- scopelint
|
||||
- interfacer
|
||||
- tagliatelle
|
||||
- thelper
|
||||
- godox
|
||||
|
@ -41,16 +34,17 @@ linters:
|
|||
- exhaustruct
|
||||
- nonamedreturns
|
||||
- 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
|
||||
- tagalign # hurts readability of kong tags
|
||||
- mnd
|
||||
- perfsprint
|
||||
- err113
|
||||
- copyloopvar
|
||||
- intrange
|
||||
- execinquery
|
||||
|
||||
linters-settings:
|
||||
govet:
|
||||
check-shadowing: true
|
||||
# These govet checks are disabled by default, but they're useful.
|
||||
enable:
|
||||
- niliness
|
||||
|
@ -76,6 +70,7 @@ issues:
|
|||
- 'bad syntax for struct tag key'
|
||||
- 'bad syntax for struct tag pair'
|
||||
- 'result .* \(error\) is always nil'
|
||||
- 'Error return value of `fmt.Fprintln` is not checked'
|
||||
|
||||
exclude-rules:
|
||||
# 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)
|
||||
|
||||
<!-- 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)
|
||||
- [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)
|
||||
## Version 1.0.0 Release
|
||||
|
||||
<!-- /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
|
||||
|
||||
|
@ -561,29 +565,35 @@ Both can coexist with standard Tag parsing.
|
|||
| `name:"X"` | Long name, for overriding field name. |
|
||||
| `help:"X"` | Help text. |
|
||||
| `type:"X"` | Specify [named types](#custom-named-decoders) to use. |
|
||||
| `placeholder:"X"` | Placeholder text. |
|
||||
| `placeholder:"X"` | Placeholder input, if flag. e.g. `` `placeholder:"<the-placeholder>"` `` will show `--flag-name=<the-placeholder>` when displaying help. |
|
||||
| `default:"X"` | Default value. |
|
||||
| `default:"1"` | On a command, make it the default. |
|
||||
| `default:"withargs"` | On a command, make it the default and allow args/flags from that command |
|
||||
| `short:"X"` | Short name, if flag. |
|
||||
| `aliases:"X,Y"` | One or more aliases (for cmd or flag). |
|
||||
| `aliases:"X,Y"` | One or more aliases (for cmd or flag). |
|
||||
| `required:""` | If present, flag/arg is required. |
|
||||
| `optional:""` | If present, flag/arg is optional. |
|
||||
| `hidden:""` | If present, command or flag is hidden. |
|
||||
| `negatable:""` | If present on a `bool` field, supports prefixing a flag with `--no-` to invert the default value |
|
||||
| `negatable:"X"` | If present on a `bool` field, supports `--X` to invert the default value |
|
||||
| `format:"X"` | Format for parsing input, if supported. |
|
||||
| `sep:"X"` | Separator for sequences (defaults to ","). May be `none` to disable splitting. |
|
||||
| `mapsep:"X"` | Separator for maps (defaults to ";"). May be `none` to disable splitting. |
|
||||
| `enum:"X,Y,..."` | Set of valid values allowed for this flag. An enum field must be `required` or have a valid `default`. |
|
||||
| `group:"X"` | Logical group for a flag or command. |
|
||||
| `xor:"X,Y,..."` | Exclusive OR groups for flags. Only one flag in the group can be used which is restricted within the same command. When combined with `required`, at least one of the `xor` group will be required. |
|
||||
| `and:"X,Y,..."` | AND groups for flags. All flags in the group must be used in the same command. When combined with `required`, all flags in the group will be required. |
|
||||
| `prefix:"X"` | Prefix for all sub-flags. |
|
||||
| `envprefix:"X"` | Envar prefix for all sub-flags. |
|
||||
| `set:"K=V"` | Set a variable for expansion by child elements. Multiples can occur. |
|
||||
| `embed:""` | If present, this field's children will be embedded in the parent. Useful for composition. |
|
||||
| `passthrough:""` | If present on a positional argument, it stops flag parsing when encountered, as if `--` was processed before. Useful for external command wrappers, like `exec`. On a command it requires that the command contains only one argument of type `[]string` which is then filled with everything following the command, unparsed. |
|
||||
| `passthrough:"<mode>"`[^1] | If present on a positional argument, it stops flag parsing when encountered, as if `--` was processed before. Useful for external command wrappers, like `exec`. On a command it requires that the command contains only one argument of type `[]string` which is then filled with everything following the command, unparsed. |
|
||||
| `-` | Ignore the field. Useful for adding non-CLI fields to a configuration struct. e.g `` `kong:"-"` `` |
|
||||
|
||||
[^1]: `<mode>` can be `partial` or `all` (the default). `all` will pass through all arguments including flags, including
|
||||
flags. `partial` will validate flags until the first positional argument is encountered, then pass through all remaining
|
||||
positional arguments.
|
||||
|
||||
## Plugins
|
||||
|
||||
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
|
||||
|
||||
Kong does validation on the structure of a command-line, but also supports
|
||||
extensible validation. Any node in the tree may implement the following
|
||||
interface:
|
||||
extensible validation. Any node in the tree may implement either of the following interfaces:
|
||||
|
||||
```go
|
||||
type Validatable interface {
|
||||
|
@ -663,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
|
||||
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.
|
||||
|
||||
1. Use `ConfigureHelp(HelpOptions)` to configure how help is formatted (see [HelpOptions](https://godoc.org/github.com/alecthomas/kong#HelpOptions) for details).
|
||||
2. Custom help can be wired into Kong via the `Help(HelpFunc)` option. The `HelpFunc` is passed a `Context`, which contains the parsed context for the current command-line. See the implementation of `PrintHelp` for an example.
|
||||
2. Custom help can be wired into Kong via the `Help(HelpFunc)` option. The `HelpFunc` is passed a `Context`, which contains the parsed context for the current command-line. See the implementation of `DefaultHelpPrinter` for an example.
|
||||
3. Use `ValueFormatter(HelpValueFormatter)` if you want to just customize the help text that is accompanied by flags and arguments.
|
||||
4. Use `Groups([]Group)` if you want to customize group titles or add a header.
|
||||
|
||||
### `Bind(...)` - bind values for callback hooks and Run() methods
|
||||
### Injecting values into `Run()` methods
|
||||
|
||||
See the [section on hooks](#hooks-beforeresolve-beforeapply-afterapply-and-the-bind-option) for details.
|
||||
There are several ways to inject values into `Run()` methods:
|
||||
|
||||
1. Use `Bind()` to bind values directly.
|
||||
2. Use `BindTo()` to bind values to an interface type.
|
||||
3. Use `BindToProvider()` to bind values to a function that provides the value.
|
||||
4. Implement `Provide<Type>() error` methods on the command structure.
|
||||
|
||||
### Other options
|
||||
|
||||
|
|
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) {
|
||||
v = reflect.Indirect(v)
|
||||
if v.Kind() != reflect.Struct {
|
||||
return out, nil
|
||||
}
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
ft := v.Type().Field(i)
|
||||
fv := v.Field(i)
|
||||
|
@ -170,6 +173,12 @@ MAIN:
|
|||
if flag.Short != 0 {
|
||||
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 {
|
||||
|
@ -272,17 +281,18 @@ func buildField(k *Kong, node *Node, v reflect.Value, ft reflect.StructField, fv
|
|||
}
|
||||
|
||||
value := &Value{
|
||||
Name: name,
|
||||
Help: tag.Help,
|
||||
OrigHelp: tag.Help,
|
||||
HasDefault: tag.HasDefault,
|
||||
Default: tag.Default,
|
||||
DefaultValue: reflect.New(fv.Type()).Elem(),
|
||||
Mapper: mapper,
|
||||
Tag: tag,
|
||||
Target: fv,
|
||||
Enum: tag.Enum,
|
||||
Passthrough: tag.Passthrough,
|
||||
Name: name,
|
||||
Help: tag.Help,
|
||||
OrigHelp: tag.Help,
|
||||
HasDefault: tag.HasDefault,
|
||||
Default: tag.Default,
|
||||
DefaultValue: reflect.New(fv.Type()).Elem(),
|
||||
Mapper: mapper,
|
||||
Tag: tag,
|
||||
Target: fv,
|
||||
Enum: tag.Enum,
|
||||
Passthrough: tag.Passthrough,
|
||||
PassthroughMode: tag.PassthroughMode,
|
||||
|
||||
// Flags are optional by default, and args are required by default.
|
||||
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
|
||||
}
|
||||
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{
|
||||
Value: value,
|
||||
Aliases: tag.Aliases,
|
||||
|
@ -317,6 +334,7 @@ func buildField(k *Kong, node *Node, v reflect.Value, ft reflect.StructField, fv
|
|||
Envs: tag.Envs,
|
||||
Group: buildGroupForKey(k, tag.Group),
|
||||
Xor: tag.Xor,
|
||||
And: tag.And,
|
||||
Hidden: tag.Hidden,
|
||||
}
|
||||
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"
|
||||
)
|
||||
|
||||
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 {
|
||||
out := []string{}
|
||||
|
@ -19,32 +22,23 @@ func (b bindings) String() string {
|
|||
func (b bindings) add(values ...interface{}) bindings {
|
||||
for _, v := range values {
|
||||
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
|
||||
}
|
||||
|
||||
func (b bindings) addTo(impl, iface interface{}) {
|
||||
valueOf := reflect.ValueOf(impl)
|
||||
b[reflect.TypeOf(iface).Elem()] = func() (reflect.Value, error) { return valueOf, nil }
|
||||
b[reflect.TypeOf(iface).Elem()] = func() (any, error) { return impl, nil }
|
||||
}
|
||||
|
||||
func (b bindings) addProvider(provider interface{}) error {
|
||||
pv := reflect.ValueOf(provider)
|
||||
t := pv.Type()
|
||||
if t.Kind() != reflect.Func || t.NumIn() != 0 || 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)
|
||||
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)
|
||||
}
|
||||
rt := pv.Type().Out(0)
|
||||
b[rt] = func() (reflect.Value, error) {
|
||||
out := pv.Call(nil)
|
||||
errv := out[1]
|
||||
var err error
|
||||
if !errv.IsNil() {
|
||||
err = errv.Interface().(error) //nolint
|
||||
}
|
||||
return out[0], err
|
||||
}
|
||||
b[rt] = provider
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -78,28 +72,19 @@ func callFunction(f reflect.Value, bindings bindings) error {
|
|||
if f.Kind() != reflect.Func {
|
||||
return fmt.Errorf("expected function, got %s", f.Type())
|
||||
}
|
||||
in := []reflect.Value{}
|
||||
t := f.Type()
|
||||
if t.NumOut() != 1 || !t.Out(0).Implements(callbackReturnSignature) {
|
||||
return fmt.Errorf("return value of %s must implement \"error\"", t)
|
||||
}
|
||||
for i := 0; i < t.NumIn(); i++ {
|
||||
pt := t.In(i)
|
||||
if argf, ok := bindings[pt]; ok {
|
||||
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, err := callAnyFunction(f, bindings)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
out := f.Call(in)
|
||||
if out[0].IsNil() {
|
||||
ferr := out[0]
|
||||
if ferrv := reflect.ValueOf(ferr); !ferrv.IsValid() || ((ferrv.Kind() == reflect.Interface || ferrv.Kind() == reflect.Pointer) && ferrv.IsNil()) {
|
||||
return nil
|
||||
}
|
||||
return out[0].Interface().(error) //nolint
|
||||
return ferr.(error) //nolint:forcetypeassert
|
||||
}
|
||||
|
||||
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()
|
||||
for i := 0; i < t.NumIn(); i++ {
|
||||
pt := t.In(i)
|
||||
if argf, ok := bindings[pt]; ok {
|
||||
argv, err := argf()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
in = append(in, argv)
|
||||
} else {
|
||||
argf, ok := bindings[pt]
|
||||
if !ok {
|
||||
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)
|
||||
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()
|
||||
}
|
||||
if validate := isValidatable(value); validate != nil {
|
||||
if err := validate.Validate(); err != nil {
|
||||
if err := validate.Validate(c); err != nil {
|
||||
if desc != "" {
|
||||
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 {
|
||||
return err
|
||||
}
|
||||
if err := checkXorDuplicates(c.Path); err != nil {
|
||||
if err := checkXorDuplicatedAndAndMissing(c.Path); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -347,6 +347,7 @@ func (c *Context) endParsing() {
|
|||
}
|
||||
}
|
||||
|
||||
//nolint:maintidx
|
||||
func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
|
||||
positional := 0
|
||||
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.
|
||||
case v == "--":
|
||||
c.scan.Pop()
|
||||
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.
|
||||
case strings.HasPrefix(v, "--"):
|
||||
c.scan.Pop()
|
||||
|
@ -420,12 +425,22 @@ func (c *Context) trace(node *Node) (err error) { //nolint: gocyclo
|
|||
|
||||
case FlagToken:
|
||||
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:
|
||||
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:
|
||||
|
@ -700,13 +715,13 @@ func (c *Context) parseFlag(flags []*Flag, match string) (err error) {
|
|||
candidates = append(candidates, alias)
|
||||
}
|
||||
|
||||
neg := "--no-" + flag.Name
|
||||
if !matched && !(match == neg && flag.Tag.Negatable) {
|
||||
neg := negatableFlagName(flag.Name, flag.Tag.Negatable)
|
||||
if !matched && match != neg {
|
||||
continue
|
||||
}
|
||||
// Found a matching flag.
|
||||
c.scan.Pop()
|
||||
if match == neg && flag.Tag.Negatable {
|
||||
if match == neg && flag.Tag.Negatable != "" {
|
||||
flag.Negated = true
|
||||
}
|
||||
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})
|
||||
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.
|
||||
func (c *Context) Call(fn any, binds ...interface{}) (out []interface{}, err error) {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -757,6 +782,19 @@ func (c *Context) RunNode(node *Node, binds ...interface{}) (err error) {
|
|||
methodBinds = methodBinds.clone()
|
||||
for p := node; p != nil; p = p.Parent {
|
||||
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() {
|
||||
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) {
|
||||
node := c.Selected()
|
||||
if node == nil {
|
||||
if len(c.Path) > 0 {
|
||||
selected := c.Path[0].Node()
|
||||
if selected.Type == ApplicationNode {
|
||||
method := getMethod(selected.Target, "Run")
|
||||
if method.IsValid() {
|
||||
return c.RunNode(selected, binds...)
|
||||
}
|
||||
}
|
||||
if len(c.Path) == 0 {
|
||||
return fmt.Errorf("no command selected")
|
||||
}
|
||||
selected := c.Path[0].Node()
|
||||
if selected.Type == ApplicationNode {
|
||||
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.
|
||||
|
@ -811,23 +853,35 @@ func (c *Context) PrintUsage(summary bool) error {
|
|||
func checkMissingFlags(flags []*Flag) error {
|
||||
xorGroupSet := map[string]bool{}
|
||||
xorGroup := map[string][]string{}
|
||||
andGroupSet := map[string]bool{}
|
||||
andGroup := map[string][]string{}
|
||||
missing := []string{}
|
||||
andGroupRequired := getRequiredAndGroupMap(flags)
|
||||
for _, flag := range flags {
|
||||
for _, and := range flag.And {
|
||||
flag.Required = andGroupRequired[and]
|
||||
}
|
||||
if flag.Set {
|
||||
for _, xor := range flag.Xor {
|
||||
xorGroupSet[xor] = true
|
||||
}
|
||||
for _, and := range flag.And {
|
||||
andGroupSet[and] = true
|
||||
}
|
||||
}
|
||||
if !flag.Required || flag.Set {
|
||||
continue
|
||||
}
|
||||
if len(flag.Xor) > 0 {
|
||||
if len(flag.Xor) > 0 || len(flag.And) > 0 {
|
||||
for _, xor := range flag.Xor {
|
||||
if xorGroupSet[xor] {
|
||||
continue
|
||||
}
|
||||
xorGroup[xor] = append(xorGroup[xor], flag.Summary())
|
||||
}
|
||||
for _, and := range flag.And {
|
||||
andGroup[and] = append(andGroup[and], flag.Summary())
|
||||
}
|
||||
} else {
|
||||
missing = append(missing, flag.Summary())
|
||||
}
|
||||
|
@ -837,6 +891,11 @@ func checkMissingFlags(flags []*Flag) error {
|
|||
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 {
|
||||
return nil
|
||||
|
@ -847,6 +906,18 @@ func checkMissingFlags(flags []*Flag) error {
|
|||
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 {
|
||||
missing := []string{}
|
||||
|
||||
|
@ -883,7 +954,7 @@ func checkMissingChildren(node *Node) error {
|
|||
if len(missing) == 1 {
|
||||
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.
|
||||
|
@ -943,7 +1014,7 @@ func checkEnum(value *Value, target reflect.Value) error {
|
|||
}
|
||||
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 {
|
||||
for _, path := range paths {
|
||||
seen := map[string]*Flag{}
|
||||
|
@ -975,6 +1060,38 @@ func checkXorDuplicates(paths []*Path) error {
|
|||
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 {
|
||||
if len(haystack) == 0 {
|
||||
return fmt.Errorf(format, args...)
|
||||
|
@ -995,12 +1112,23 @@ func findPotentialCandidates(needle string, haystack []string, format string, ar
|
|||
}
|
||||
|
||||
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() {
|
||||
return nil
|
||||
}
|
||||
if validate, ok := v.Interface().(validatable); ok {
|
||||
return validatableFunc(validate.Validate)
|
||||
}
|
||||
if validate, ok := v.Interface().(extendedValidatable); ok {
|
||||
return validate
|
||||
}
|
||||
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
|
||||
isBool := flag.IsBool()
|
||||
isCounter := flag.IsCounter()
|
||||
|
||||
short := ""
|
||||
if flag.Short != 0 {
|
||||
if isBool && flag.Tag.Negatable {
|
||||
flagString += fmt.Sprintf("-%c, --[no-]%s", flag.Short, name)
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
}
|
||||
short = "-" + string(flag.Short) + ", "
|
||||
} else if haveShort {
|
||||
short = " "
|
||||
}
|
||||
|
||||
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 {
|
||||
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.
|
||||
type BeforeResolve interface {
|
||||
// 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.
|
||||
type BeforeApply interface {
|
||||
// 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.
|
||||
type AfterApply interface {
|
||||
// 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.
|
||||
for _, embed := range k.embedded {
|
||||
tag, err := parseTagString(strings.Join(embed.tags, " ")) //nolint:govet
|
||||
tag, err := parseTagString(strings.Join(embed.tags, " "))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -167,9 +167,42 @@ func New(grammar interface{}, options ...Option) (*Kong, error) {
|
|||
|
||||
k.bindings.add(k.vars)
|
||||
|
||||
if err = checkOverlappingXorAnd(k); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
updatedVars := map[string]string{
|
||||
"default": value.Default,
|
||||
"enum": value.Enum,
|
||||
}
|
||||
if value.Default, err = interpolate(value.Default, vars, nil); err != nil {
|
||||
return fmt.Errorf("default value for %s: %s", value.Summary(), err)
|
||||
}
|
||||
if value.Enum, err = interpolate(value.Enum, vars, nil); err != nil {
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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{}) {
|
||||
lines := strings.Split(fmt.Sprintf(format, args...), "\n")
|
||||
lines := strings.Split(strings.TrimRight(fmt.Sprintf(format, args...), "\n"), "\n")
|
||||
leader := ""
|
||||
for _, l := range leaders {
|
||||
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]
|
||||
}
|
||||
|
||||
func min(a, b int) int {
|
||||
func min(a, b int) int { //nolint:predeclared
|
||||
if a <= b {
|
||||
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.
|
||||
type Value struct {
|
||||
Flag *Flag // Nil if positional argument.
|
||||
Name string
|
||||
Help string
|
||||
OrigHelp string // Original help string, without interpolated variables.
|
||||
HasDefault bool
|
||||
Default string
|
||||
DefaultValue reflect.Value
|
||||
Enum string
|
||||
Mapper Mapper
|
||||
Tag *Tag
|
||||
Target reflect.Value
|
||||
Required bool
|
||||
Set bool // Set to true when this value is set through some mechanism.
|
||||
Format string // Formatting directive, if applicable.
|
||||
Position int // Position (for positional arguments).
|
||||
Passthrough bool // Set to true to stop flag parsing when encountered.
|
||||
Active bool // Denotes the value is part of an active branch in the CLI.
|
||||
Flag *Flag // Nil if positional argument.
|
||||
Name string
|
||||
Help string
|
||||
OrigHelp string // Original help string, without interpolated variables.
|
||||
HasDefault bool
|
||||
Default string
|
||||
DefaultValue reflect.Value
|
||||
Enum string
|
||||
Mapper Mapper
|
||||
Tag *Tag
|
||||
Target reflect.Value
|
||||
Required bool
|
||||
Set bool // Set to true when this value is set through some mechanism.
|
||||
Format string // Formatting directive, if applicable.
|
||||
Position int // Position (for positional arguments).
|
||||
Passthrough bool // Deprecated: Use PassthroughMode instead. Set to true to stop flag parsing when encountered.
|
||||
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.
|
||||
|
@ -405,6 +406,7 @@ type Flag struct {
|
|||
*Value
|
||||
Group *Group // Logical grouping when displaying. May also be used by configuration loaders to group options logically.
|
||||
Xor []string
|
||||
And []string
|
||||
PlaceHolder string
|
||||
Envs []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>".
|
||||
func DynamicCommand(name, help, group string, cmd interface{}, tags ...string) Option {
|
||||
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{
|
||||
name: name,
|
||||
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
|
||||
// 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 {
|
||||
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:]
|
||||
}
|
||||
|
|
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"
|
||||
)
|
||||
|
||||
// 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.
|
||||
type Tag struct {
|
||||
Ignored bool // Field is ignored by Kong. ie. kong:"-"
|
||||
Cmd bool
|
||||
Arg bool
|
||||
Required bool
|
||||
Optional bool
|
||||
Name string
|
||||
Help string
|
||||
Type string
|
||||
TypeName string
|
||||
HasDefault bool
|
||||
Default string
|
||||
Format string
|
||||
PlaceHolder string
|
||||
Envs []string
|
||||
Short rune
|
||||
Hidden bool
|
||||
Sep rune
|
||||
MapSep rune
|
||||
Enum string
|
||||
Group string
|
||||
Xor []string
|
||||
Vars Vars
|
||||
Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix.
|
||||
EnvPrefix string
|
||||
Embed bool
|
||||
Aliases []string
|
||||
Negatable bool
|
||||
Passthrough bool
|
||||
Ignored bool // Field is ignored by Kong. ie. kong:"-"
|
||||
Cmd bool
|
||||
Arg bool
|
||||
Required bool
|
||||
Optional bool
|
||||
Name string
|
||||
Help string
|
||||
Type string
|
||||
TypeName string
|
||||
HasDefault bool
|
||||
Default string
|
||||
Format string
|
||||
PlaceHolder string
|
||||
Envs []string
|
||||
Short rune
|
||||
Hidden bool
|
||||
Sep rune
|
||||
MapSep rune
|
||||
Enum string
|
||||
Group string
|
||||
Xor []string
|
||||
And []string
|
||||
Vars Vars
|
||||
Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix.
|
||||
EnvPrefix string
|
||||
Embed bool
|
||||
Aliases []string
|
||||
Negatable string
|
||||
Passthrough bool // Deprecated: use PassthroughMode instead.
|
||||
PassthroughMode PassthroughMode
|
||||
|
||||
// Storage for all tag keys for arbitrary lookups.
|
||||
items map[string][]string
|
||||
|
@ -249,14 +263,22 @@ func hydrateTag(t *Tag, typ reflect.Type) error { //nolint: gocyclo
|
|||
for _, xor := range t.GetAll("xor") {
|
||||
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.EnvPrefix = t.Get("envprefix")
|
||||
t.Embed = t.Has("embed")
|
||||
negatable := t.Has("negatable")
|
||||
if negatable && !isBool && !isBoolPtr {
|
||||
return fmt.Errorf("negatable can only be set on booleans")
|
||||
if t.Has("negatable") {
|
||||
if !isBool && !isBoolPtr {
|
||||
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")
|
||||
if len(aliases) > 0 {
|
||||
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")
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
|
|
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
|
||||
## explicit
|
||||
github.com/agext/levenshtein
|
||||
# github.com/alecthomas/kong v0.9.0
|
||||
## explicit; go 1.18
|
||||
# github.com/alecthomas/kong v1.6.0
|
||||
## explicit; go 1.20
|
||||
github.com/alecthomas/kong
|
||||
# github.com/andybalholm/cascadia v1.3.2
|
||||
## explicit; go 1.16
|
||||
|
|
Loading…
Reference in a new issue