diff --git a/README.adoc b/README.adoc index 6f23b32..9dd2569 100644 --- a/README.adoc +++ b/README.adoc @@ -330,9 +330,9 @@ Only the last two versions of Go will be supported. NOTE: For a <>, jump to that section in the TOC or review the http://godoc.org/github.com/DavidGamba/go-getoptions[GoDoc Documentation]. -Option parsing is the act of taking command line arguments and converting them into meaningful structures within the program. +Option parsing is the act of taking command line (CLI) arguments and converting them into meaningful structures within the program. -First declare a getoptions instance: +First declare a `getoptions` instance: [source, go] ---- @@ -472,6 +472,186 @@ func Name(ctx context.Context, opt *getoptions.GetOpt, args []string) error { } ---- +== Automatically generate help + +For a proper extended man page for your program consider link:http://asciidoctor.org/[asciidoctor] that can generate manpages written in the Asciidoc markup. + +For the built-in help, you can add a description to your program: + +- `opt.Self("", "This is a program description")` + +NOTE: When the first argument is empty, it will use the program name from `os.Args[0]`. + +For options help ensure you add option descriptions and argument names. + +- `opt.Description("This is a string option")` +- `opt.ArgName("mystring")` + +The help command needs to be defined after all options, commands and subcommands. + +`opt.HelpCommand("help", opt.Alias("?"))` + +When calling the help command, you get the full help. +Optionally you can print only given sections of the Help. + +For example: + +[source, go] +---- +fmt.Fprintf(os.Stderr, "%s", opt.Help(getoptions.HelpSynopsis)) +---- + +Or through a helper: + +[source, go] +---- +func ForceUnlock(ctx context.Context, opt *getoptions.GetOpt, args []string) error { + lockID, args, err := opt.GetRequiredArg(args) + if err != nil { + return err + } +---- + +In the code above, if there is no argument passed, the `GetRequiredArg` will print an error plus the synopsis: + +---- +ERROR: Missing +SYNOPSIS: + program [--help] +---- + +The error return is `getoptions.ErrorHelpCalled` which signals the help is already printed. +The dispatch error handling can handle this error and not print and additional error message. + + +[source, go] +---- + err = opt.Dispatch(ctx, remaining) + if err != nil { + if errors.Is(err, getoptions.ErrorHelpCalled) { + return 1 + } + fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) + if errors.Is(err, getoptions.ErrorParsing) { + fmt.Fprintf(os.Stderr, "\n"+opt.Help()) + } + return 1 + } + return 0 +---- + +Another helpful error to check for is `getoptions.ErrorParsing`, as shown above, which indicates there was a problem parsing the CLI arguments. +This can be used, to print the help only in cases where the user didn't enter valid CLI options or arguments. + +The built in help shows default values and environment variables when available. + +It separates required parameters from options. + +For example, the following is a script using the built in help: + +---- +$ bt terraform force-unlock help +NAME: + bt terraform force-unlock + +SYNOPSIS: + bt terraform force-unlock [--help|-?] [--profile ] [--quiet] + [--ws ] + +ARGUMENTS: + Lock ID + +OPTIONS: + --help|-? (default: false) + + --profile BT Terraform Profile to use (default: "default", env: AWS_PROFILE) + + --quiet (default: false, env: QUIET) + + --ws Workspace to use (default: "") +---- + +And below is the output of the automated help of a program with multiple commands: + +---- +$ tz help +SYNOPSIS: + tz [--config|-c ] [--format-standard|--format-12-hour|--format-12h] + [--group ] [--help|-?] [--short|-s] [--verbose] [] + +COMMANDS: + cities filter cities list + list list all timezones + version show version + +OPTIONS: + --config|-c Config file (default: "") + + --format-standard|--format-12-hour|--format-12h Use standard 12 hour AM/PM time format (default: false) + + --group Group to show (default: "") + + --help|-? (default: false) + + --short|-s Don't show timezone bars (default: false) + + --verbose Enable logging (default: false, env: TZ_VERBOSE) + +Use 'tz help ' for extra details. +---- + +Any built-in string in `go-getoptions`, like titles, is exposed as a public variable so it can be overridden for internationalization. + +== Autocompletion + +To enable bash autocompletion, add the following line to your bash profile: + +[source,bash] +---- +complete -o default -C my-go-program my-go-program +---- + +For the above to work, the program must be in the PATH. +Otherwise: + +[source,bash] +---- +complete -o default -C "$HOME/go/bin/my-go-program" my-go-program +---- + +To enable zsh autocompletion, add the following line to your zsh profile: + +[source,zsh] +---- +export ZSHELL="true" +autoload -U +X compinit && compinit +autoload -U +X bashcompinit && bashcompinit +complete -o default -C my-go-program my-go-program +---- + +The `ZSHELL="true"` export is required because bash and zsh have different ways of handling autocompletion and there is no reliable way to detect which shell is being used. + +If testing completion in the CLI, you might require to first clean the completion entry that `complete` auto generates when hitting `Tab` twice: + +`complete -r ./my-go-program 2>/dev/null` + +When providing these as scripts that users source but not add into their profile you can use the following `sourceme.bash` script: + +.sourceme.bash +[source,bash] +---- +#!/bin/bash + +# Remove existing entries to ensure the right one is loaded +# This is not required when the completion one liner is loaded in your bashrc. +complete -r ./my-go-program 2>/dev/null + +complete -o default -C "$PWD/my-go-program" my-go-program +---- + +Then when the users go into the directory and run `source sourceme.bash` the autocompletion will be enabled. + + === Boolean options Opposite of default when passed on the command line. @@ -744,7 +924,7 @@ When calling `CommandFn` directly, it is sometimes useful to set the option as c Use cases are for testing and wrappers. [[operation_modes]] -== Operation Modes +== Operation Modes: How to handle single dash '-' options Notice how so far only long options (options starting with double dash `--`) have been mentioned. There are 3 main ways to handle short options (options starting with only one dash `-`). @@ -818,185 +998,6 @@ a|option: `"o"`, argument: `"pt=arg"` footnote:[Argument gets type casted depend |=== -== Automatically generate help - -For a proper extended man page for your program consider link:http://asciidoctor.org/[asciidoctor] that can generate manpages written in the Asciidoc markup. - -For the built-in help, you can add a description to your program: - -- `opt.Self("", "This is a program description")` - -NOTE: When the first argument is empty, it will use the program name from `os.Args[0]`. - -For options help ensure you add option descriptions and argument names. - -- `opt.Description("This is a string option")` -- `opt.ArgName("mystring")` - -The help command needs to be defined after all options, commands and subcommands. - -`opt.HelpCommand("help", opt.Alias("?"))` - -When calling the help command, you get the full help. -Optionally you can print only given sections of the Help. - -For example: - -[source, go] ----- -fmt.Fprintf(os.Stderr, "%s", opt.Help(getoptions.HelpSynopsis)) ----- - -Or through a helper: - -[source, go] ----- -func ForceUnlock(ctx context.Context, opt *getoptions.GetOpt, args []string) error { - lockID, args, err := opt.GetRequiredArg(args) - if err != nil { - return err - } ----- - -In the code above, if there is no argument passed, the `GetRequiredArg` will print an error plus the synopsis: - ----- -ERROR: Missing -SYNOPSIS: - program [--help] ----- - -The error return is `getoptions.ErrorHelpCalled` which signals the help is already printed. -The dispatch error handling can handle this error and not print and additional error message. - - -[source, go] ----- - err = opt.Dispatch(ctx, remaining) - if err != nil { - if errors.Is(err, getoptions.ErrorHelpCalled) { - return 1 - } - fmt.Fprintf(os.Stderr, "ERROR: %s\n", err) - if errors.Is(err, getoptions.ErrorParsing) { - fmt.Fprintf(os.Stderr, "\n"+opt.Help()) - } - return 1 - } - return 0 ----- - -Another helpful error to check for is `getoptions.ErrorParsing`, as shown above, which indicates there was a problem parsing the CLI arguments. -This can be used, to print the help only in cases where the user didn't enter valid CLI options or arguments. - -The built in help shows default values and environment variables when available. - -It separates required parameters from options. - -For example, the following is a script using the built in help: - ----- -$ bt terraform force-unlock help -NAME: - bt terraform force-unlock - -SYNOPSIS: - bt terraform force-unlock [--help|-?] [--profile ] [--quiet] - [--ws ] - -ARGUMENTS: - Lock ID - -OPTIONS: - --help|-? (default: false) - - --profile BT Terraform Profile to use (default: "default", env: AWS_PROFILE) - - --quiet (default: false, env: QUIET) - - --ws Workspace to use (default: "") ----- - -And below is the output of the automated help of a program with multiple commands: - ----- -$ tz help -SYNOPSIS: - tz [--config|-c ] [--format-standard|--format-12-hour|--format-12h] - [--group ] [--help|-?] [--short|-s] [--verbose] [] - -COMMANDS: - cities filter cities list - list list all timezones - version show version - -OPTIONS: - --config|-c Config file (default: "") - - --format-standard|--format-12-hour|--format-12h Use standard 12 hour AM/PM time format (default: false) - - --group Group to show (default: "") - - --help|-? (default: false) - - --short|-s Don't show timezone bars (default: false) - - --verbose Enable logging (default: false, env: TZ_VERBOSE) - -Use 'tz help ' for extra details. ----- - -Any built-in string in `go-getoptions`, like titles, is exposed as a public variable so it can be overridden for internationalization. - -== Autocompletion - -To enable bash autocompletion, add the following line to your bash profile: - -[source,bash] ----- -complete -o default -C my-go-program my-go-program ----- - -For the above to work, the program must be in the PATH. -Otherwise: - -[source,bash] ----- -complete -o default -C "$HOME/go/bin/my-go-program" my-go-program ----- - -To enable zsh autocompletion, add the following line to your zsh profile: - -[source,zsh] ----- -export ZSHELL="true" -autoload -U +X compinit && compinit -autoload -U +X bashcompinit && bashcompinit -complete -o default -C my-go-program my-go-program ----- - -The `ZSHELL="true"` export is required because bash and zsh have different ways of handling autocompletion and there is no reliable way to detect which shell is being used. - -If testing completion in the CLI, you might require to first clean the completion entry that `complete` auto generates when hitting `Tab` twice: - -`complete -r ./my-go-program 2>/dev/null` - -When providing these as scripts that users source but not add into their profile you can use the following `sourceme.bash` script: - -.sourceme.bash -[source,bash] ----- -#!/bin/bash - -# Remove existing entries to ensure the right one is loaded -# This is not required when the completion one liner is loaded in your bashrc. -complete -r ./my-go-program 2>/dev/null - -complete -o default -C "$PWD/my-go-program" my-go-program ----- - -Then when the users go into the directory and run `source sourceme.bash` the autocompletion will be enabled. - == Command behaviour This section describes how the parser resolves ambiguities between the program and the command.