如何指定默认子命令?未提供子命令时如何输出帮助信息?
我来帮你搞定picocli里的这两个需求——指定默认子命令,以及无参时自动打印帮助。你的代码之所以没达到预期,是因为主命令实现了Callable后,无参时会直接执行call方法,而你之前注释里直接调用HelpCommand().run()的方式不对,因为它没有绑定到当前的命令上下文。咱们来看正确的实现方式:
一、指定默认子命令
如果希望用户不输入子命令时自动执行某个特定子命令,直接在主命令的@Command注解里添加defaultSubcommand属性即可。比如你想默认执行ListPlugins子命令,修改后的代码如下:
@Command( name = "tool", mixinStandardHelpOptions = true, subcommands = [ListPlugins::class, RunJob::class, CommandLine.HelpCommand::class], defaultSubcommand = ListPlugins::class // 指定默认触发的子命令 ) class Main : Callable<Int> { override fun call(): Int { // 此时这个call方法不会被触发,因为默认子命令会接管执行逻辑 return 0 } }
这样用户只输入tool而不加子命令时,就会自动执行ListPlugins的业务逻辑。
二、未提供子命令时打印帮助信息
如果你的需求是用户不输入子命令时直接显示主命令的帮助信息,有两种可靠的实现方式:
方式1:将帮助命令设为默认子命令
这是最简单的方案,直接把CommandLine.HelpCommand::class设为默认子命令,无参时自动调用帮助:
@Command( name = "tool", mixinStandardHelpOptions = true, subcommands = [ListPlugins::class, RunJob::class, CommandLine.HelpCommand::class], defaultSubcommand = CommandLine.HelpCommand::class // 默认显示帮助 ) class Main : Callable<Int> { override fun call(): Int { return 0 } }
方式2:在主命令的call方法中手动生成帮助
如果不想依赖默认子命令的设置,也可以在Main的call方法里手动输出帮助信息。这里要注意必须关联当前的命令上下文,不能直接实例化HelpCommand就运行,正确写法如下:
@Command( name = "tool", mixinStandardHelpOptions = true, subcommands = [ListPlugins::class, RunJob::class, CommandLine.HelpCommand::class] ) class Main : Callable<Int> { override fun call(): Int { // 获取当前命令的CommandLine实例,打印完整帮助内容 val cmdLine = CommandLine.getCommandLine(this) ?: return 1 cmdLine.usage(System.out) return 0 } }
这样当用户不输入子命令时,就会执行call方法,输出主命令的帮助,包括所有子命令的列表和参数说明。
内容的提问来源于stack exchange,提问作者expert
相关产品推荐
相关产品推荐

