From 0254dc3bbf9538153b89bcf401339fab1ba42158 Mon Sep 17 00:00:00 2001 From: arimu1 <19286898+arimu1@users.noreply.github.com> Date: Sat, 22 Aug 2026 11:59:32 +0700 Subject: [PATCH] [CLI-354] Fix HelpFormatter wrapped description indent When remaining pad equals indent, continuation lines dropped the leading indent and padded the right instead, so some wrapped description lines sat one space left of the others. Apply indent when restLen >= indent. --- .../apache/commons/cli/help/TextStyle.java | 2 +- .../commons/cli/help/HelpFormatterTest.java | 33 +++++++++++++++++++ .../commons/cli/help/TextStyleTest.java | 11 +++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/commons/cli/help/TextStyle.java b/src/main/java/org/apache/commons/cli/help/TextStyle.java index fef720f34..02346daae 100644 --- a/src/main/java/org/apache/commons/cli/help/TextStyle.java +++ b/src/main/java/org/apache/commons/cli/help/TextStyle.java @@ -369,7 +369,7 @@ public CharSequence pad(final boolean addIndent, final CharSequence text) { rest = ""; } else { int restLen = maxWidth - text.length(); - if (addIndent && restLen > indent) { + if (addIndent && restLen >= indent) { indentPad = Util.repeatSpace(indent); restLen -= indent; } else { diff --git a/src/test/java/org/apache/commons/cli/help/HelpFormatterTest.java b/src/test/java/org/apache/commons/cli/help/HelpFormatterTest.java index 04041f644..e7b995bca 100644 --- a/src/test/java/org/apache/commons/cli/help/HelpFormatterTest.java +++ b/src/test/java/org/apache/commons/cli/help/HelpFormatterTest.java @@ -340,6 +340,39 @@ void testPrintOptions() throws IOException { assertEquals(expected, actual); } + /** + * Continuation description lines must share the same indent. + * + * @see [CLI-354] HelpFormatter: Description indentation is incorrect + */ + @Test + void testPrintHelpWrappedDescriptionIndent() throws IOException { + final StringBuilder sb = new StringBuilder(); + final TextHelpAppendable serializer = new TextHelpAppendable(sb); + final HelpFormatter formatter = HelpFormatter.builder().setHelpAppendable(serializer).setShowSince(false).get(); + final String description = "an argument passed to the remote command. The value will be wrapped in double quotes " + + "and appended to the command-line. This option can be added multiple times."; + final Options options = new Options().addOption(Option.builder("V").longOpt("argument-value").hasArg().desc(description).get()); + + final List expected = new ArrayList<>(); + expected.add(" usage: cs [-V ]"); + expected.add(""); + expected.add(" header"); + expected.add(""); + expected.add(" Options Description "); + expected.add(" -V, --argument-value an argument passed to the remote command. "); + expected.add(" The value will be wrapped in double quotes"); + expected.add(" and appended to the command-line. This "); + expected.add(" option can be added multiple times. "); + expected.add(""); + expected.add(" footer"); + expected.add(""); + + formatter.printHelp("cs", "header", options, "footer", true); + final List actual = IOUtils.readLines(new StringReader(sb.toString())); + assertEquals(expected, actual); + } + @Test void testSetOptionFormatBuilderTest() { final HelpFormatter.Builder underTest = HelpFormatter.builder(); diff --git a/src/test/java/org/apache/commons/cli/help/TextStyleTest.java b/src/test/java/org/apache/commons/cli/help/TextStyleTest.java index b3e946278..2f18ae3ba 100644 --- a/src/test/java/org/apache/commons/cli/help/TextStyleTest.java +++ b/src/test/java/org/apache/commons/cli/help/TextStyleTest.java @@ -71,6 +71,17 @@ static Stream padTestData() { builder.setAlignment(TextStyle.Alignment.CENTER); lst.add(Arguments.of(builder.get(), " Hello world ", " Hello world ")); + // width equal to text length + indent applies indent on continuation lines + builder.setMaxWidth(16); + builder.setAlignment(TextStyle.Alignment.LEFT); + lst.add(Arguments.of(builder.get(), "Hello world ", " Hello world")); + + builder.setAlignment(TextStyle.Alignment.RIGHT); + lst.add(Arguments.of(builder.get(), " Hello world", " Hello world")); + + builder.setAlignment(TextStyle.Alignment.CENTER); + lst.add(Arguments.of(builder.get(), " Hello world ", " Hello world ")); + // width greater than text length and less than text length + indent creates result of text length + pad builder.setMaxWidth(14); builder.setAlignment(TextStyle.Alignment.LEFT);