cmd/cue: refactor our use of cobra
Our API in cmd/cue/cmd was somewhat confused;
the New function was only meant to create the root command,
but it also returned an error as it had to do more work upfront.
In particular, it tried to interpret arguments and flags to support:
1) `cue mycmd` being a shortcut to `cue cmd mycmd`
2) `cue help cmd` and `cue help cmd mycmd` loading custom command info
This code was messy and has caused bugs in the past,
such as `cue help` loading the current package unnecessarily (#2161),
or TestHelp being chatty since New could print usage text
before cobra.Command.SetOutput could be called (#1694).
Instead, make New do very little work, and offload the two cases above:
1) Allow the root command to take arbitrary arguments,
meaning that its RunE func is used as a fallback when the first
argument does not match any built-in sub-command like `fix`.
Said RunE func is simply forwarded to `cue cmd`,
which is taught how to load `*_tool.cue` files just like New used to,
to then run the specified command.
2) Add our own custom "help" command, a version of cobra's default
which knows how to load `*_tool.cue` files and add all of their
custom commands when using `cue help cmd [args]`.
For consistency with "help" now being our own command and not cobra's,
make the "-h" or "--help" flag our own, and hide it from the usage text.
We also slightly improve the output from `cue foo` and `cue cmd foo`
when "foo" is not a known built-in nor custom command,
which can be seen from the changes in testdata.
While here, update the version of cobra as well.
Finally, add copious amounts of documentation to the tricky bits,
because it took some digging to figure out how to make it work well.
Note that a bit more cleanup can be done in the other subcommands,
but this CL focuses on "cmd" and "help" as they were the biggest ones.
Also note that we don't change the API for New and Command.Run,
although New always returns a nil error and args are only used by Run,
because it feels like unnecessary churn to break the API right now.
Plus, this refactor is already large enough as it is.
Fixes #1694.
Signed-off-by: Daniel Martí <mvdan@mvdan.cc>
Change-Id: Iabe6e5724e2da9afbab8897fa22b49883e195733
Reviewed-on: https://review.gerrithub.io/c/cue-lang/cue/+/552733
Unity-Result: CUEcueckoo <cueckoo@cuelang.org>
TryBot-Result: CUEcueckoo <cueckoo@cuelang.org>
Reviewed-by: Roger Peppe <rogpeppe@gmail.com>