From 67e41336f0a6aa565d3dc3b9a4ba2cee9e0c98fc Mon Sep 17 00:00:00 2001 From: hogejo Date: Fri, 29 Nov 2024 23:19:07 +0100 Subject: [PATCH 1/5] Avoid printing extra new lines at the end of usage --- .../jcommander/DefaultUsageFormatter.java | 10 +++-- .../java/com/beust/jcommander/JCommander.java | 4 +- .../jcommander/DefaultUsageFormatterTest.java | 44 ++++++++++++++++++- .../jcommander/OutputForwardingConsole.java | 29 ++++++++++++ .../UnixStyleUsageFormatterTest.java | 9 +++- 5 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 src/test/java/com/beust/jcommander/OutputForwardingConsole.java diff --git a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java index 4456103d3..0e9796db6 100644 --- a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java +++ b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java @@ -40,7 +40,7 @@ public DefaultUsageFormatter(JCommander commander) { public final void usage(String commandName) { StringBuilder sb = new StringBuilder(); usage(commandName, sb); - commander.getConsole().println(sb.toString()); + commander.getConsole().print(sb.toString()); } /** @@ -270,13 +270,18 @@ public void appendCommands(StringBuilder out, int indentCount, int descriptionIn return; out.append(indent + " Commands:\n"); - + boolean firstCommand = true; // The magic value 3 is the number of spaces between the name of the option and its description for (Map.Entry commands : commander.getRawCommands().entrySet()) { Object arg = commands.getValue().getObjects().get(0); Parameters p = arg.getClass().getAnnotation(Parameters.class); if (p == null || !p.hidden()) { + if (!firstCommand) { + out.append("\n"); + } else { + firstCommand = false; + } JCommander.ProgramName progName = commands.getKey(); String dispName = progName.getDisplayName(); String commandDescription = Optional.ofNullable(getCommandDescription(progName.getName())) @@ -289,7 +294,6 @@ public void appendCommands(StringBuilder out, int indentCount, int descriptionIn // Options for this command JCommander jc = commander.findCommandByAlias(progName.getName()); jc.getUsageFormatter().usage(out, indent + s(6)); - out.append("\n"); } } } diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index a6d36e71f..d67404c44 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -1096,7 +1096,7 @@ public void setProgramName(String name, String... aliases) { public void usage() { StringBuilder sb = new StringBuilder(); usageFormatter.usage(sb); - getConsole().println(sb.toString()); + getConsole().print(sb.toString()); } /** @@ -1105,7 +1105,7 @@ public void usage() { public void usage(String commandName) { StringBuilder sb = new StringBuilder(); usageFormatter.usage(commandName, sb); - getConsole().println(sb.toString()); + getConsole().print(sb.toString()); } /** diff --git a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java index 6146909b5..1f27e2a20 100644 --- a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java +++ b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java @@ -5,8 +5,8 @@ import org.testng.Assert; import org.testng.annotations.Test; -import java.util.*; import java.util.ResourceBundle; +import java.util.*; @Test public class DefaultUsageFormatterTest { @@ -28,6 +28,39 @@ private enum TestEnum1 { private enum TestEnum2 { } + @Test + public void testUsage() { + class MainParameters { + @Parameter(names = {"-a", "--a", "--a-parameter"}, description = "a parameter") + public int a; + } + @Parameters(commandNames = "one", commandDescription = "one command") + class OneCommand { + @Parameter(names = {"-b", "--b", "--b-parameter"}, description = "b parameter") + public int b; + } + JCommander jc = JCommander.newBuilder() + .addObject(new MainParameters()) + .addCommand(new OneCommand()) + .build(); + StringBuilder output = new StringBuilder(); + jc.setConsole(new OutputForwardingConsole(output)); + jc.usage(); + String expected = "Usage:
[options] [command] [command options]\n" + + " Options:\n" + + " -a, --a, --a-parameter\n" + + " a parameter\n" + + " Default: 0\n" + + " Commands:\n" + + " one one command\n" + + " Usage: one [options]\n" + + " Options:\n" + + " -b, --b, --b-parameter\n" + + " b parameter\n" + + " Default: 0\n"; + Assert.assertEquals(output.toString(), expected); + } + @Test public void testOutputFormat() { class ArgsTemplate { @@ -341,7 +374,14 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); c.getUsageFormatter().usage(sb); - Assert.assertTrue(sb.toString().contains("command a parameters\n\n b")); + String expected = "Usage:
[command] [command options]\n" + + " Commands:\n" + + " a command a\n" + + " Usage: a command a parameters\n" + + "\n" + + " b command b\n" + + " Usage: b command b parameters\n"; + Assert.assertEquals(sb.toString(), expected); } @Test diff --git a/src/test/java/com/beust/jcommander/OutputForwardingConsole.java b/src/test/java/com/beust/jcommander/OutputForwardingConsole.java new file mode 100644 index 000000000..a1f7e5b31 --- /dev/null +++ b/src/test/java/com/beust/jcommander/OutputForwardingConsole.java @@ -0,0 +1,29 @@ +package com.beust.jcommander; + +import com.beust.jcommander.internal.Console; + +public class OutputForwardingConsole implements Console { + + public final StringBuilder output; + + public OutputForwardingConsole(StringBuilder output) { + this.output = output; + } + + @Override + public void print(String msg) { + output.append(msg); + } + + @Override + public void println(String msg) { + print(msg); + output.append("\n"); + } + + @Override + public char[] readPassword(boolean echoInput) { + throw new UnsupportedOperationException(); + } + +} diff --git a/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java b/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java index 31d55ee4c..2bb37840a 100644 --- a/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java +++ b/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java @@ -331,7 +331,14 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); jc.getUsageFormatter().usage(sb); - Assert.assertTrue(sb.toString().contains("command a parameters\n\n b")); + String expected = "Usage:
[command] [command options]\n" + + " Commands:\n" + + " a command a\n" + + " Usage: a command a parameters\n" + + "\n" + + " b command b\n" + + " Usage: b command b parameters\n"; + Assert.assertEquals(sb.toString(), expected); } @Test From 24d842122301d23f9d889146fa2b1bb2222bc276 Mon Sep 17 00:00:00 2001 From: hogejo Date: Fri, 29 Nov 2024 23:29:32 +0100 Subject: [PATCH 2/5] Remove extra lines between commands --- .../com/beust/jcommander/DefaultUsageFormatter.java | 7 +------ .../beust/jcommander/DefaultUsageFormatterTest.java | 13 ++++++++++++- .../jcommander/UnixStyleUsageFormatterTest.java | 1 - 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java index 0e9796db6..99e8ef8ea 100644 --- a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java +++ b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java @@ -270,18 +270,13 @@ public void appendCommands(StringBuilder out, int indentCount, int descriptionIn return; out.append(indent + " Commands:\n"); - boolean firstCommand = true; + // The magic value 3 is the number of spaces between the name of the option and its description for (Map.Entry commands : commander.getRawCommands().entrySet()) { Object arg = commands.getValue().getObjects().get(0); Parameters p = arg.getClass().getAnnotation(Parameters.class); if (p == null || !p.hidden()) { - if (!firstCommand) { - out.append("\n"); - } else { - firstCommand = false; - } JCommander.ProgramName progName = commands.getKey(); String dispName = progName.getDisplayName(); String commandDescription = Optional.ofNullable(getCommandDescription(progName.getName())) diff --git a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java index 1f27e2a20..1da3c8398 100644 --- a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java +++ b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java @@ -39,9 +39,15 @@ class OneCommand { @Parameter(names = {"-b", "--b", "--b-parameter"}, description = "b parameter") public int b; } + @Parameters(commandNames = "two", commandDescription = "two command") + class TwoCommand { + @Parameter(names = {"-c", "--c", "--c-parameter"}, description = "c parameter") + public int c; + } JCommander jc = JCommander.newBuilder() .addObject(new MainParameters()) .addCommand(new OneCommand()) + .addCommand(new TwoCommand()) .build(); StringBuilder output = new StringBuilder(); jc.setConsole(new OutputForwardingConsole(output)); @@ -57,6 +63,12 @@ class OneCommand { + " Options:\n" + " -b, --b, --b-parameter\n" + " b parameter\n" + + " Default: 0\n" + + " two two command\n" + + " Usage: two [options]\n" + + " Options:\n" + + " -c, --c, --c-parameter\n" + + " c parameter\n" + " Default: 0\n"; Assert.assertEquals(output.toString(), expected); } @@ -378,7 +390,6 @@ class ArgCommandB { + " Commands:\n" + " a command a\n" + " Usage: a command a parameters\n" - + "\n" + " b command b\n" + " Usage: b command b parameters\n"; Assert.assertEquals(sb.toString(), expected); diff --git a/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java b/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java index 2bb37840a..f8fe4f20f 100644 --- a/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java +++ b/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java @@ -335,7 +335,6 @@ class ArgCommandB { + " Commands:\n" + " a command a\n" + " Usage: a command a parameters\n" - + "\n" + " b command b\n" + " Usage: b command b parameters\n"; Assert.assertEquals(sb.toString(), expected); From a644c0bd392402a0ad23090e438d3384a1368d0e Mon Sep 17 00:00:00 2001 From: hogejo Date: Sun, 1 Dec 2024 12:34:23 +0100 Subject: [PATCH 3/5] Add extra blank lines before options, commands and between commands --- .../com/beust/jcommander/DefaultUsageFormatter.java | 8 ++++++++ .../beust/jcommander/DefaultUsageFormatterTest.java | 12 ++++++++++-- .../jcommander/UnixStyleUsageFormatterTest.java | 6 ++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java index 99e8ef8ea..30d7cb7b9 100644 --- a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java +++ b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java @@ -169,6 +169,7 @@ public void appendMainLine(StringBuilder out, boolean hasOptions, boolean hasCom public void appendAllParametersDetails(StringBuilder out, int indentCount, String indent, List sortedParameters) { if (sortedParameters.size() > 0) { + out.append("\n"); out.append(indent).append(" Options:\n"); } @@ -269,14 +270,21 @@ public void appendCommands(StringBuilder out, int indentCount, int descriptionIn if (hasOnlyHiddenCommands) return; + out.append("\n"); out.append(indent + " Commands:\n"); + boolean firstCommand = true; // The magic value 3 is the number of spaces between the name of the option and its description for (Map.Entry commands : commander.getRawCommands().entrySet()) { Object arg = commands.getValue().getObjects().get(0); Parameters p = arg.getClass().getAnnotation(Parameters.class); if (p == null || !p.hidden()) { + if (!firstCommand) { + out.append("\n"); + } else { + firstCommand = false; + } JCommander.ProgramName progName = commands.getKey(); String dispName = progName.getDisplayName(); String commandDescription = Optional.ofNullable(getCommandDescription(progName.getName())) diff --git a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java index 1da3c8398..f18b51254 100644 --- a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java +++ b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java @@ -53,19 +53,24 @@ class TwoCommand { jc.setConsole(new OutputForwardingConsole(output)); jc.usage(); String expected = "Usage:
[options] [command] [command options]\n" + + "\n" + " Options:\n" + " -a, --a, --a-parameter\n" + " a parameter\n" + " Default: 0\n" + + "\n" + " Commands:\n" + " one one command\n" + " Usage: one [options]\n" + + "\n" + " Options:\n" + " -b, --b, --b-parameter\n" + " b parameter\n" + " Default: 0\n" + + "\n" + " two two command\n" + " Usage: two [options]\n" + + "\n" + " Options:\n" + " -c, --c, --c-parameter\n" + " c parameter\n" @@ -109,6 +114,7 @@ class ArgsTemplate { // verify String expected = "Usage:
[options]\n" + + "\n" + " Options:\n" + " --a, -a\n" + " Default: 0\n" @@ -358,7 +364,7 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); c.getUsageFormatter().usage(sb); - Assert.assertTrue(sb.toString().contains("[command options]\n Commands:")); + Assert.assertTrue(sb.toString().contains("[command options]\n\n Commands:")); } @Test @@ -387,9 +393,11 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); c.getUsageFormatter().usage(sb); String expected = "Usage:
[command] [command options]\n" + + "\n" + " Commands:\n" + " a command a\n" + " Usage: a command a parameters\n" + + "\n" + " b command b\n" + " Usage: b command b parameters\n"; Assert.assertEquals(sb.toString(), expected); @@ -424,7 +432,7 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); c.getUsageFormatter().usage(sb); - Assert.assertTrue(sb.toString().contains("command a parameters\n Commands:")); + Assert.assertTrue(sb.toString().contains("command a parameters\n\n Commands:")); Assert.assertTrue(sb.toString().contains("command b\n Usage:")); } diff --git a/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java b/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java index f8fe4f20f..15bdae640 100644 --- a/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java +++ b/src/test/java/com/beust/jcommander/UnixStyleUsageFormatterTest.java @@ -302,7 +302,7 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); jc.getUsageFormatter().usage(sb); - Assert.assertTrue(sb.toString().contains("[command options]\n Commands:")); + Assert.assertTrue(sb.toString().contains("[command options]\n\n Commands:")); } @Test @@ -332,9 +332,11 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); jc.getUsageFormatter().usage(sb); String expected = "Usage:
[command] [command options]\n" + + "\n" + " Commands:\n" + " a command a\n" + " Usage: a command a parameters\n" + + "\n" + " b command b\n" + " Usage: b command b parameters\n"; Assert.assertEquals(sb.toString(), expected); @@ -370,7 +372,7 @@ class ArgCommandB { StringBuilder sb = new StringBuilder(); jc.getUsageFormatter().usage(sb); - Assert.assertTrue(sb.toString().contains("command a parameters\n Commands:")); + Assert.assertTrue(sb.toString().contains("command a parameters\n\n Commands:")); Assert.assertTrue(sb.toString().contains("command b\n Usage:")); } From 8774cbae47f1fe88ce7edbdc8e0377a4b48978a5 Mon Sep 17 00:00:00 2001 From: hogejo Date: Sun, 1 Dec 2024 14:44:27 +0100 Subject: [PATCH 4/5] Rename OutputForwardingConsole to StringBuilderConsole --- .../java/com/beust/jcommander/DefaultUsageFormatterTest.java | 2 +- ...OutputForwardingConsole.java => StringBuilderConsole.java} | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) rename src/test/java/com/beust/jcommander/{OutputForwardingConsole.java => StringBuilderConsole.java} (78%) diff --git a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java index f18b51254..041d30d1b 100644 --- a/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java +++ b/src/test/java/com/beust/jcommander/DefaultUsageFormatterTest.java @@ -50,7 +50,7 @@ class TwoCommand { .addCommand(new TwoCommand()) .build(); StringBuilder output = new StringBuilder(); - jc.setConsole(new OutputForwardingConsole(output)); + jc.setConsole(new StringBuilderConsole(output)); jc.usage(); String expected = "Usage:
[options] [command] [command options]\n" + "\n" diff --git a/src/test/java/com/beust/jcommander/OutputForwardingConsole.java b/src/test/java/com/beust/jcommander/StringBuilderConsole.java similarity index 78% rename from src/test/java/com/beust/jcommander/OutputForwardingConsole.java rename to src/test/java/com/beust/jcommander/StringBuilderConsole.java index a1f7e5b31..36148bb25 100644 --- a/src/test/java/com/beust/jcommander/OutputForwardingConsole.java +++ b/src/test/java/com/beust/jcommander/StringBuilderConsole.java @@ -2,11 +2,11 @@ import com.beust.jcommander.internal.Console; -public class OutputForwardingConsole implements Console { +public class StringBuilderConsole implements Console { public final StringBuilder output; - public OutputForwardingConsole(StringBuilder output) { + public StringBuilderConsole(StringBuilder output) { this.output = output; } From 4b1422c20b14793c695b5dffaefdf6e87ac5ec33 Mon Sep 17 00:00:00 2001 From: hogejo Date: Sun, 1 Dec 2024 14:47:03 +0100 Subject: [PATCH 5/5] Append newline character instead of string --- .../jcommander/DefaultUsageFormatter.java | 20 +++++++++---------- .../jcommander/UnixStyleUsageFormatter.java | 2 +- .../jcommander/StringBuilderConsole.java | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java index 30d7cb7b9..1d564d679 100644 --- a/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java +++ b/src/main/java/com/beust/jcommander/DefaultUsageFormatter.java @@ -67,7 +67,7 @@ public final void usage(String commandName, StringBuilder out, String indent) { if (description != null) { out.append(indent).append(description); - out.append("\n"); + out.append('\n'); } jc.getUsageFormatter().usage(out, indent); } @@ -154,7 +154,7 @@ public void appendMainLine(StringBuilder out, boolean hasOptions, boolean hasCom mainLine.append(" ").append(commander.getMainParameter().getDescription().getDescription()); } wrapDescription(out, indentCount, mainLine.toString()); - out.append("\n"); + out.append('\n'); } /** @@ -169,7 +169,7 @@ public void appendMainLine(StringBuilder out, boolean hasOptions, boolean hasCom public void appendAllParametersDetails(StringBuilder out, int indentCount, String indent, List sortedParameters) { if (sortedParameters.size() > 0) { - out.append("\n"); + out.append('\n'); out.append(indent).append(" Options:\n"); } @@ -183,7 +183,7 @@ public void appendAllParametersDetails(StringBuilder out, int indentCount, Strin .append(" ") .append(parameter.required() ? "* " : " ") .append(pd.getNames()) - .append("\n"); + .append('\n'); if (hasDescription) { wrapDescription(out, indentCount, s(indentCount) + description); @@ -242,7 +242,7 @@ public void appendAllParametersDetails(StringBuilder out, int indentCount, Strin out.append(possibleValues); } } - out.append("\n"); + out.append('\n'); } } @@ -270,10 +270,10 @@ public void appendCommands(StringBuilder out, int indentCount, int descriptionIn if (hasOnlyHiddenCommands) return; - out.append("\n"); + out.append('\n'); out.append(indent + " Commands:\n"); - boolean firstCommand = true; + var firstCommand = true; // The magic value 3 is the number of spaces between the name of the option and its description for (Map.Entry commands : commander.getRawCommands().entrySet()) { Object arg = commands.getValue().getObjects().get(0); @@ -281,7 +281,7 @@ public void appendCommands(StringBuilder out, int indentCount, int descriptionIn if (p == null || !p.hidden()) { if (!firstCommand) { - out.append("\n"); + out.append('\n'); } else { firstCommand = false; } @@ -292,7 +292,7 @@ public void appendCommands(StringBuilder out, int indentCount, int descriptionIn .orElse(""); String description = indent + s(4) + dispName + commandDescription; wrapDescription(out, indentCount + descriptionIndent, description); - out.append("\n"); + out.append('\n'); // Options for this command JCommander jc = commander.findCommandByAlias(progName.getName()); @@ -369,7 +369,7 @@ public void wrapDescription(StringBuilder out, int indent, int currentLineIndent current++; } } else { - out.append("\n").append(s(indent)).append(word).append(" "); + out.append('\n').append(s(indent)).append(word).append(" "); current = indent + word.length() + 1; } } diff --git a/src/main/java/com/beust/jcommander/UnixStyleUsageFormatter.java b/src/main/java/com/beust/jcommander/UnixStyleUsageFormatter.java index e0a169009..16e8c955c 100644 --- a/src/main/java/com/beust/jcommander/UnixStyleUsageFormatter.java +++ b/src/main/java/com/beust/jcommander/UnixStyleUsageFormatter.java @@ -102,7 +102,7 @@ public void appendAllParametersDetails(StringBuilder out, int indentCount, Strin // The magic value 3 is the number of spaces between the name of the option and its description // in DefaultUsageFormatter#appendCommands(..) wrapDescription(out, indentCount + prefixIndent - 3, initialLinePrefixLength, description); - out.append("\n"); + out.append('\n'); } } } diff --git a/src/test/java/com/beust/jcommander/StringBuilderConsole.java b/src/test/java/com/beust/jcommander/StringBuilderConsole.java index 36148bb25..39aab03d5 100644 --- a/src/test/java/com/beust/jcommander/StringBuilderConsole.java +++ b/src/test/java/com/beust/jcommander/StringBuilderConsole.java @@ -18,7 +18,7 @@ public void print(String msg) { @Override public void println(String msg) { print(msg); - output.append("\n"); + output.append('\n'); } @Override