diff --git a/go.mod b/go.mod index 5b42f32b54f..6011840497a 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.23.3 require ( cloud.google.com/go/storage v1.41.0 - github.com/alecthomas/kong v1.6.0 + github.com/alecthomas/kong v1.6.1 github.com/alicebob/miniredis/v2 v2.34.0 github.com/aws/aws-sdk-go v1.55.5 github.com/cespare/xxhash/v2 v2.3.0 diff --git a/go.sum b/go.sum index 58aec5551bf..e3d919d72ef 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,8 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= 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/kong v1.6.1 h1:/7bVimARU3uxPD0hbryPE8qWrS3Oz3kPQoxA/H2NKG8= +github.com/alecthomas/kong v1.6.1/go.mod h1:p2vqieVMeTAnaC83txKtXe8FLke2X07aruPWXyMPQrU= github.com/alecthomas/participle/v2 v2.1.1 h1:hrjKESvSqGHzRb4yW1ciisFJ4p3MGYih6icjJvbsmV8= github.com/alecthomas/participle/v2 v2.1.1/go.mod h1:Y1+hAs8DHPmc3YUFzqllV+eSQ9ljPTk0ZkPMtEdAx2c= github.com/alecthomas/repr v0.4.0 h1:GhI2A8MACjfegCPVq9f1FLvIBS+DrQ2KQBFZP1iFzXc= diff --git a/vendor/github.com/alecthomas/kong/README.md b/vendor/github.com/alecthomas/kong/README.md index ee4befea393..4a86251ca96 100644 --- a/vendor/github.com/alecthomas/kong/README.md +++ b/vendor/github.com/alecthomas/kong/README.md @@ -5,40 +5,39 @@ [![](https://godoc.org/github.com/alecthomas/kong?status.svg)](http://godoc.org/github.com/alecthomas/kong) [![CircleCI](https://img.shields.io/circleci/project/github/alecthomas/kong.svg)](https://circleci.com/gh/alecthomas/kong) [![Go Report Card](https://goreportcard.com/badge/github.com/alecthomas/kong)](https://goreportcard.com/report/github.com/alecthomas/kong) [![Slack chat](https://img.shields.io/static/v1?logo=slack&style=flat&label=slack&color=green&message=gophers)](https://gophers.slack.com/messages/CN9DS8YF3) -- [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) +- [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) + - [Injecting values into `Run()` methods](#injecting-values-into-run-methods) + - [Other options](#other-options) ## Version 1.0.0 Release @@ -308,8 +307,8 @@ func main() { ## Hooks: BeforeReset(), BeforeResolve(), BeforeApply(), AfterApply() and the Bind() option -If a node in the grammar has a `BeforeReset(...)`, `BeforeResolve -(...)`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those +If a node in the CLI, or any of its embedded fields, has a `BeforeReset(...) error`, `BeforeResolve +(...) error`, `BeforeApply(...) error` and/or `AfterApply(...) error` method, those methods will be called before values are reset, before validation/assignment, and after validation/assignment, respectively. @@ -342,40 +341,6 @@ func main() { } ``` -Another example of using hooks is load the env-file: - -```go -package main - -import ( - "fmt" - "github.com/alecthomas/kong" - "github.com/joho/godotenv" -) - -type EnvFlag string - -// BeforeResolve loads env file. -func (c EnvFlag) BeforeReset(ctx *kong.Context, trace *kong.Path) error { - path := string(ctx.FlagValue(trace.Flag).(EnvFlag)) // nolint - path = kong.ExpandPath(path) - if err := godotenv.Load(path); err != nil { - return err - } - return nil -} - -var CLI struct { - EnvFile EnvFlag - Flag `env:"FLAG"` -} - -func main() { - _ = kong.Parse(&CLI) - fmt.Println(CLI.Flag) -} -``` - ## Flags Any [mapped](#mapper---customising-how-the-command-line-is-mapped-to-go-values) field in the command structure _not_ tagged with `cmd` or `arg` will be a flag. Flags are optional by default. @@ -585,6 +550,7 @@ Both can coexist with standard Tag parsing. | `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. | +| `xorprefix:"X"` | Prefix for all sub-flags in XOR/AND groups. | | `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:""`[^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. | @@ -683,7 +649,7 @@ normal validation. ## Modifying Kong's behaviour -Each Kong parser can be configured via functional options passed to `New(cli interface{}, options...Option)`. +Each Kong parser can be configured via functional options passed to `New(cli any, options...Option)`. The full set of options can be found [here](https://godoc.org/github.com/alecthomas/kong#Option). @@ -741,7 +707,7 @@ All builtin Go types (as well as a bunch of useful stdlib types like `time.Time` 1. `NamedMapper(string, Mapper)` and using the tag key `type:""`. 2. `KindMapper(reflect.Kind, Mapper)`. 3. `TypeMapper(reflect.Type, Mapper)`. -4. `ValueMapper(interface{}, Mapper)`, passing in a pointer to a field of the grammar. +4. `ValueMapper(any, Mapper)`, passing in a pointer to a field of the grammar. ### `ConfigureHelp(HelpOptions)` and `Help(HelpFunc)` - customising help diff --git a/vendor/github.com/alecthomas/kong/build.go b/vendor/github.com/alecthomas/kong/build.go index 42d30f08e04..5d17f53fc86 100644 --- a/vendor/github.com/alecthomas/kong/build.go +++ b/vendor/github.com/alecthomas/kong/build.go @@ -9,9 +9,9 @@ import ( // Plugins are dynamically embedded command-line structures. // // Each element in the Plugins list *must* be a pointer to a structure. -type Plugins []interface{} +type Plugins []any -func build(k *Kong, ast interface{}) (app *Application, err error) { +func build(k *Kong, ast any) (app *Application, err error) { v := reflect.ValueOf(ast) iv := reflect.Indirect(v) if v.Kind() != reflect.Ptr || iv.Kind() != reflect.Struct { @@ -71,6 +71,7 @@ func flattenedFields(v reflect.Value, ptag *Tag) (out []flattenedField, err erro // Accumulate prefixes. tag.Prefix = ptag.Prefix + tag.Prefix tag.EnvPrefix = ptag.EnvPrefix + tag.EnvPrefix + tag.XorPrefix = ptag.XorPrefix + tag.XorPrefix // Combine parent vars. tag.Vars = ptag.Vars.CloneWith(tag.Vars) // Command and embedded structs can be pointers, so we hydrate them now. @@ -111,7 +112,7 @@ func flattenedFields(v reflect.Value, ptag *Tag) (out []flattenedField, err erro // Build a Node in the Kong data model. // // "v" is the value to create the node from, "typ" is the output Node type. -func buildNode(k *Kong, v reflect.Value, typ NodeType, tag *Tag, seenFlags map[string]bool) (*Node, error) { +func buildNode(k *Kong, v reflect.Value, typ NodeType, tag *Tag, seenFlags map[string]bool) (*Node, error) { //nolint:gocyclo node := &Node{ Type: typ, Target: v, @@ -147,6 +148,18 @@ MAIN: } } + if len(tag.Xor) != 0 { + for i := range tag.Xor { + tag.Xor[i] = tag.XorPrefix + tag.Xor[i] + } + } + + if len(tag.And) != 0 { + for i := range tag.And { + tag.And[i] = tag.XorPrefix + tag.And[i] + } + } + // Nested structs are either commands or args, unless they implement the Mapper interface. if field.value.Kind() == reflect.Struct && (tag.Cmd || tag.Arg) && k.registry.ForValue(fv) == nil { typ := CommandNode diff --git a/vendor/github.com/alecthomas/kong/callbacks.go b/vendor/github.com/alecthomas/kong/callbacks.go index 1df975d8236..c1fac817814 100644 --- a/vendor/github.com/alecthomas/kong/callbacks.go +++ b/vendor/github.com/alecthomas/kong/callbacks.go @@ -19,7 +19,7 @@ func (b bindings) String() string { return "bindings{" + strings.Join(out, ", ") + "}" } -func (b bindings) add(values ...interface{}) bindings { +func (b bindings) add(values ...any) bindings { for _, v := range values { v := v b[reflect.TypeOf(v)] = func() (any, error) { return v, nil } @@ -27,11 +27,11 @@ func (b bindings) add(values ...interface{}) bindings { return b } -func (b bindings) addTo(impl, iface interface{}) { +func (b bindings) addTo(impl, iface any) { b[reflect.TypeOf(iface).Elem()] = func() (any, error) { return impl, nil } } -func (b bindings) addProvider(provider interface{}) error { +func (b bindings) addProvider(provider any) error { pv := reflect.ValueOf(provider) t := pv.Type() if t.Kind() != reflect.Func || t.NumOut() != 2 || t.Out(1) != reflect.TypeOf((*error)(nil)).Elem() { @@ -68,6 +68,33 @@ func getMethod(value reflect.Value, name string) reflect.Value { return method } +// Get methods from the given value and any embedded fields. +func getMethods(value reflect.Value, name string) []reflect.Value { + // Collect all possible receivers + receivers := []reflect.Value{value} + if value.Kind() == reflect.Ptr { + value = value.Elem() + } + if value.Kind() == reflect.Struct { + t := value.Type() + for i := 0; i < value.NumField(); i++ { + field := value.Field(i) + fieldType := t.Field(i) + if fieldType.IsExported() && fieldType.Anonymous { + receivers = append(receivers, field) + } + } + } + // Search all receivers for methods + var methods []reflect.Value + for _, receiver := range receivers { + if method := getMethod(receiver, name); method.IsValid() { + methods = append(methods, method) + } + } + return methods +} + func callFunction(f reflect.Value, bindings bindings) error { if f.Kind() != reflect.Func { return fmt.Errorf("expected function, got %s", f.Type()) diff --git a/vendor/github.com/alecthomas/kong/context.go b/vendor/github.com/alecthomas/kong/context.go index fd168fa921b..b6a56e33cc5 100644 --- a/vendor/github.com/alecthomas/kong/context.go +++ b/vendor/github.com/alecthomas/kong/context.go @@ -102,7 +102,7 @@ func Trace(k *Kong, args []string) (*Context, error) { } // Bind adds bindings to the Context. -func (c *Context) Bind(args ...interface{}) { +func (c *Context) Bind(args ...any) { c.bindings.add(args...) } @@ -111,7 +111,7 @@ func (c *Context) Bind(args ...interface{}) { // This will typically have to be called like so: // // BindTo(impl, (*MyInterface)(nil)) -func (c *Context) BindTo(impl, iface interface{}) { +func (c *Context) BindTo(impl, iface any) { c.bindings.addTo(impl, iface) } @@ -119,7 +119,7 @@ func (c *Context) BindTo(impl, iface interface{}) { // // This is useful when the Run() function of different commands require different values that may // not all be initialisable from the main() function. -func (c *Context) BindToProvider(provider interface{}) error { +func (c *Context) BindToProvider(provider any) error { return c.bindings.addProvider(provider) } @@ -306,7 +306,7 @@ func (c *Context) AddResolver(resolver Resolver) { } // FlagValue returns the set value of a flag if it was encountered and exists, or its default value. -func (c *Context) FlagValue(flag *Flag) interface{} { +func (c *Context) FlagValue(flag *Flag) any { for _, trace := range c.Path { if trace.Flag == flag { v, ok := c.values[trace.Flag.Value] @@ -572,7 +572,7 @@ func (c *Context) Resolve() error { } // Pick the last resolved value. - var selected interface{} + var selected any for _, resolver := range resolvers { s, err := resolver.Resolve(c, path, flag) if err != nil { @@ -757,7 +757,7 @@ 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) { +func (c *Context) Call(fn any, binds ...any) (out []any, err error) { fv := reflect.ValueOf(fn) bindings := c.Kong.bindings.clone().add(binds...).add(c).merge(c.bindings) return callAnyFunction(fv, bindings) @@ -769,7 +769,7 @@ func (c *Context) Call(fn any, binds ...interface{}) (out []interface{}, err err // // Any passed values will be bindable to arguments of the target Run() method. Additionally, // all parent nodes in the command structure will be bound. -func (c *Context) RunNode(node *Node, binds ...interface{}) (err error) { +func (c *Context) RunNode(node *Node, binds ...any) (err error) { type targetMethod struct { node *Node method reflect.Value @@ -803,11 +803,6 @@ func (c *Context) RunNode(node *Node, binds ...interface{}) (err error) { if len(methods) == 0 { return fmt.Errorf("no Run() method found in hierarchy of %s", c.Selected().Summary()) } - _, err = c.Apply() - if err != nil { - return err - } - for _, method := range methods { if err = callFunction(method.method, method.binds); err != nil { return err @@ -820,7 +815,7 @@ func (c *Context) RunNode(node *Node, binds ...interface{}) (err error) { // // Any passed values will be bindable to arguments of the target Run() method. Additionally, // all parent nodes in the command structure will be bound. -func (c *Context) Run(binds ...interface{}) (err error) { +func (c *Context) Run(binds ...any) (err error) { node := c.Selected() if node == nil { if len(c.Path) == 0 { @@ -832,7 +827,9 @@ func (c *Context) Run(binds ...interface{}) (err error) { if method.IsValid() { node = selected } - } else { + } + + if node == nil { return fmt.Errorf("no command selected") } } @@ -1092,7 +1089,7 @@ func checkAndMissing(paths []*Path) error { return nil } -func findPotentialCandidates(needle string, haystack []string, format string, args ...interface{}) error { +func findPotentialCandidates(needle string, haystack []string, format string, args ...any) error { if len(haystack) == 0 { return fmt.Errorf(format, args...) } diff --git a/vendor/github.com/alecthomas/kong/defaults.go b/vendor/github.com/alecthomas/kong/defaults.go index f6728d79fa8..9489fb3bf27 100644 --- a/vendor/github.com/alecthomas/kong/defaults.go +++ b/vendor/github.com/alecthomas/kong/defaults.go @@ -1,7 +1,7 @@ package kong // ApplyDefaults if they are not already set. -func ApplyDefaults(target interface{}, options ...Option) error { +func ApplyDefaults(target any, options ...Option) error { app, err := New(target, options...) if err != nil { return err diff --git a/vendor/github.com/alecthomas/kong/global.go b/vendor/github.com/alecthomas/kong/global.go index d4b3cb56aa5..babe1e197dc 100644 --- a/vendor/github.com/alecthomas/kong/global.go +++ b/vendor/github.com/alecthomas/kong/global.go @@ -5,7 +5,7 @@ import ( ) // Parse constructs a new parser and parses the default command-line. -func Parse(cli interface{}, options ...Option) *Context { +func Parse(cli any, options ...Option) *Context { parser, err := New(cli, options...) if err != nil { panic(err) diff --git a/vendor/github.com/alecthomas/kong/help.go b/vendor/github.com/alecthomas/kong/help.go index 26f355df373..6363ea212dc 100644 --- a/vendor/github.com/alecthomas/kong/help.go +++ b/vendor/github.com/alecthomas/kong/help.go @@ -386,7 +386,7 @@ func newHelpWriter(ctx *Context, options HelpOptions) *helpWriter { return w } -func (h *helpWriter) Printf(format string, args ...interface{}) { +func (h *helpWriter) Printf(format string, args ...any) { h.Print(fmt.Sprintf(format, args...)) } diff --git a/vendor/github.com/alecthomas/kong/kong.go b/vendor/github.com/alecthomas/kong/kong.go index 764a994c720..b85e145296c 100644 --- a/vendor/github.com/alecthomas/kong/kong.go +++ b/vendor/github.com/alecthomas/kong/kong.go @@ -15,7 +15,7 @@ var ( callbackReturnSignature = reflect.TypeOf((*error)(nil)).Elem() ) -func failField(parent reflect.Value, field reflect.StructField, format string, args ...interface{}) error { +func failField(parent reflect.Value, field reflect.StructField, format string, args ...any) error { name := parent.Type().Name() if name == "" { name = "" @@ -24,7 +24,7 @@ func failField(parent reflect.Value, field reflect.StructField, format string, a } // Must creates a new Parser or panics if there is an error. -func Must(ast interface{}, options ...Option) *Kong { +func Must(ast any, options ...Option) *Kong { k, err := New(ast, options...) if err != nil { panic(err) @@ -76,7 +76,7 @@ type Kong struct { // New creates a new Kong parser on grammar. // // See the README (https://github.com/alecthomas/kong) for usage instructions. -func New(grammar interface{}, options ...Option) (*Kong, error) { +func New(grammar any, options ...Option) (*Kong, error) { k := &Kong{ Exit: os.Exit, Stdout: os.Stdout, @@ -361,16 +361,14 @@ func (k *Kong) applyHook(ctx *Context, name string) error { default: panic("unsupported Path") } - method := getMethod(value, name) - if !method.IsValid() { - continue - } - binds := k.bindings.clone() - binds.add(ctx, trace) - binds.add(trace.Node().Vars().CloneWith(k.vars)) - binds.merge(ctx.bindings) - if err := callFunction(method, binds); err != nil { - return err + for _, method := range getMethods(value, name) { + binds := k.bindings.clone() + binds.add(ctx, trace) + binds.add(trace.Node().Vars().CloneWith(k.vars)) + binds.merge(ctx.bindings) + if err := callFunction(method, binds); err != nil { + return err + } } } // Path[0] will always be the app root. @@ -392,20 +390,18 @@ func (k *Kong) applyHookToDefaultFlags(ctx *Context, node *Node, name string) er if !flag.HasDefault || ctx.values[flag.Value].IsValid() || !flag.Target.IsValid() { continue } - method := getMethod(flag.Target, name) - if !method.IsValid() { - continue - } - path := &Path{Flag: flag} - if err := callFunction(method, binds.clone().add(path)); err != nil { - return next(err) + for _, method := range getMethods(flag.Target, name) { + path := &Path{Flag: flag} + if err := callFunction(method, binds.clone().add(path)); err != nil { + return next(err) + } } } return next(nil) }) } -func formatMultilineMessage(w io.Writer, leaders []string, format string, args ...interface{}) { +func formatMultilineMessage(w io.Writer, leaders []string, format string, args ...any) { lines := strings.Split(strings.TrimRight(fmt.Sprintf(format, args...), "\n"), "\n") leader := "" for _, l := range leaders { @@ -421,25 +417,25 @@ func formatMultilineMessage(w io.Writer, leaders []string, format string, args . } // Printf writes a message to Kong.Stdout with the application name prefixed. -func (k *Kong) Printf(format string, args ...interface{}) *Kong { +func (k *Kong) Printf(format string, args ...any) *Kong { formatMultilineMessage(k.Stdout, []string{k.Model.Name}, format, args...) return k } // Errorf writes a message to Kong.Stderr with the application name prefixed. -func (k *Kong) Errorf(format string, args ...interface{}) *Kong { +func (k *Kong) Errorf(format string, args ...any) *Kong { formatMultilineMessage(k.Stderr, []string{k.Model.Name, "error"}, format, args...) return k } // Fatalf writes a message to Kong.Stderr with the application name prefixed then exits with a non-zero status. -func (k *Kong) Fatalf(format string, args ...interface{}) { +func (k *Kong) Fatalf(format string, args ...any) { k.Errorf(format, args...) k.Exit(1) } // FatalIfErrorf terminates with an error message if err != nil. -func (k *Kong) FatalIfErrorf(err error, args ...interface{}) { +func (k *Kong) FatalIfErrorf(err error, args ...any) { if err == nil { return } diff --git a/vendor/github.com/alecthomas/kong/mapper.go b/vendor/github.com/alecthomas/kong/mapper.go index 584bb00691d..db3f24ec8be 100644 --- a/vendor/github.com/alecthomas/kong/mapper.go +++ b/vendor/github.com/alecthomas/kong/mapper.go @@ -251,7 +251,7 @@ func (r *Registry) RegisterType(typ reflect.Type, mapper Mapper) *Registry { } // RegisterValue registers a Mapper by pointer to the field value. -func (r *Registry) RegisterValue(ptr interface{}, mapper Mapper) *Registry { +func (r *Registry) RegisterValue(ptr any, mapper Mapper) *Registry { key := reflect.ValueOf(ptr) if key.Kind() != reflect.Ptr { panic("expected a pointer") @@ -473,7 +473,7 @@ func mapDecoder(r *Registry) MapperFunc { case string: childScanner = ScanAsType(t.Type, SplitEscaped(v, mapsep)...) - case []map[string]interface{}: + case []map[string]any: for _, m := range v { err := jsonTranscode(m, target.Addr().Interface()) if err != nil { @@ -482,7 +482,7 @@ func mapDecoder(r *Registry) MapperFunc { } return nil - case map[string]interface{}: + case map[string]any: return jsonTranscode(v, target.Addr().Interface()) default: @@ -548,11 +548,11 @@ func sliceDecoder(r *Registry) MapperFunc { case string: childScanner = ScanAsType(t.Type, SplitEscaped(v, sep)...) - case []interface{}: + case []any: return jsonTranscode(v, target.Addr().Interface()) default: - v = []interface{}{v} + v = []any{v} return jsonTranscode(v, target.Addr().Interface()) } } else { @@ -922,7 +922,7 @@ func (f *FileContentFlag) Decode(ctx *DecodeContext) error { //nolint: revive return nil } -func jsonTranscode(in, out interface{}) error { +func jsonTranscode(in, out any) error { data, err := json.Marshal(in) if err != nil { return err diff --git a/vendor/github.com/alecthomas/kong/model.go b/vendor/github.com/alecthomas/kong/model.go index 25ffe96be9f..065fcdd0848 100644 --- a/vendor/github.com/alecthomas/kong/model.go +++ b/vendor/github.com/alecthomas/kong/model.go @@ -69,7 +69,7 @@ func (n *Node) Leaf() bool { // Find a command/argument/flag by pointer to its field. // // Returns nil if not found. Panics if ptr is not a pointer. -func (n *Node) Find(ptr interface{}) *Node { +func (n *Node) Find(ptr any) *Node { key := reflect.ValueOf(ptr) if key.Kind() != reflect.Ptr { panic("expected a pointer") @@ -433,7 +433,7 @@ func (f *Flag) FormatPlaceHolder() string { return placeholderHelper.PlaceHolder(f) } tail := "" - if f.Value.IsSlice() && f.Value.Tag.Sep != -1 { + if f.Value.IsSlice() && f.Value.Tag.Sep != -1 && f.Tag.Type == "" { tail += string(f.Value.Tag.Sep) + "..." } if f.PlaceHolder != "" { @@ -446,7 +446,7 @@ func (f *Flag) FormatPlaceHolder() string { return f.Default + tail } if f.Value.IsMap() { - if f.Value.Tag.MapSep != -1 { + if f.Value.Tag.MapSep != -1 && f.Tag.Type == "" { tail = string(f.Value.Tag.MapSep) + "..." } return "KEY=VALUE" + tail diff --git a/vendor/github.com/alecthomas/kong/options.go b/vendor/github.com/alecthomas/kong/options.go index 3bc991b9511..6263202b65d 100644 --- a/vendor/github.com/alecthomas/kong/options.go +++ b/vendor/github.com/alecthomas/kong/options.go @@ -79,7 +79,7 @@ type dynamicCommand struct { help string group string tags []string - cmd interface{} + cmd any } // DynamicCommand registers a dynamically constructed command with the root of the CLI. @@ -87,7 +87,7 @@ type dynamicCommand struct { // This is useful for command-line structures that are extensible via user-provided plugins. // // "tags" is a list of extra tag strings to parse, in the form :"". -func DynamicCommand(name, help, group string, cmd interface{}, tags ...string) Option { +func DynamicCommand(name, help, group string, cmd any, 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) @@ -156,7 +156,7 @@ func KindMapper(kind reflect.Kind, mapper Mapper) Option { } // ValueMapper registers a mapper to a field value. -func ValueMapper(ptr interface{}, mapper Mapper) Option { +func ValueMapper(ptr any, mapper Mapper) Option { return OptionFunc(func(k *Kong) error { k.registry.RegisterValue(ptr, mapper) return nil @@ -191,7 +191,7 @@ func Writers(stdout, stderr io.Writer) Option { // AfterApply(...) error // // Called before validation/assignment, and immediately after validation/assignment, respectively. -func Bind(args ...interface{}) Option { +func Bind(args ...any) Option { return OptionFunc(func(k *Kong) error { k.bindings.add(args...) return nil @@ -201,7 +201,7 @@ func Bind(args ...interface{}) Option { // BindTo allows binding of implementations to interfaces. // // BindTo(impl, (*iface)(nil)) -func BindTo(impl, iface interface{}) Option { +func BindTo(impl, iface any) Option { return OptionFunc(func(k *Kong) error { k.bindings.addTo(impl, iface) return nil @@ -212,11 +212,11 @@ func BindTo(impl, iface interface{}) Option { // // The provider function must have the signature: // -// func() (interface{}, error) +// func() (any, error) // // This is useful when the Run() function of different commands require different values that may // not all be initialisable from the main() function. -func BindToProvider(provider interface{}) Option { +func BindToProvider(provider any) Option { return OptionFunc(func(k *Kong) error { return k.bindings.addProvider(provider) }) diff --git a/vendor/github.com/alecthomas/kong/resolver.go b/vendor/github.com/alecthomas/kong/resolver.go index dca4309f7ff..29be1b9189f 100644 --- a/vendor/github.com/alecthomas/kong/resolver.go +++ b/vendor/github.com/alecthomas/kong/resolver.go @@ -14,15 +14,15 @@ type Resolver interface { Validate(app *Application) error // Resolve the value for a Flag. - Resolve(context *Context, parent *Path, flag *Flag) (interface{}, error) + Resolve(context *Context, parent *Path, flag *Flag) (any, error) } // ResolverFunc is a convenience type for non-validating Resolvers. -type ResolverFunc func(context *Context, parent *Path, flag *Flag) (interface{}, error) +type ResolverFunc func(context *Context, parent *Path, flag *Flag) (any, error) var _ Resolver = ResolverFunc(nil) -func (r ResolverFunc) Resolve(context *Context, parent *Path, flag *Flag) (interface{}, error) { //nolint: revive +func (r ResolverFunc) Resolve(context *Context, parent *Path, flag *Flag) (any, error) { //nolint: revive return r(context, parent, flag) } func (r ResolverFunc) Validate(app *Application) error { return nil } //nolint: revive @@ -31,12 +31,12 @@ func (r ResolverFunc) Validate(app *Application) error { return nil } //nolint: // // Flag names are used as JSON keys indirectly, by tring snake_case and camelCase variants. func JSON(r io.Reader) (Resolver, error) { - values := map[string]interface{}{} + values := map[string]any{} err := json.NewDecoder(r).Decode(&values) if err != nil { return nil, err } - var f ResolverFunc = func(context *Context, parent *Path, flag *Flag) (interface{}, error) { + var f ResolverFunc = func(context *Context, parent *Path, flag *Flag) (any, error) { name := strings.ReplaceAll(flag.Name, "-", "_") snakeCaseName := snakeCase(flag.Name) raw, ok := values[name] @@ -47,7 +47,7 @@ func JSON(r io.Reader) (Resolver, error) { } raw = values for _, part := range strings.Split(name, ".") { - if values, ok := raw.(map[string]interface{}); ok { + if values, ok := raw.(map[string]any); ok { raw, ok = values[part] if !ok { return nil, nil diff --git a/vendor/github.com/alecthomas/kong/scanner.go b/vendor/github.com/alecthomas/kong/scanner.go index c8a8bd60dbb..262d16f1cfe 100644 --- a/vendor/github.com/alecthomas/kong/scanner.go +++ b/vendor/github.com/alecthomas/kong/scanner.go @@ -41,7 +41,7 @@ func (t TokenType) String() string { // Token created by Scanner. type Token struct { - Value interface{} + Value any Type TokenType } @@ -171,7 +171,7 @@ func (s *Scanner) PopValue(context string) (Token, error) { // PopValueInto pops a value token into target or returns an error. // // "context" is used to assist the user if the value can not be popped, eg. "expected value but got " -func (s *Scanner) PopValueInto(context string, target interface{}) error { +func (s *Scanner) PopValueInto(context string, target any) error { t, err := s.PopValue(context) if err != nil { return err @@ -204,13 +204,13 @@ func (s *Scanner) Peek() Token { } // Push an untyped Token onto the front of the Scanner. -func (s *Scanner) Push(arg interface{}) *Scanner { +func (s *Scanner) Push(arg any) *Scanner { s.PushToken(Token{Value: arg}) return s } // PushTyped pushes a typed token onto the front of the Scanner. -func (s *Scanner) PushTyped(arg interface{}, typ TokenType) *Scanner { +func (s *Scanner) PushTyped(arg any, typ TokenType) *Scanner { s.PushToken(Token{Value: arg, Type: typ}) return s } diff --git a/vendor/github.com/alecthomas/kong/tag.go b/vendor/github.com/alecthomas/kong/tag.go index 226171b6b78..a2bc4a978ff 100644 --- a/vendor/github.com/alecthomas/kong/tag.go +++ b/vendor/github.com/alecthomas/kong/tag.go @@ -48,6 +48,7 @@ type Tag struct { Vars Vars Prefix string // Optional prefix on anonymous structs. All sub-flags will have this prefix. EnvPrefix string + XorPrefix string // Optional prefix on XOR/AND groups. Embed bool Aliases []string Negatable string @@ -268,6 +269,7 @@ func hydrateTag(t *Tag, typ reflect.Type) error { //nolint: gocyclo } t.Prefix = t.Get("prefix") t.EnvPrefix = t.Get("envprefix") + t.XorPrefix = t.Get("xorprefix") t.Embed = t.Has("embed") if t.Has("negatable") { if !isBool && !isBoolPtr { diff --git a/vendor/modules.txt b/vendor/modules.txt index b77e3b0dd9e..967642c60f9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -115,7 +115,7 @@ github.com/AzureAD/microsoft-authentication-library-for-go/apps/public # github.com/IBM/sarama v1.43.3 ## explicit; go 1.19 github.com/IBM/sarama -# github.com/alecthomas/kong v1.6.0 +# github.com/alecthomas/kong v1.6.1 ## explicit; go 1.20 github.com/alecthomas/kong # github.com/alecthomas/participle/v2 v2.1.1