Skip to content

Commit

Permalink
Excludes hidden options, params, and subcommands from man page genera…
Browse files Browse the repository at this point in the history
…tion

Fixes: #1063
  • Loading branch information
bdemers committed May 26, 2020
1 parent d1b9a30 commit 2f6de1c
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ static int generateManPage(Config config, CommandSpec... specs) throws IOExcepti
// recursively create man pages for subcommands
for (CommandLine sub : spec.subcommands().values()) {
CommandSpec subSpec = sub.getCommandSpec();
if (done.contains(subSpec)) {continue;}
if (done.contains(subSpec) || subSpec.usageMessage().hidden()) {continue;}
done.add(subSpec);
result = generateManPage(config, subSpec);
if (result != CommandLine.ExitCode.OK) {
Expand Down Expand Up @@ -381,6 +381,14 @@ static void genOptions(PrintWriter pw, CommandSpec spec) {
IParameterRenderer parameterRenderer = spec.commandLine().getHelp().createDefaultParameterRenderer();

List<OptionSpec> options = new ArrayList<OptionSpec>(spec.options()); // options are stored in order of declaration

// remove hidden options
for (Iterator<OptionSpec> iter = options.iterator(); iter.hasNext();) {
if (iter.next().hidden()) {
iter.remove();
}
}

List<ArgGroupSpec> groups = optionListGroups(spec);
for (ArgGroupSpec group : groups) { options.removeAll(group.options()); }

Expand Down Expand Up @@ -441,12 +449,14 @@ private static void writeOption(PrintWriter pw, IOptionRenderer optionRenderer,
}

private static void writePositional(PrintWriter pw, PositionalParamSpec positional, IParameterRenderer parameterRenderer, IParamLabelRenderer paramLabelRenderer) {
pw.println();
Text[][] rows = parameterRenderer.render(positional, paramLabelRenderer, COLOR_SCHEME);
pw.printf("%s::%n", join(", ", rows[0][1], rows[0][3]));
pw.printf(" %s%n", rows[0][4]);
for (int i = 1; i < rows.length; i++) {
pw.printf("+%n%s%n", rows[i][4]);
if (!positional.hidden()) {
pw.println();
Text[][] rows = parameterRenderer.render(positional, paramLabelRenderer, COLOR_SCHEME);
pw.printf("%s::%n", join(", ", rows[0][1], rows[0][3]));
pw.printf(" %s%n", rows[0][4]);
for (int i = 1; i < rows.length; i++) {
pw.printf("+%n%s%n", rows[i][4]);
}
}
}

Expand Down Expand Up @@ -481,6 +491,15 @@ static void genPositionalArgs(PrintWriter pw, CommandSpec spec) {
}

static void genCommands(PrintWriter pw, CommandSpec spec) {

// remove hidden subcommands
Map<String, CommandLine> subCommands = new LinkedHashMap<String, CommandLine>(spec.subcommands());
for (Iterator<Map.Entry<String, CommandLine>> iter = subCommands.entrySet().iterator(); iter.hasNext();) {
if (iter.next().getValue().getCommandSpec().usageMessage().hidden()) {
iter.remove();
}
}

if (spec.subcommands().isEmpty()) {
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@

public class ManPageGeneratorTest {

@Test
public void main() {
}

@Test
public void generateManPage() throws IOException {
@Command(name = "myapp", mixinStandardHelpOptions = true,
Expand Down Expand Up @@ -153,6 +149,53 @@ public void setVerbosity(boolean[] verbosity) {
assertEquals(expected, sw.toString());
}

@Test
public void testHidden() throws IOException {

@Command(name = "a-sub", mixinStandardHelpOptions = true, description = "A sub command")
class ASubCommand {
@Option(names = "input-a")
String inputA;
}

@Command(name = "hidden-sub", mixinStandardHelpOptions = true, hidden = true)
class HiddenSubCommand {
@Option(names = "input-b")
String inputB;
}

@Command(name = "testHidden", mixinStandardHelpOptions = true,
version = {
"Versioned Command 1.0",
"Picocli " + picocli.CommandLine.VERSION,
"JVM: ${java.version} (${java.vendor} ${java.vm.name} ${java.vm.version})",
"OS: ${os.name} ${os.version} ${os.arch}"},
description = "This app does great things.",
subcommands = { ASubCommand.class, HiddenSubCommand.class }

)
class MyApp {
@Option(names = {"-o", "--output"}, description = "Output location full path.")
File outputFolder;

@Option(names = {"--hidden-test"}, hidden = true)
File hidden;

@Parameters(hidden = true)
List<String> values;
}

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw); //System.out, true
ManPageGenerator.writeSingleManPage(pw, new CommandLine(new MyApp()).getCommandSpec());
pw.flush();

String expected = read("/testHidden.manpage.adoc");
expected = expected.replace("\r\n", "\n");
expected = expected.replace("\n", System.getProperty("line.separator"));
assertEquals(expected, sw.toString());
}

private String read(String resource) throws IOException {
return readAndClose(getClass().getResourceAsStream(resource));
}
Expand Down
60 changes: 60 additions & 0 deletions picocli-codegen/src/test/resources/testHidden.manpage.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// tag::picocli-generated-full-manpage[]
// tag::picocli-generated-man-section-header[]
:doctype: manpage
:revnumber: Versioned Command 1.0
:manmanual: TestHidden Manual
:mansource: Versioned Command 1.0
:man-linkstyle: pass:[blue R < >]
= testHidden(1)

// end::picocli-generated-man-section-header[]

// tag::picocli-generated-man-section-name[]
== Name

testHidden - This app does great things.

// end::picocli-generated-man-section-name[]

// tag::picocli-generated-man-section-synopsis[]
== Synopsis

*testHidden* [*-hV*] [*-o*=_<outputFolder>_] [COMMAND]

// end::picocli-generated-man-section-synopsis[]

// tag::picocli-generated-man-section-description[]
== Description

This app does great things.

// end::picocli-generated-man-section-description[]

// tag::picocli-generated-man-section-options[]
== Options

*-h*, *--help*::
Show this help message and exit.

*-o*, *--output*=_<outputFolder>_::
Output location full path.

*-V*, *--version*::
Print version information and exit.

// end::picocli-generated-man-section-options[]

// tag::picocli-generated-man-section-arguments[]
== Arguments

// end::picocli-generated-man-section-arguments[]

// tag::picocli-generated-man-section-commands[]
== Commands

*a-sub*::
A sub command

// end::picocli-generated-man-section-commands[]

// end::picocli-generated-full-manpage[]

0 comments on commit 2f6de1c

Please sign in to comment.