diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index 8871e00f3..0f12398fe 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -1821,6 +1821,12 @@ public CommandLine setExpandAtFiles(boolean expandAtFiles) { * @return text to display after the list of options * @see Help#footer(Object...) */ String[] footer() default {}; + + /** + * Set {@code hidden=true} if this command should not be included in the usage documentation. + * @return whether this command should be excluded from the usage message + */ + boolean hidden() default false; } /** *

@@ -2164,6 +2170,7 @@ private static boolean updateCommandAttributes(Class cls, CommandSpec command if (!commandSpec.isSortOptionsInitialized() && !cmd.sortOptions()) { commandSpec.sortOptions(cmd.sortOptions()); } if (!commandSpec.isShowDefaultValuesInitialized() && cmd.showDefaultValues()) { commandSpec.showDefaultValues(cmd.showDefaultValues()); } if (!commandSpec.isIsHelpCommandInitialized() && cmd.isHelpCommand()) { commandSpec.setHelpCommand(cmd.isHelpCommand()); } + if (!commandSpec.isIsHiddenInitialized() && cmd.hidden() ) { commandSpec.setHidden(cmd.hidden()); } if (!commandSpec.isVersionProviderInitialized() && cmd.versionProvider() != NoVersionProvider.class) { commandSpec.versionProvider(DefaultFactory.createVersionProvider(factory, cmd.versionProvider())); } @@ -2475,6 +2482,7 @@ public static class CommandSpec { private Boolean sortOptions; private Boolean showDefaultValues; private Boolean isHelpCommand; + private Boolean isHidden; private Character requiredOptionMarker; private String headerHeading; private String synopsisHeading; @@ -2790,6 +2798,20 @@ public String[] version() { * @see Command#isHelpCommand() */ public CommandSpec setHelpCommand(boolean newValue) {isHelpCommand = newValue; return this;} + /** + * @return {@code true} when the command is annotated with a {@link Command#hidden} attribute, {@code false} otherwise.o + */ + public boolean isHidden() { return isHidden != null ? isHidden : false; } + + /** + * Set the hidden flag on this command to prevent to add in the help usage text. + * @param value enable or disable the hidden flag + * @see {@link Command#hidden()} + */ + public void setHidden( boolean value ) { + isHidden = value; + } + /** Returns the optional heading preceding the subcommand list. Initialized from {@link Command#commandListHeading()}. {@code "Commands:%n"} by default. */ public String commandListHeading() { return commandListHeading; } @@ -2842,6 +2864,7 @@ public String[] version() { boolean isFooterHeadingInitialized() { return !empty(footerHeading); } boolean isParameterListHeadingInitialized() { return !empty(parameterListHeading); } boolean isOptionListHeadingInitialized() { return !empty(optionListHeading); } + boolean isIsHiddenInitialized() { return isHidden != null; } } /** Models the shared attributes of {@link OptionSpec} and {@link PositionalParamSpec}. * @since 3.0 */ @@ -4408,6 +4431,7 @@ public Help(CommandSpec commandSpec, ColorScheme colorScheme) { public Help addAllSubcommands(Map commands) { if (commands != null) { for (Map.Entry entry : commands.entrySet()) { + if( entry.getValue().getCommandSpec().isHidden() ) continue; addSubcommand(entry.getKey(), entry.getValue()); } } diff --git a/src/test/java/picocli/CommandLineHelpTest.java b/src/test/java/picocli/CommandLineHelpTest.java index 78a719e59..bd03dff0c 100644 --- a/src/test/java/picocli/CommandLineHelpTest.java +++ b/src/test/java/picocli/CommandLineHelpTest.java @@ -3054,4 +3054,23 @@ public void testAutoHelpMixinRunHelpSubcommandWithoutCommand() throws Exception " help Displays help information about the specified command%n"); assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); } + + @Test + public void testUsageTextWithHiddenSubcommand() throws Exception { + @Command(name = "foo", description = "This is a foo sub-command") class Foo { } + @Command(name = "bar", description = "This is a foo sub-command", hidden = true) class Bar { } + @Command(name = "app", abbreviateSynopsis = true) class App { } + + CommandLine app = new CommandLine(new App()) + .addSubcommand("foo", new Foo()) + .addSubcommand("bar", new Bar()); + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + app.usage(new PrintStream(baos)); + + String expected = "Usage: app\n" + + "Commands:\n" + + " foo This is a foo sub-command\n"; + assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + } }