From 62c16bceaa04be0b8997d23eb4bc3a4583c0a752 Mon Sep 17 00:00:00 2001 From: Bartosz Spyrko-Smietanko Date: Fri, 4 Jul 2025 15:24:03 +0200 Subject: [PATCH] [JBEAP-30446] Use ANSI codes to erase the line in the console --- dist/common/src/main/licenses/licenses.xml | 11 ++++ .../base/org/jboss/prospero/main/module.xml | 1 + dist/standalone-galleon-pack/pom.xml | 5 ++ dist/wildfly-galleon-pack/pom.xml | 5 ++ pom.xml | 7 +++ prospero-cli/pom.xml | 5 ++ .../org/wildfly/prospero/cli/CliConsole.java | 52 +++++++++---------- .../org/wildfly/prospero/cli/CliMain.java | 7 +-- .../galleon/DownloadsCallbackAdapter.java | 4 +- 9 files changed, 66 insertions(+), 31 deletions(-) diff --git a/dist/common/src/main/licenses/licenses.xml b/dist/common/src/main/licenses/licenses.xml index a86188d47..68dd1ac90 100644 --- a/dist/common/src/main/licenses/licenses.xml +++ b/dist/common/src/main/licenses/licenses.xml @@ -320,6 +320,17 @@ + + org.fusesource.jansi + jansi + + + Apache License 2.0 + http://www.apache.org/licenses/LICENSE-2.0 + repo + + + org.jboss staxmapper diff --git a/dist/common/src/main/resources/modules/system/layers/base/org/jboss/prospero/main/module.xml b/dist/common/src/main/resources/modules/system/layers/base/org/jboss/prospero/main/module.xml index 5fc921d2a..1d44f135c 100644 --- a/dist/common/src/main/resources/modules/system/layers/base/org/jboss/prospero/main/module.xml +++ b/dist/common/src/main/resources/modules/system/layers/base/org/jboss/prospero/main/module.xml @@ -55,6 +55,7 @@ + diff --git a/dist/standalone-galleon-pack/pom.xml b/dist/standalone-galleon-pack/pom.xml index df098729c..a89afedd3 100644 --- a/dist/standalone-galleon-pack/pom.xml +++ b/dist/standalone-galleon-pack/pom.xml @@ -133,6 +133,11 @@ + + org.fusesource.jansi + jansi + + info.picocli picocli diff --git a/dist/wildfly-galleon-pack/pom.xml b/dist/wildfly-galleon-pack/pom.xml index eb3d76887..e2eab119a 100644 --- a/dist/wildfly-galleon-pack/pom.xml +++ b/dist/wildfly-galleon-pack/pom.xml @@ -119,6 +119,11 @@ + + org.fusesource.jansi + jansi + + info.picocli picocli diff --git a/pom.xml b/pom.xml index 6d524f357..b90bef308 100644 --- a/pom.xml +++ b/pom.xml @@ -63,6 +63,7 @@ 6.0.4.Final 6.10.0.202406032230-r 2.18.2 + 2.4.2 2.1.19.Final 2.0.1.Final 2.2.1.Final @@ -260,6 +261,12 @@ ${version.org.codehaus.plexus-utils} + + org.fusesource.jansi + jansi + ${version.org.fusesource.jansi} + + org.jboss staxmapper diff --git a/prospero-cli/pom.xml b/prospero-cli/pom.xml index 7e707adfa..86e7e069a 100644 --- a/prospero-cli/pom.xml +++ b/prospero-cli/pom.xml @@ -25,6 +25,11 @@ com.networknt json-schema-validator + + org.fusesource.jansi + jansi + + org.wildfly.prospero prospero-common diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliConsole.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliConsole.java index b984ef027..51ae8dde7 100644 --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliConsole.java +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliConsole.java @@ -24,12 +24,13 @@ import java.util.Optional; import java.util.Scanner; -import org.apache.commons.lang3.StringUtils; +import org.fusesource.jansi.AnsiConsole; import org.wildfly.prospero.api.Console; import org.wildfly.prospero.api.ProvisioningProgressEvent; import org.wildfly.prospero.api.ArtifactChange; import picocli.CommandLine; +import static org.fusesource.jansi.Ansi.ansi; import static org.jboss.galleon.Constants.TRACK_CONFIGS; import static org.jboss.galleon.Constants.TRACK_LAYOUT_BUILD; import static org.jboss.galleon.Constants.TRACK_PACKAGES; @@ -39,21 +40,16 @@ import static org.wildfly.prospero.galleon.GalleonEnvironment.TRACK_RESOLVING_VERSIONS; @SuppressWarnings("PMD.TooManyStaticImports") -public class CliConsole implements Console { +public class CliConsole implements Console,AutoCloseable { - private static final int MAX_LENGTH = 120; + private static final int MAX_LENGTH = AnsiConsole.getTerminalWidth() == 0 ? 120 : AnsiConsole.getTerminalWidth(); + protected static final String DOTS_SEPARATOR = "..."; private static class ProgressLogger { private final String starting; private final String completed; private final String progress; - ProgressLogger(String starting, String completed, String progress) { - this.starting = starting; - this.completed = completed; - this.progress = progress; - } - ProgressLogger(String starting, String completed) { this.starting = starting; this.completed = completed; @@ -71,27 +67,28 @@ String progress() { } } - private class Cli { - int lastLength; + private class Cli implements AutoCloseable { PrintStream out; Cli(PrintStream out) { + AnsiConsole.systemInstall(); this.out = out; } - synchronized void print(String msg) { - final String eraser = StringUtils.repeat(' ', this.lastLength); - out.print("\r" + eraser + "\r"); - lastLength = msg.length(); + synchronized void print(String msg) { + out.print(ansi().cursorToColumn(0).eraseLine()); out.print(msg); } synchronized void println(String msg) { - final String eraser = StringUtils.repeat(' ', this.lastLength); - out.print("\r" + eraser + "\r"); - lastLength = msg.length(); + out.print(ansi().cursorToColumn(0).eraseLine()); out.println(msg); } + + @Override + public void close() { + AnsiConsole.systemUninstall(); + } } private static HashMap loggers = new HashMap<>(); @@ -120,14 +117,12 @@ public void progressUpdate(ProvisioningProgressEvent update) { final String item; if (update.isSlowPhase()) { - item = " " + CliMessages.MESSAGES.installProgressWait() + "..."; + item = " " + CliMessages.MESSAGES.installProgressWait() + DOTS_SEPARATOR; } else { item = update.getCurrentItem(); } final String progressMsg; - final String details = item == null ? "" : item; - if (update.getTotal() > 0) { progressMsg = String.format(" %d/%d(%.0f%%) ", update.getCompleted(), update.getTotal(), update.getProgress()); } else { @@ -135,12 +130,13 @@ public void progressUpdate(ProvisioningProgressEvent update) { } final String text; - if (logger.progress.length() + progressMsg.length() > MAX_LENGTH) { + final String details = item == null ? "" : item; + int textLength = logger.progress.length() + progressMsg.length(); + if (textLength > MAX_LENGTH) { text = (logger.progress() + progressMsg).substring(0, MAX_LENGTH); - } else if (logger.progress.length() + progressMsg.length() + details.length() > MAX_LENGTH) { - int used = logger.progress.length() + progressMsg.length(); - int left = MAX_LENGTH - used; - text = logger.progress() + progressMsg + "..." + details.substring(details.length() - left); + } else if (textLength + details.length() > MAX_LENGTH) { + int left = MAX_LENGTH - textLength - DOTS_SEPARATOR.length(); + text = logger.progress() + progressMsg + DOTS_SEPARATOR + details.substring(details.length() - left); } else { text = logger.progress() + progressMsg + details; } @@ -262,4 +258,8 @@ public void printf(String text, String... args) { } } + @Override + public void close() { + cli.close(); + } } diff --git a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java index 72f4f59e8..ec10d468c 100644 --- a/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java +++ b/prospero-cli/src/main/java/org/wildfly/prospero/cli/CliMain.java @@ -136,9 +136,10 @@ private static void enableDebugLogging() { } static int execute(String[] args) { - CliConsole console = new CliConsole(); - CommandLine commandLine = createCommandLine(console, args); - return commandLine.execute(args); + try (CliConsole console = new CliConsole()) { + CommandLine commandLine = createCommandLine(console, args); + return commandLine.execute(args); + } } static void logException(Exception e) { diff --git a/prospero-common/src/main/java/org/wildfly/prospero/galleon/DownloadsCallbackAdapter.java b/prospero-common/src/main/java/org/wildfly/prospero/galleon/DownloadsCallbackAdapter.java index b59212064..babc7c2db 100644 --- a/prospero-common/src/main/java/org/wildfly/prospero/galleon/DownloadsCallbackAdapter.java +++ b/prospero-common/src/main/java/org/wildfly/prospero/galleon/DownloadsCallbackAdapter.java @@ -26,7 +26,6 @@ import org.wildfly.prospero.api.Console; import org.wildfly.prospero.api.ProvisioningProgressEvent; -import java.io.File; import java.util.HashSet; import static org.wildfly.prospero.galleon.GalleonEnvironment.TRACK_JB_ARTIFACTS_RESOLVE; @@ -97,7 +96,8 @@ public void transferSucceeded(TransferEvent event) { ProsperoLogger.ROOT_LOGGER.debug("Downloaded artifact: " + item); } - final int fileNameIndex = item.lastIndexOf(File.separator); + // note the fileName has Unix separators regardless of the actual OS + final int fileNameIndex = item.lastIndexOf("/"); item = item.substring(fileNameIndex + 1); if (console != null) { if ("maven-metadata.xml".equals(item)) {