feat: add Deprecated field to flags and commands - #2429
Open
anandghegde wants to merge 1 commit into
Open
anandghegde wants to merge 1 commit into
anandghegde wants to merge 1 commit into
Conversation
Setting Deprecated on a flag or command prints a one-line warning to the
root ErrWriter when the flag is set (on the command line or from its
Sources) or the command is invoked, and execution continues. The message
format mirrors cobra and pflag:
Command "old" is deprecated, use "new" instead
Flag --old-flag has been deprecated, use --new-flag instead
Deprecated flags and commands are not hidden from help; set Hidden for
that.
anandghegde
force-pushed
the
feat/deprecated-flags-commands
branch
from
September 15, 2026 16:40
9d64ae6 to
a971b40
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What type of PR is this?
What this PR does / why we need it:
When a CLI renames a flag or command, there is currently no built-in way to keep the old name working while telling users to switch. Apps have to write their own
Action/Beforehooks, and those don't cover env-sourced values in a uniform way. cobra hasCommand.Deprecatedand pflag hasMarkDeprecated. This PR adds the same thing to urfave/cli, using the same message format:Changes by file:
flag_impl.go,flag_bool_with_inverse.go: newDeprecated stringfield and aGetDeprecated()method. AllFlagBasealiases (StringFlag,IntFlag,TextFlag, ...) get it, and so doesBoolWithInverseFlag.flag.go: new optionalDeprecatedFlaginterface, following the same pattern asRequiredFlagandVisibleFlag, so custom flag types can opt in.command.go: newCommand.Deprecated stringfield, next toHidden.command_run.go:printDeprecationWarningsruns once for the command that is actually executed, right beforeArgValidator/Before/flag actions. It walks the command chain from the root down. For each deprecated command it passes through, it writes a warning to the rootErrWriter. It does the same for each deprecated flag found in that command's set flags. Execution then continues as normal.command_test.go:TestCommand_Deprecatedtable test that capturesErrWriter, plus a test checking that the deprecated command's action still runs and still sees the flag value.TestJSONExportCommandexpectations now include the newdeprecatedJSON key.docs/v3/examples/flags/advanced.md,docs/v3/examples/subcommands/basics.md: short "Deprecated Flags" / "Deprecated Commands" sections with runnable examples.godoc-current.txt,testdata/godoc-v3.x.txt: regenerated withmake generate+make v3approve.Design choices:
Sourcescounts as "set" (IsSet()is true, flag actions run), so a deprecated flag warns whether it was set on the command line or through an env var, file, etc. A flag that just keeps its default value does not warn.Hiddenfield, so the two stay independent: setHidden: trueas well if you want the entry hidden. That way settingDeprecatednever removes anything from help or completion as a side effect. This is noted in the field docs and in the docs examples. Happy to switch to auto-hiding if maintainers prefer cobra's behavior.--help,--versionand shell completion print nothing. Parent commands in the chain are checked too, soapp old-group subwarns aboutold-group. A persistent flag that is set on both a parent and a subcommand warns only once.Name, with-or--in front, the same way help output does it (prefixFor). An alias like-oor an inverse form like--no-colorreports the primary name.Which issue(s) this PR fixes:
None filed. This is a feature request, modeled on cobra's
Command.Deprecatedand pflag'sFlagSet.MarkDeprecated.Special notes for your reviewer:
Deprecatedis a new exported field onCommandandFlagBase, so the public API grows (see the godoc diff). Nothing changes unless the field is set.This PR was prepared with help from Claude Code. I reviewed the changes and tested them locally.
Testing
make vetpassesmake test:ok github.com/urfave/cli/v3 coverage: 99.5% of statements. Includes the newTestCommand_Deprecated(12 cases: command, parent command, long/short/alias/inverse-bool flags, env source, persistent flag on a subcommand, set twice warns once,--helpdoes not warn) andTestCommand_DeprecatedStillRunsprintDeprecationWarningscall commented out, and the warn-once case fails with the de-duplication removedmake lint(goimports) andgolangci-lint run ./...(0 issues) passmake check-binary-size: 2.0MB, within the 1.5–2.2MB boundsmake gfmrun FLAGS='--walk docs/v3/':error_count=0 example_count=47(the new examples compile against the local module)make generate,make v3approve: godoc diff contains only the new field, method and interfaceRelease Notes
🤖 Generated with Claude Code
https://claude.ai/code/session_01QBWFWqjbUQGS1c9LsM2bxX