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);