diff --git a/go.mod b/go.mod index 811110efb9..81d0a22829 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/regclient/regclient v0.11.5 github.com/sirupsen/logrus v1.10.2 github.com/stretchr/testify v1.12.1 - github.com/urfave/cli/v3 v3.12.0 + github.com/urfave/cli/v3 v3.13.0 go.uber.org/zap v1.28.0 golang.org/x/mod v0.41.0 k8s.io/api v0.37.0 diff --git a/go.sum b/go.sum index 0ff6efba02..9316959730 100644 --- a/go.sum +++ b/go.sum @@ -230,8 +230,8 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/ulikunitz/xz v0.5.15 h1:9DNdB5s+SgV3bQ2ApL10xRc35ck0DuIX/isZvIk+ubY= github.com/ulikunitz/xz v0.5.15/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= -github.com/urfave/cli/v3 v3.12.0 h1:p2iMu5yeXB+ORzD1AAqwP2kHV9Q6QObnwyQXFFdnXYQ= -github.com/urfave/cli/v3 v3.12.0/go.mod h1:vXn6HxPNccJSzQr2QvwVncOKrgYGIHU0HY5h8B2nQj4= +github.com/urfave/cli/v3 v3.13.0 h1:Dr6jqMfIyyFsRVn7Nz5mqLsMY+ZMpfh3a0aMs+umPVY= +github.com/urfave/cli/v3 v3.13.0/go.mod h1:vXn6HxPNccJSzQr2QvwVncOKrgYGIHU0HY5h8B2nQj4= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ= diff --git a/vendor/github.com/urfave/cli/v3/command.go b/vendor/github.com/urfave/cli/v3/command.go index 02f9f76658..21faf1859a 100644 --- a/vendor/github.com/urfave/cli/v3/command.go +++ b/vendor/github.com/urfave/cli/v3/command.go @@ -82,6 +82,10 @@ type Command struct { InvalidFlagAccessHandler InvalidFlagAccessFunc `json:"-"` // Boolean to hide this command from help or completion Hidden bool `json:"hidden"` + // Deprecation message for this command. If non-empty, a warning is + // printed to ErrWriter when the command is invoked. Setting it does not + // hide the command; set Hidden as well for that. + Deprecated string `json:"deprecated"` // List of all authors who contributed (string or fmt.Stringer) // TODO: ~string | fmt.Stringer when interface unions are available Authors []any `json:"authors"` diff --git a/vendor/github.com/urfave/cli/v3/command_parse.go b/vendor/github.com/urfave/cli/v3/command_parse.go index a4d943848e..74a7db013b 100644 --- a/vendor/github.com/urfave/cli/v3/command_parse.go +++ b/vendor/github.com/urfave/cli/v3/command_parse.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" "unicode" + "unicode/utf8" ) const ( @@ -133,7 +134,7 @@ func (cmd *Command) parseFlags(args Args) (Args, error) { if firstArg[1] == '-' { numMinuses++ shortOptionHandling = false - } else if !unicode.IsLetter(rune(firstArg[1])) { + } else if firstRune, _ := utf8.DecodeRuneInString(firstArg[1:]); !unicode.IsLetter(firstRune) { // this is not a flag tracef("parseFlags not a unicode letter. Stop parsing") posArgs = append(posArgs, rargs...) diff --git a/vendor/github.com/urfave/cli/v3/command_run.go b/vendor/github.com/urfave/cli/v3/command_run.go index 34398f8e98..8e9da80c22 100644 --- a/vendor/github.com/urfave/cli/v3/command_run.go +++ b/vendor/github.com/urfave/cli/v3/command_run.go @@ -332,6 +332,8 @@ func (cmd *Command) run(ctx context.Context, osArgs []string) (_ context.Context // First, resolve the chain of nested commands up to the parent. cmdChain := commandChain(cmd) + printDeprecationWarnings(cmdChain) + // Run ArgValidator from the nearest ancestor that sets one. if validator := findArgValidator(cmd); validator != nil { if err := validator(ctx, cmd); err != nil { @@ -421,6 +423,32 @@ func commandChain(cmd *Command) []*Command { return cmdChain } +// printDeprecationWarnings writes a warning to the root ErrWriter for each +// deprecated command in the chain and for each deprecated flag that has been +// set, whether on the command line or from one of its Sources. +func printDeprecationWarnings(cmdChain []*Command) { + w := cmdChain[0].ErrWriter + warned := map[Flag]struct{}{} + for _, cmd := range cmdChain { + if cmd.Deprecated != "" { + fmt.Fprintf(w, "Command %q is deprecated, %s\n", cmd.Name, cmd.Deprecated) + } + for _, fl := range cmd.appliedFlags { + if _, inSet := cmd.setFlags[fl]; !inSet { + continue + } + if _, done := warned[fl]; done { + continue + } + if df, ok := fl.(DeprecatedFlag); ok && df.GetDeprecated() != "" { + warned[fl] = struct{}{} + name := fl.Names()[0] + fmt.Fprintf(w, "Flag %s%s has been deprecated, %s\n", prefixFor(name), name, df.GetDeprecated()) + } + } + } +} + func findArgValidator(cmd *Command) ArgValidatorFunc { for c := cmd; c != nil; c = c.parent { if c.ArgValidator != nil { diff --git a/vendor/github.com/urfave/cli/v3/docs.go b/vendor/github.com/urfave/cli/v3/docs.go index 88461386b8..30c053ca81 100644 --- a/vendor/github.com/urfave/cli/v3/docs.go +++ b/vendor/github.com/urfave/cli/v3/docs.go @@ -5,10 +5,11 @@ import ( "os" "runtime" "strings" + "unicode/utf8" ) func prefixFor(name string) (prefix string) { - if len(name) == 1 { + if utf8.RuneCountInString(name) == 1 { prefix = "-" } else { prefix = "--" diff --git a/vendor/github.com/urfave/cli/v3/flag.go b/vendor/github.com/urfave/cli/v3/flag.go index 9dbe0199ef..f3a9fb54ab 100644 --- a/vendor/github.com/urfave/cli/v3/flag.go +++ b/vendor/github.com/urfave/cli/v3/flag.go @@ -118,6 +118,13 @@ type RequiredFlag interface { IsRequired() bool } +// DeprecatedFlag is an interface that allows us to mark flags as deprecated +type DeprecatedFlag interface { + // GetDeprecated returns the deprecation message, or an empty string + // if the flag is not deprecated + GetDeprecated() string +} + // DocGenerationFlag is an interface that allows documentation generation for the flag type DocGenerationFlag interface { // TakesValue returns true if the flag takes a value, otherwise false diff --git a/vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go b/vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go index d57225dc17..c58770ebf7 100644 --- a/vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go +++ b/vendor/github.com/urfave/cli/v3/flag_bool_with_inverse.go @@ -18,6 +18,7 @@ type BoolWithInverseFlag struct { Sources ValueSourceChain `json:"-"` // sources to load flag value from Required bool `json:"required"` // whether the flag is required or not Hidden bool `json:"hidden"` // whether to hide the flag in help output + Deprecated string `json:"deprecated"` // deprecation message, if set a warning is printed when the flag is set Local bool `json:"local"` // whether the flag needs to be applied to subcommands as well Value bool `json:"defaultValue"` // default value for this flag if not set by from any source Destination *bool `json:"-"` // destination pointer for value when set @@ -83,10 +84,6 @@ func (bif *BoolWithInverseFlag) inversePrefix() string { } func (bif *BoolWithInverseFlag) PreParse() error { - count := bif.Config.Count - if count == nil { - count = &bif.count - } dest := bif.Destination if dest == nil { dest = new(bool) @@ -94,7 +91,7 @@ func (bif *BoolWithInverseFlag) PreParse() error { *dest = bif.Value bif.value = &boolValue{ destination: dest, - count: count, + count: bif.Config.Count, } // Validate the given default or values set from external sources as well @@ -153,6 +150,7 @@ func (bif *BoolWithInverseFlag) Set(name, val string) error { } bif.nset = true } + bif.count++ if bif.Validator != nil { return bif.Validator(bif.value.Get().(bool)) @@ -244,6 +242,11 @@ func (bif *BoolWithInverseFlag) GetDefaultText() string { return boolValue{}.ToString(bif.Value) } +// GetDeprecated returns the deprecation message of the flag +func (bif *BoolWithInverseFlag) GetDeprecated() string { + return bif.Deprecated +} + // GetCategory returns the category of the flag func (bif *BoolWithInverseFlag) GetCategory() string { return bif.Category diff --git a/vendor/github.com/urfave/cli/v3/flag_impl.go b/vendor/github.com/urfave/cli/v3/flag_impl.go index e829d6814e..beea60136a 100644 --- a/vendor/github.com/urfave/cli/v3/flag_impl.go +++ b/vendor/github.com/urfave/cli/v3/flag_impl.go @@ -63,6 +63,7 @@ type FlagBase[T any, C any, VC ValueCreator[T, C]] struct { Sources ValueSourceChain `json:"-"` // sources to load flag value from Required bool `json:"required"` // whether the flag is required or not Hidden bool `json:"hidden"` // whether to hide the flag in help output + Deprecated string `json:"deprecated"` // deprecation message, if set a warning is printed when the flag is set Local bool `json:"local"` // whether the flag needs to be applied to subcommands as well Value T `json:"defaultValue"` // default value for this flag if not set by from any source Destination *T `json:"-"` // destination pointer for value when set @@ -267,6 +268,11 @@ func (f *FlagBase[T, C, V]) IsVisible() bool { return !f.Hidden } +// GetDeprecated returns the deprecation message of the flag +func (f *FlagBase[T, C, V]) GetDeprecated() string { + return f.Deprecated +} + // GetCategory returns the category of the flag func (f *FlagBase[T, C, V]) GetCategory() string { return f.Category diff --git a/vendor/github.com/urfave/cli/v3/flag_map_impl.go b/vendor/github.com/urfave/cli/v3/flag_map_impl.go index cb65903b92..dfe8f09781 100644 --- a/vendor/github.com/urfave/cli/v3/flag_map_impl.go +++ b/vendor/github.com/urfave/cli/v3/flag_map_impl.go @@ -13,6 +13,7 @@ type MapBase[T any, C any, VC ValueCreator[T, C]] struct { dict *map[string]T hasBeenSet bool value Value + trimKeySpace bool multiValueConfig multiValueParsingConfig } @@ -24,9 +25,16 @@ func (i MapBase[T, C, VC]) Create(val map[string]T, p *map[string]T, c C) Value var t T np := new(T) var vc VC + // The key is always a string, so it answers to StringConfig.TrimSpace just + // like the value does. + trimKeySpace := false + if sc, ok := any(c).(StringConfig); ok { + trimKeySpace = sc.TrimSpace + } return &MapBase[T, C, VC]{ - dict: p, - value: vc.Create(t, np, c), + dict: p, + value: vc.Create(t, np, c), + trimKeySpace: trimKeySpace, } } @@ -81,6 +89,9 @@ func (i *MapBase[T, C, VC]) Set(value string) error { if !ok { return fmt.Errorf("item %q is missing separator %q", item, keyValueSeparator) } + if i.trimKeySpace { + key = strings.TrimSpace(key) + } if err := i.value.Set(value); err != nil { return err } diff --git a/vendor/github.com/urfave/cli/v3/godoc-current.txt b/vendor/github.com/urfave/cli/v3/godoc-current.txt index dc41e1bd8b..ce70dbc0cc 100644 --- a/vendor/github.com/urfave/cli/v3/godoc-current.txt +++ b/vendor/github.com/urfave/cli/v3/godoc-current.txt @@ -357,6 +357,7 @@ type BoolWithInverseFlag struct { Sources ValueSourceChain `json:"-"` // sources to load flag value from Required bool `json:"required"` // whether the flag is required or not Hidden bool `json:"hidden"` // whether to hide the flag in help output + Deprecated string `json:"deprecated"` // deprecation message, if set a warning is printed when the flag is set Local bool `json:"local"` // whether the flag needs to be applied to subcommands as well Value bool `json:"defaultValue"` // default value for this flag if not set by from any source Destination *bool `json:"-"` // destination pointer for value when set @@ -383,6 +384,9 @@ func (bif *BoolWithInverseFlag) GetCategory() string func (bif *BoolWithInverseFlag) GetDefaultText() string GetDefaultText returns the default text for this flag +func (bif *BoolWithInverseFlag) GetDeprecated() string + GetDeprecated returns the deprecation message of the flag + func (bif *BoolWithInverseFlag) GetEnvVars() []string GetEnvVars returns the env vars for this flag @@ -519,6 +523,10 @@ type Command struct { InvalidFlagAccessHandler InvalidFlagAccessFunc `json:"-"` // Boolean to hide this command from help or completion Hidden bool `json:"hidden"` + // Deprecation message for this command. If non-empty, a warning is + // printed to ErrWriter when the command is invoked. Setting it does not + // hide the command; set Hidden as well for that. + Deprecated string `json:"deprecated"` // List of all authors who contributed (string or fmt.Stringer) // TODO: ~string | fmt.Stringer when interface unions are available Authors []any `json:"authors"` @@ -879,6 +887,13 @@ type Countable interface { Countable is an interface to enable detection of flag values which support repetitive flags +type DeprecatedFlag interface { + // GetDeprecated returns the deprecation message, or an empty string + // if the flag is not deprecated + GetDeprecated() string +} + DeprecatedFlag is an interface that allows us to mark flags as deprecated + type DocGenerationFlag interface { // TakesValue returns true if the flag takes a value, otherwise false TakesValue() bool @@ -1007,6 +1022,7 @@ type FlagBase[T any, C any, VC ValueCreator[T, C]] struct { Sources ValueSourceChain `json:"-"` // sources to load flag value from Required bool `json:"required"` // whether the flag is required or not Hidden bool `json:"hidden"` // whether to hide the flag in help output + Deprecated string `json:"deprecated"` // deprecation message, if set a warning is printed when the flag is set Local bool `json:"local"` // whether the flag needs to be applied to subcommands as well Value T `json:"defaultValue"` // default value for this flag if not set by from any source Destination *T `json:"-"` // destination pointer for value when set @@ -1038,6 +1054,9 @@ func (f *FlagBase[T, C, V]) GetCategory() string func (f *FlagBase[T, C, V]) GetDefaultText() string GetDefaultText returns the default text for this flag +func (f *FlagBase[T, C, V]) GetDeprecated() string + GetDeprecated returns the deprecation message of the flag + func (f *FlagBase[T, C, V]) GetEnvVars() []string GetEnvVars returns the env vars for this flag diff --git a/vendor/modules.txt b/vendor/modules.txt index 382e1f5af5..9cc47f41d3 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -415,7 +415,7 @@ github.com/ulikunitz/xz github.com/ulikunitz/xz/internal/hash github.com/ulikunitz/xz/internal/xlog github.com/ulikunitz/xz/lzma -# github.com/urfave/cli/v3 v3.12.0 +# github.com/urfave/cli/v3 v3.13.0 ## explicit; go 1.22 github.com/urfave/cli/v3 # github.com/x448/float16 v0.8.4