diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 946f9c793..c271f2ceb 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -1,5 +1,16 @@ # picocli Release Notes +# Picocli 3.0.0-alpha-2 (UNRELEASED) +## Fixed issues + +- [#307] Enhancement: Provide CommandLine.usage(PrintWriter) method for testing and to facilitate migration from commons-cli to picocli. + +## Deprecations +See [3.0.0-alpha-1]()#3.0.0-alpha-1-deprecated) + +## Potential breaking changes +See [3.0.0-alpha-1]()#3.0.0-alpha-1-breaking-changes) + # Picocli 3.0.0-alpha-1 The picocli community is pleased to announce picocli 3.0.0-alpha-1. diff --git a/src/main/java/picocli/CommandLine.java b/src/main/java/picocli/CommandLine.java index 5ab901bb5..3764a1adf 100644 --- a/src/main/java/picocli/CommandLine.java +++ b/src/main/java/picocli/CommandLine.java @@ -15,11 +15,7 @@ */ package picocli; -import java.io.File; -import java.io.FileReader; -import java.io.LineNumberReader; -import java.io.PrintStream; -import java.io.StreamTokenizer; +import java.io.*; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -1261,9 +1257,13 @@ public static void usage(Object command, PrintStream out, Help.ColorScheme color * @param out the printStream to print to * @see #usage(PrintStream, Help.ColorScheme) */ - public void usage(PrintStream out) { - usage(out, Help.Ansi.AUTO); - } + public void usage(PrintStream out) { usage(out, Help.Ansi.AUTO); } + /** + * Delegates to {@link #usage(PrintWriter, Help.Ansi)} with the {@linkplain Help.Ansi#AUTO platform default}. + * @param writer the PrintWriter to print to + * @see #usage(PrintWriter, Help.ColorScheme) + * @since 3.0 */ + public void usage(PrintWriter writer) { usage(writer, Help.Ansi.AUTO); } /** * Delegates to {@link #usage(PrintStream, Help.ColorScheme)} with the {@linkplain Help#defaultColorScheme(CommandLine.Help.Ansi) default color scheme}. @@ -1271,9 +1271,11 @@ public void usage(PrintStream out) { * @param ansi whether the usage message should include ANSI escape codes or not * @see #usage(PrintStream, Help.ColorScheme) */ - public void usage(PrintStream out, Help.Ansi ansi) { - usage(out, Help.defaultColorScheme(ansi)); - } + public void usage(PrintStream out, Help.Ansi ansi) { usage(out, Help.defaultColorScheme(ansi)); } + /** Similar to {@link #usage(PrintStream, Help.Ansi)} but with the specified {@code PrintWriter} instead of a {@code PrintStream}. + * @since 3.0 */ + public void usage(PrintWriter writer, Help.Ansi ansi) { usage(writer, Help.defaultColorScheme(ansi)); } + /** * Prints a usage help message for the annotated command class to the specified {@code PrintStream}. * Delegates construction of the usage help message to the {@link Help} inner class and is equivalent to: @@ -1307,9 +1309,15 @@ public void usage(PrintStream out, Help.Ansi ansi) { * @param colorScheme the {@code ColorScheme} defining the styles for options, parameters and commands when ANSI is enabled */ public void usage(PrintStream out, Help.ColorScheme colorScheme) { - Help help = new Help(getCommandSpec(), colorScheme); - StringBuilder sb = new StringBuilder() - .append(help.headerHeading()) + out.print(usage(new StringBuilder(), new Help(getCommandSpec(), colorScheme))); + } + /** Similar to {@link #usage(PrintStream, Help.ColorScheme)}, but with the specified {@code PrintWriter} instead of a {@code PrintStream}. + * @since 3.0 */ + public void usage(PrintWriter writer, Help.ColorScheme colorScheme) { + writer.print(usage(new StringBuilder(), new Help(getCommandSpec(), colorScheme))); + } + private static StringBuilder usage(StringBuilder sb, Help help) { + return sb.append(help.headerHeading()) .append(help.header()) .append(help.synopsisHeading()) //e.g. Usage: .append(help.synopsis(help.synopsisHeadingLength())) //e.g. <main class> [OPTIONS] <command> [COMMAND-OPTIONS] [ARGUMENTS] @@ -1323,7 +1331,6 @@ public void usage(PrintStream out, Help.ColorScheme colorScheme) { .append(help.commandList()) //e.g. add adds the frup to the frooble .append(help.footerHeading()) .append(help.footer()); - out.print(sb); } /** diff --git a/src/test/java/picocli/CommandLineHelpTest.java b/src/test/java/picocli/CommandLineHelpTest.java index 5f7390995..a43cd204d 100644 --- a/src/test/java/picocli/CommandLineHelpTest.java +++ b/src/test/java/picocli/CommandLineHelpTest.java @@ -2788,7 +2788,7 @@ class App { String expected = String.format("" + "Usage:
[-h]%n" + " -h%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -2802,7 +2802,7 @@ class App { assertTrue(CommandLine.printHelpIfRequested(list, new PrintStream(baos), Help.Ansi.OFF)); String expected = String.format("abc 1.2.3 myversion%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -2815,7 +2815,7 @@ class App { assertFalse(CommandLine.printHelpIfRequested(list, new PrintStream(baos), Help.Ansi.OFF)); String expected = ""; - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Command(name = "top", subcommands = {Sub.class}) @@ -2903,7 +2903,7 @@ public void testAutoHelpMixinUsageHelpOption() throws Exception { "Usage:
[-hV]%n" + " -h, --help Show this help message and exit.%n" + " -V, --version Print version information and exit.%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } } @@ -2920,7 +2920,7 @@ public void testAutoHelpMixinVersionHelpOption() throws Exception { assertTrue(CommandLine.printHelpIfRequested(list, new PrintStream(baos), Help.Ansi.OFF)); String expected = String.format("1.2.3%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } } @@ -2939,7 +2939,7 @@ public void testAutoHelpMixinUsageHelpSubcommandOnAppWithoutSubcommands() throws " -V, --version Print version information and exit.%n" + "Commands:%n" + " help Displays help information about the specified command%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -2956,7 +2956,7 @@ class App implements Runnable{ public void run(){}} " -V, --version Print version information and exit.%n" + "Commands:%n" + " help Displays help information about the specified command%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test public void testHelpSubcommandWithValidCommand() throws Exception { @@ -2968,7 +2968,7 @@ public void testHelpSubcommandWithValidCommand() throws Exception { String expected = String.format("" + "Usage: sub%n" + "This is a subcommand%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -2987,7 +2987,7 @@ class App implements Runnable{ public void run(){}} "Commands:%n" + " sub This is a subcommand%n" + " help Displays help information about the specified command%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -3008,7 +3008,11 @@ class App implements Runnable{ public void run(){}} "%n" + " [COMMAND]... The COMMAND to display the usage help message for.%n" + " -h, --help Show usage help for the help command and exit.%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); + + StringWriter sw = new StringWriter(); + new CommandLine(new App()).getSubcommands().get("help").usage(new PrintWriter(sw)); + assertEquals(expected, sw.toString()); } @Test @@ -3026,7 +3030,11 @@ class App implements Runnable{ public void run(){}} "Commands:%n" + " sub This is a subcommand%n" + " help Displays help information about the specified command%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); + + StringWriter sw = new StringWriter(); + new CommandLine(new App()).usage(new PrintWriter(sw)); + assertEquals(expected, sw.toString()); } @Test @@ -3043,7 +3051,7 @@ public void testUsageTextWithHiddenSubcommand() throws Exception { "Usage: app%n" + "Commands:%n" + " foo This is a visible subcommand%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -3061,7 +3069,7 @@ public void testUsage_NoHeaderIfAllSubcommandHidden() throws Exception { String expected = format("" + "Usage: app%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -3080,7 +3088,7 @@ public void run() { } "Missing required parameters at positions 0..*: FILES%n" + "Usage:
FILES...%n" + " FILES... List of files%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test @@ -3103,7 +3111,7 @@ public void run() { } "Usage:
[-v] FILES...%n" + " FILES... List of files%n" + " -v Print output%n"); - assertEquals(expected, new String(baos.toByteArray(), "UTF-8")); + assertEquals(expected, baos.toString()); } @Test