Support intercepting the help message generated by a multiple-subcommand application
See original GitHub issueCurrently, if one has a command-line application with multiple subcommands, and one wants to write a high-level help message to the console, they would write something like this:
String... args = ...;
CommandLine cmd = ...;
cmd.parseWithHandler(new RunLast(), System.out, args);
or if things are a bit more complicated (as is the case for me):
String... args = ...;
CommandLine cmd = ...;
try {
List<CommandLine> parsedArgs = cmd.parse(args);
new RunLast().handleParseResult(parsedArgs, System.out, Ansi.AUTO);
System.exit(0);
} catch (ParameterException exception) {
new DefaultExceptionHandler()
.handleException(exception, System.err, Ansi.AUTO, args);
System.exit(-1);
}
But sadly, this is not quite enough for me, because I need some way of “intercepting” the text sent to System.{out,err}
so that I can assert on the contents of auto-generated help message at unit-test time.
The closest solution I’ve thought of so far is to use PrintWriter
s in place of System.{out,err}
so that, at unit-test time, I can swap out System.{out,err}
with a custom PrintWriter
that diverts the text it receives to a StringWriter
, so that I can query the text directly. But sadly, this doesn’t work because RunLast::handleParseResult
doesn’t have an overload that accepts a PrintWriter
instead of a PrintStream
.
Does picocli have something built-in that would allow me to intercept the auto-generated help message of a command-line application with multiple subcommands?
If not, would providing an overload of IParseResultHandler::handleParseResult
that accepts a PrintWriter
be an idea that the picocli team would be interested in implementing?
Issue Analytics
- State:
- Created 6 years ago
- Comments:17 (7 by maintainers)
I just thought of a way to address your requirements while also reducing the number of arguments passed to the
parseWithHandler(s)
methods (these methods already have too many arguments…)PrintStream
orPrintWriter
(also take an optionalHelp.Ansi
parameter)andExit(int)
to the default handlers that returns a wrapper that invokes the handler first and then callsSystem.exit
with the specified error code. Add this method to the default handlers instead of adding a static method onCommandLine
.User code, like your application, would look like this:
Test code could look like this:
This looks a lot cleaner than the current API and I wish I had thought of it earlier…
This also makes it possible to have much simpler
IParseResultHandler
andIExceptionHandler
interfaces:Unfortunately I can’t think of another way to avoid breaking backwards compatibility than adding additional interfaces with different names. Darn, I really wish we could have had this conversation a week ago! 😃
Yes it certainly was helpful! The user manual is already a bit biggish, so How to test picocli command line applications will likely be a separate article. Thanks again for the great feedback!