I encountered this problem when trying to view the Consul help with consul agent --help. Any time a command has a lot of help text I send it to a pager (ex: consul agent --help | less). I will also quite frequently pipe the help output to grep to quickly find the help text for a flag that I know exists, but I may not remember exactly what it expects as a value.
To my surprise, this did not work! I did some digging and found that all help text (and --version output), even when requested by the user, is always sent to stderr.
I looked to see how other users of this library have handled the problem and I found that nomad sets HelpWriter to os.Stdout. This fixes the problem, but introduces a new problem. If a user runs a command with an invalid flag the error message ends up on stdout instead of stderr. This can be very confusing to users when they are trying to run a command with output piped somewhere else, because the error will be hidden.
I believe it is best practice for a CLI to write requested help and version output to stdout, but to send that same output to stderr when it is being printed as a result of an invalid flag or subcommand.
This PR addresses the problem by introducing a second Writer. I believe it is backwards compatible as the new writer is initialized to the value of the existing Writer.
I've seen this problem solved this way in another cli library so I thought it may be applicable here as well.
Problem
I encountered this problem when trying to view the Consul help with
consul agent --help
. Any time a command has a lot of help text I send it to a pager (ex:consul agent --help | less
). I will also quite frequently pipe the help output to grep to quickly find the help text for a flag that I know exists, but I may not remember exactly what it expects as a value.To my surprise, this did not work! I did some digging and found that all help text (and --version output), even when requested by the user, is always sent to
stderr
.I looked to see how other users of this library have handled the problem and I found that
nomad
setsHelpWriter
toos.Stdout
. This fixes the problem, but introduces a new problem. If a user runs a command with an invalid flag the error message ends up onstdout
instead ofstderr
. This can be very confusing to users when they are trying to run a command with output piped somewhere else, because the error will be hidden.I believe it is best practice for a CLI to write requested help and version output to stdout, but to send that same output to stderr when it is being printed as a result of an invalid flag or subcommand.
Solution
This PR addresses the problem by introducing a second
Writer
. I believe it is backwards compatible as the new writer is initialized to the value of the existingWriter
.I've seen this problem solved this way in another cli library so I thought it may be applicable here as well.