diff --git a/cli/src/main/java/de/jplag/cli/CLI.java b/cli/src/main/java/de/jplag/cli/CLI.java index 2b054e8207..a5be417426 100644 --- a/cli/src/main/java/de/jplag/cli/CLI.java +++ b/cli/src/main/java/de/jplag/cli/CLI.java @@ -11,6 +11,7 @@ import de.jplag.JPlag; import de.jplag.JPlagResult; import de.jplag.cli.logger.CliProgressBarProvider; +import de.jplag.cli.logger.CollectedLogger; import de.jplag.cli.logger.CollectedLoggerFactory; import de.jplag.cli.picocli.CliInputHandler; import de.jplag.exceptions.ExitException; @@ -50,6 +51,7 @@ public void executeCli() throws ExitException, IOException { logger.debug("Your version of JPlag is {}", JPlag.JPLAG_VERSION); if (!this.inputHandler.parse()) { + CollectedLogger.setLogLevel(this.inputHandler.getCliOptions().advanced.logLevel); ProgressBarLogger.setProgressBarProvider(new CliProgressBarProvider()); switch (this.inputHandler.getCliOptions().mode) { diff --git a/cli/src/main/java/de/jplag/cli/logger/CliProgressBarProvider.java b/cli/src/main/java/de/jplag/cli/logger/CliProgressBarProvider.java index d21e78211e..db514aabac 100644 --- a/cli/src/main/java/de/jplag/cli/logger/CliProgressBarProvider.java +++ b/cli/src/main/java/de/jplag/cli/logger/CliProgressBarProvider.java @@ -1,5 +1,9 @@ package de.jplag.cli.logger; +import java.util.Set; + +import org.slf4j.event.Level; + import de.jplag.logging.ProgressBar; import de.jplag.logging.ProgressBarProvider; import de.jplag.logging.ProgressBarType; @@ -11,15 +15,21 @@ * A ProgressBar provider, that used the tongfei progress bar library underneath, to show progress bars on the cli. */ public class CliProgressBarProvider implements ProgressBarProvider { + private static final Set allowedLogLevels = Set.of(Level.INFO); + @Override public ProgressBar initProgressBar(ProgressBarType type, int totalSteps) { - if (type.isIdleBar()) { - IdleBar idleBar = new IdleBar(type.getDefaultText()); - idleBar.start(); - return idleBar; + if (allowedLogLevels.contains(CollectedLogger.getLogLevel())) { + if (type.isIdleBar()) { + IdleBar idleBar = new IdleBar(type.getDefaultText()); + idleBar.start(); + return idleBar; + } + me.tongfei.progressbar.ProgressBar progressBar = new ProgressBarBuilder().setTaskName(type.getDefaultText()).setInitialMax(totalSteps) + .setStyle(ProgressBarStyle.ASCII).build(); + return new TongfeiProgressBar(progressBar); + } else { + return new VoidProgressBar(); } - me.tongfei.progressbar.ProgressBar progressBar = new ProgressBarBuilder().setTaskName(type.getDefaultText()).setInitialMax(totalSteps) - .setStyle(ProgressBarStyle.ASCII).build(); - return new TongfeiProgressBar(progressBar); } } diff --git a/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java b/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java index 2c37ec6255..b93e8cacf7 100644 --- a/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java +++ b/cli/src/main/java/de/jplag/cli/logger/CollectedLogger.java @@ -20,10 +20,10 @@ public class CollectedLogger extends AbstractLogger { private static final Level LOG_LEVEL_FOR_EXTERNAL_LIBRARIES = Level.ERROR; private static final int MAXIMUM_MESSAGE_LENGTH = 32; private static final PrintStream TARGET_STREAM = System.out; + private static Level currentLogLevel = Level.INFO; private final transient SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd-hh:mm:ss_SSS"); private final ConcurrentLinkedDeque allErrors = new ConcurrentLinkedDeque<>(); - private final Level currentLogLevel; /** * Indicator whether finalization is in progress. @@ -33,21 +33,10 @@ public class CollectedLogger extends AbstractLogger { /** * Creates a logger with a specific name and level. - * @param currentLogLevel is the current log level. - * @param name is the name of the logger. - */ - CollectedLogger(Level currentLogLevel, String name) { - this.currentLogLevel = currentLogLevel; - this.name = name; - } - - /** - * Creates a logger with a specific name and {@link Level.INFO}. - * @param currentLogLevel is the current log level. * @param name is the name of the logger. */ CollectedLogger(String name) { - this(Level.INFO, name); + this.name = name; } @Override @@ -165,4 +154,12 @@ private void printLogEntry(LogEntry entry) { } TARGET_STREAM.flush(); } + + public static Level getLogLevel() { + return currentLogLevel; + } + + public static void setLogLevel(Level logLevel) { + currentLogLevel = logLevel; + } } diff --git a/cli/src/main/java/de/jplag/cli/logger/VoidProgressBar.java b/cli/src/main/java/de/jplag/cli/logger/VoidProgressBar.java new file mode 100644 index 0000000000..f1453fe392 --- /dev/null +++ b/cli/src/main/java/de/jplag/cli/logger/VoidProgressBar.java @@ -0,0 +1,18 @@ +package de.jplag.cli.logger; + +import de.jplag.logging.ProgressBar; + +/** + * An empty {@link ProgressBar} implementation, used to hide the progress bar depending on the log level. + */ +public class VoidProgressBar implements ProgressBar { + @Override + public void step(int number) { + // does nothing see class description + } + + @Override + public void dispose() { + // does nothing see class description + } +} diff --git a/cli/src/main/java/de/jplag/cli/options/CliOptions.java b/cli/src/main/java/de/jplag/cli/options/CliOptions.java index 0cc7f13260..73f95f91bc 100644 --- a/cli/src/main/java/de/jplag/cli/options/CliOptions.java +++ b/cli/src/main/java/de/jplag/cli/options/CliOptions.java @@ -2,6 +2,8 @@ import java.io.File; +import org.slf4j.event.Level; + import de.jplag.Language; import de.jplag.clustering.ClusteringAlgorithm; import de.jplag.clustering.ClusteringOptions; @@ -101,6 +103,9 @@ public static class Advanced { @Option(names = "--overwrite", description = "Existing result files will be overwritten.") public boolean overwrite = false; + + @Option(names = "--log-level", description = "Set the log level for the cli.") + public Level logLevel = Level.INFO; } public static class Clustering { diff --git a/cli/src/test/java/de/jplag/cli/logger/VoidProgressBarTest.java b/cli/src/test/java/de/jplag/cli/logger/VoidProgressBarTest.java new file mode 100644 index 0000000000..ba4152164c --- /dev/null +++ b/cli/src/test/java/de/jplag/cli/logger/VoidProgressBarTest.java @@ -0,0 +1,49 @@ +package de.jplag.cli.logger; + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.slf4j.event.Level; + +import de.jplag.logging.ProgressBar; +import de.jplag.logging.ProgressBarType; + +class VoidProgressBarTest { + @Test + void testVoidProgressBarBehaviour() { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream originalOutput = System.out; + System.setOut(new PrintStream(outputStream)); + + VoidProgressBar progressBar = new VoidProgressBar(); + progressBar.step(); + progressBar.step(2); + progressBar.dispose(); + + System.setOut(originalOutput); + + Assertions.assertEquals("", outputStream.toString()); + } + + @ParameterizedTest + @MethodSource("getRelevantLogLevels") + void testVoidProgressBarCreated(Level logLevel) { + Level originalLogLevel = CollectedLogger.getLogLevel(); + CollectedLogger.setLogLevel(logLevel); + + ProgressBar progressBar = new CliProgressBarProvider().initProgressBar(ProgressBarType.CLUSTERING, 10); + progressBar.dispose(); + + Assertions.assertInstanceOf(VoidProgressBar.class, progressBar); + + CollectedLogger.setLogLevel(originalLogLevel); + } + + public static Level[] getRelevantLogLevels() { + return new Level[] {Level.TRACE, Level.DEBUG, Level.ERROR, Level.WARN}; + } +} diff --git a/report-viewer/package-lock.json b/report-viewer/package-lock.json index 8a39e60bf8..e2d80cc488 100644 --- a/report-viewer/package-lock.json +++ b/report-viewer/package-lock.json @@ -6210,12 +6210,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/sortablejs": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.2.tgz", - "integrity": "sha512-FJF5jgdfvoKn1MAKSdGs33bIqLi3LmsgVTliuX6iITj834F+JRQZN90Z93yql8h0K2t0RwDPBmxwlbZfDcxNZA==", - "peer": true - }, "node_modules/source-map-js": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", @@ -6830,7 +6824,7 @@ "version": "5.5.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.2.tgz", "integrity": "sha512-NcRtPEOsPFFWjobJEtfihkLCZCXZt/os3zf8nTxjVH3RvTSxjrCamJpbExGvYOF+tFHc3pA65qpdwPbzjohhew==", - "devOptional": true, + "dev": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver"