[#1066] bugfix: unnamed commands should be processed without errors

This commit is contained in:
Remko Popma
2020-06-07 07:48:30 +09:00
parent 8364ff3f25
commit 4f3c737351
6 changed files with 246 additions and 3 deletions

View File

@@ -344,8 +344,9 @@ public class ManPageGenerator implements Callable<Integer> {
}
private static String makeFileName(CommandSpec spec) {
String result = spec.qualifiedName("-") + ".adoc";
return result.replaceAll("\\s", "_");
return (spec.qualifiedName("-") + ".adoc")
.replaceAll("\\s", "_")
.replace("<main_class>", "main_class");
}
private static void generateSingleManPage(CommandSpec spec, File manpage) throws IOException {

View File

@@ -16,10 +16,10 @@ import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import static org.junit.Assert.*;
@@ -428,4 +428,71 @@ public class ManPageGeneratorTest {
}
}
}
@Command(subcommands = { ManPageGenerator.class})
static class Nameless implements Callable<Integer> {
@Parameters(index = "0")
private File file;
public static void main(String... args) throws Exception {
CommandLine cmd = new CommandLine(new Nameless());
System.exit(cmd.execute(args));
}
@Override
public Integer call() throws Exception {
return 0;
}
}
@Test
public void testNamelessCommand() throws IOException {
File outdir = new File(System.getProperty("java.io.tmpdir"), "manpage" + System.currentTimeMillis());
outdir.mkdir();
File templateDir = new File(outdir, "templates");
int exitCode = new CommandLine(new Nameless())
.execute("gen-manpage", /*"-vv",*/ "--outdir=" + outdir, "--template-dir=" + templateDir);
try {
assertEquals(0, exitCode);
//System.out.println(Arrays.asList(templateDir.listFiles()));
//System.out.println(Arrays.asList(outdir.listFiles()));
String[] files = new String[] {
"main_class.adoc", //
"main_class-gen-manpage.adoc"
};
for (String f : files) {
String expected = read("/manpagegenerator/templates/" + f);
String actual = readAndClose(new FileInputStream(new File(templateDir, f)));
expected = expected.replace("$OUTDIR", outdir.getAbsolutePath().replace('\\', '/'));
assertEquals("/manpagegenerator/templates/" + f, expected, actual);
}
for (String f : files) {
String expected = read("/manpagegenerator/" + f);
String actual = readAndClose(new FileInputStream(new File(outdir, f)));
expected = expected.replace("$VERSION", CommandLine.VERSION);
assertEquals("/manpagegenerator/" + f, expected, actual);
}
} finally {
for (File f : templateDir.listFiles()) {
f.delete();
}
try {
assertTrue(templateDir.getAbsolutePath(), templateDir.delete());
} finally {
for (File f : outdir.listFiles()) {
f.delete();
}
assertTrue(outdir.getAbsolutePath(), outdir.delete());
}
}
}
}

View File

@@ -0,0 +1,86 @@
// tag::picocli-generated-full-manpage[]
// tag::picocli-generated-man-section-header[]
:doctype: manpage
:revnumber: <main class> gen-manpage 4.3.3-SNAPSHOT
:manmanual: <main class> Manual
:mansource: <main class> gen-manpage 4.3.3-SNAPSHOT
:man-linkstyle: pass:[blue R < >]
= <main class>-gen-manpage(1)
// end::picocli-generated-man-section-header[]
// tag::picocli-generated-man-section-name[]
== Name
<main class>-gen-manpage - Generates man pages for all commands in the specified directory.
// end::picocli-generated-man-section-name[]
// tag::picocli-generated-man-section-synopsis[]
== Synopsis
*<main class> gen-manpage* [*-fhVv*] [*-d*=_<outdir>_] [*-t*=_<template-dir>_] [_@<filename>_...]
// end::picocli-generated-man-section-synopsis[]
// tag::picocli-generated-man-section-description[]
== Description
Generates man pages for all commands in the specified directory.
// end::picocli-generated-man-section-description[]
// tag::picocli-generated-man-section-options[]
== Options
*-d*, *--outdir*=_<outdir>_::
Output directory to write the generated AsciiDoc files to. If not specified, files are written to the current directory.
*-t*, *--template-dir*=_<template-dir>_::
Optional directory to write customizable man page template files. If specified, an additional "template" file is created here for each generated manpage AsciiDoc file.
+
Each template file contains `include` directives that import content from the corresponding generated manpage AsciiDoc file in the `--outdir` directory. Text can be added after each include to customize the resulting man page. The resulting man page will be a mixture of generated and manually edited text.
+
These customizable templates are intended to be generated once, and afterwards be manually updated and maintained.
*-v*, *--verbose*::
Specify multiple -v options to increase verbosity.
+
For example, `-v -v -v` or `-vvv`
*-f*, *--[no-]force*::
Overwrite existing man page templates. The default is `--no-force`, meaning processing is aborted and the process exits with status code 4 if a man page template file already exists.
*-h*, *--help*::
Show this help message and exit.
*-V*, *--version*::
Print version information and exit.
// end::picocli-generated-man-section-options[]
// tag::picocli-generated-man-section-arguments[]
== Arguments
[_@<filename>_...]::
One or more argument files containing options.
// end::picocli-generated-man-section-arguments[]
// tag::picocli-generated-man-section-footer[]
== Converting to Man Page Format
[%hardbreaks]
Use the `asciidoctor` tool to convert the generated AsciiDoc files to man pages in roff format:
[%hardbreaks]
`asciidoctor --backend=manpage --source-dir=SOURCE_DIR --destination-dir=DESTINATION *.adoc`
[%hardbreaks]
Point the SOURCE_DIR to either the `--outdir` directory or the `--template-dir` directory. Use some other directory as the DESTINATION.
See https://asciidoctor.org/docs/user-manual/#man-pages
See http://man7.org/linux/man-pages/man7/roff.7.html
// end::picocli-generated-man-section-footer[]
// end::picocli-generated-full-manpage[]

View File

@@ -0,0 +1,49 @@
// tag::picocli-generated-full-manpage[]
// tag::picocli-generated-man-section-header[]
:doctype: manpage
:revnumber:
:manmanual: <main class> Manual
:mansource:
:man-linkstyle: pass:[blue R < >]
= <main class>(1)
// end::picocli-generated-man-section-header[]
// tag::picocli-generated-man-section-name[]
== Name
<main class> -
// end::picocli-generated-man-section-name[]
// tag::picocli-generated-man-section-synopsis[]
== Synopsis
*<main class>* _<file>_ [COMMAND]
// end::picocli-generated-man-section-synopsis[]
// tag::picocli-generated-man-section-description[]
== Description
// end::picocli-generated-man-section-description[]
// tag::picocli-generated-man-section-arguments[]
== Arguments
_<file>_::
// end::picocli-generated-man-section-arguments[]
// tag::picocli-generated-man-section-commands[]
== Commands
*gen-manpage*::
Generates man pages for all commands in the specified directory.
// end::picocli-generated-man-section-commands[]
// end::picocli-generated-full-manpage[]

View File

@@ -0,0 +1,20 @@
:includedir: $OUTDIR
//include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-full-manpage]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-header]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-name]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-synopsis]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-description]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-options]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-arguments]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-commands]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-exit-status]
include::{includedir}/main_class-gen-manpage.adoc[tag=picocli-generated-man-section-footer]

View File

@@ -0,0 +1,20 @@
:includedir: $OUTDIR
//include::{includedir}/main_class.adoc[tag=picocli-generated-full-manpage]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-header]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-name]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-synopsis]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-description]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-options]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-arguments]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-commands]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-exit-status]
include::{includedir}/main_class.adoc[tag=picocli-generated-man-section-footer]