Draft
Conversation
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.
Reshapes help customization and usage-error handling from the API that exists on
maintoday. The current API hasCommand.UsageFunc func(*Command) stringfor replacing help wholesale,DefaultUsage(*Command) stringfor the built-in formatter, andFlagOption/Command.FlagOptionsfor flag metadata. This PR replaces the string-based help hook with a structured help document, adds a small optionalusagepackage for composing that document, exposes the resolved command throughState.Cmd, and adds an opt-incli.UsageErrorfpath for bad invocations fromExec.The intended default path stays small: most programs still define a command tree and call
ParseAndRun.--helpstill works automatically. The new pieces are for the cases where the built-in help needs light customization, or where anExecfunction needs to say "the command was selected, but the provided args or flag combination are invalid."Closes #4, #14, #15.
Why this refactor
On
main,UsageFuncis all-or-nothing: it returns a final string. That works for replacing the entire help output, but it is awkward for the common case of keeping the default help and adding one section, such as Examples. Callers either need to rebuild the default formatter or concatenate strings aroundDefaultUsage. That also makesDefaultUsageandUsageFunctightly coupled:DefaultUsagedispatches toUsageFunc, so callingDefaultUsagefrom insideUsageFuncrecurses. Passing the built-in help document into the new hook makes composition the default and makes that recursion impossible.Usage errors have a similar ergonomics problem on
main: parse errors happen beforeExec, but many invalid invocations are only obvious insideExec, after flags and positional args are available. Without a first-class usage error, callers have to manually print usage at each call site or treat bad invocation errors the same as runtime failures.cli.UsageErrorfgives command code a small convention: return it for invalid command-line usage, andRunprints the resolved command help before returning the underlying error.State.Cmdis the primitive that makes this work. It givesExecaccess to the resolved command, so code can inspect the command path withs.Cmd.Path()or render help for the selected command withcli.Help(s.Cmd).FlagOptionis renamed toFlagConfigbecause it is a configuration record attached to a flag, not an option in the functional-options sense.New API shape
cli.Help(*Command) usage.Helpbuilds the help document for the resolved command.Command.Help func(*Command, usage.Help) usage.Helpcustomizes help by receiving the built-in document and returning the final document.usageprovides composable blocks:Text,Lines,List,Flags, andCommands.State.Cmdexposes the resolved command insideExec.cli.UsageErrorfmarks invalid command-line usage fromExec;Runprints command help to stderr and returns the underlying error.FlagConfigandCommand.FlagConfigsreplaceFlagOptionandCommand.FlagOptions.Breaking changes
Command.UsageFuncis removed. UseCommand.Help.DefaultUsageandUsageare removed. Usecli.Help(cmd).String()or render the returnedusage.Help.usage.Helpdocuments instead of returning a fully formatted string.FlagOptionis renamed toFlagConfig;Command.FlagOptionsis renamed toCommand.FlagConfigs.Migration examples