Merge branch '7.0.x' into clem.pmd7-cpd-deprecations

This commit is contained in:
Clément Fournier
2023-01-25 17:00:10 +01:00
201 changed files with 4770 additions and 2166 deletions

View File

@@ -262,6 +262,10 @@
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
</dependency>
<dependency>
<groupId>me.tongfei</groupId>
<artifactId>progressbar</artifactId>
</dependency>
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>

View File

@@ -0,0 +1,43 @@
/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package me.tongfei.progressbar;
import static me.tongfei.progressbar.TerminalUtils.CARRIAGE_RETURN;
import java.io.PrintStream;
/**
* This is a friend class for me.tongfei.progressbar, as TerminalUtils is package-private.
*/
public final class PmdProgressBarFriend {
private PmdProgressBarFriend() {
throw new AssertionError("Can't instantiate utility classes");
}
public static ConsoleProgressBarConsumer createConsoleConsumer(PrintStream ps) {
return TerminalUtils.hasCursorMovementSupport()
? new InteractiveConsoleProgressBarConsumer(ps)
: new PostCarriageReturnConsoleProgressBarConsumer(ps);
}
private static class PostCarriageReturnConsoleProgressBarConsumer extends ConsoleProgressBarConsumer {
PostCarriageReturnConsoleProgressBarConsumer(PrintStream out) {
super(out);
}
@Override
public void accept(String str) {
// Set the carriage return at the end instead of at the beginning
out.print(StringDisplayUtils.trimDisplayLength(str, getMaxRenderedLength()) + CARRIAGE_RETURN);
}
@Override
public void clear() {
// do nothing (prints an empty line otherwise)
}
}
}

View File

@@ -14,8 +14,8 @@ import java.util.List;
import java.util.Properties;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;
import net.sourceforge.pmd.PMDConfiguration;
import net.sourceforge.pmd.PmdAnalysis;
@@ -27,6 +27,7 @@ import net.sourceforge.pmd.benchmark.TimingReportRenderer;
import net.sourceforge.pmd.cli.commands.typesupport.internal.PmdLanguageTypeSupport;
import net.sourceforge.pmd.cli.commands.typesupport.internal.PmdLanguageVersionTypeSupport;
import net.sourceforge.pmd.cli.internal.CliExitCode;
import net.sourceforge.pmd.cli.internal.ProgressBarListener;
import net.sourceforge.pmd.internal.LogMessages;
import net.sourceforge.pmd.lang.Language;
import net.sourceforge.pmd.lang.LanguageVersion;
@@ -45,6 +46,7 @@ import picocli.CommandLine.ParameterException;
@Command(name = "check", showDefaultValues = true,
description = "The PMD standard source code analyzer")
public class PmdCommand extends AbstractAnalysisPmdSubcommand {
private static final Logger LOG = LoggerFactory.getLogger(PmdCommand.class);
static {
final Properties emptyProps = new Properties();
@@ -279,7 +281,6 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand {
configuration.setFailOnViolation(failOnViolation);
configuration.setAnalysisCacheLocation(cacheLocation != null ? cacheLocation.toString() : null);
configuration.setIgnoreIncrementalAnalysis(noCache);
configuration.setProgressBar(showProgressBar);
if (languageVersion != null) {
configuration.setDefaultLanguageVersions(languageVersion);
@@ -322,7 +323,17 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand {
return CliExitCode.ERROR;
}
pmdReporter.log(Level.DEBUG, "Current classpath:\n{0}", System.getProperty("java.class.path"));
LOG.debug("Current classpath:\n{}", System.getProperty("java.class.path"));
if (showProgressBar) {
if (reportFile == null) {
pmdReporter.warn("Progressbar rendering conflicts with reporting to STDOUT. "
+ "No progressbar will be shown. Try running with argument '-r <file>' to output the report to a file instead.");
} else {
pmd.addListener(new ProgressBarListener());
}
}
final ReportStats stats = pmd.runAndReturnStats();
if (pmdReporter.numErrors() > 0) {
// processing errors are ignored

View File

@@ -0,0 +1,93 @@
/*
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.cli.internal;
import java.util.concurrent.atomic.AtomicInteger;
import net.sourceforge.pmd.Report;
import net.sourceforge.pmd.RuleViolation;
import net.sourceforge.pmd.lang.document.TextFile;
import net.sourceforge.pmd.reporting.FileAnalysisListener;
import net.sourceforge.pmd.reporting.GlobalAnalysisListener;
import net.sourceforge.pmd.reporting.ListenerInitializer;
import me.tongfei.progressbar.PmdProgressBarFriend;
import me.tongfei.progressbar.ProgressBar;
import me.tongfei.progressbar.ProgressBarBuilder;
import me.tongfei.progressbar.ProgressBarStyle;
/**
* Collects runtime analysis statistics and displays them live on command line output.
* Toggled off through --no-progress command line argument.
*/
public final class ProgressBarListener implements GlobalAnalysisListener {
private ProgressBar progressBar;
private final AtomicInteger numErrors = new AtomicInteger(0);
private final AtomicInteger numViolations = new AtomicInteger(0);
@Override
public ListenerInitializer initializer() {
return new ListenerInitializer() {
@Override
public void setNumberOfFilesToAnalyze(int totalFiles) {
// We need to delay initialization until we know how many files there are to avoid a first bogus render
progressBar = new ProgressBarBuilder()
.setTaskName("Processing files")
.setStyle(ProgressBarStyle.ASCII)
.hideEta()
.continuousUpdate()
.setInitialMax(totalFiles)
.setConsumer(PmdProgressBarFriend.createConsoleConsumer(System.out))
.clearDisplayOnFinish()
.build();
progressBar.setExtraMessage(extraMessage());
}
};
}
/**
* Updates progress bar string and forces it to be output regardless of its update interval.
*/
private void refreshProgressBar() {
progressBar.setExtraMessage(extraMessage());
progressBar.refresh();
}
private String extraMessage() {
return String.format("Violations:%d, Errors:%d", numViolations.get(), numErrors.get());
}
@Override
public FileAnalysisListener startFileAnalysis(TextFile file) {
return new FileAnalysisListener() {
@Override
public void onRuleViolation(RuleViolation violation) {
ProgressBarListener.this.numViolations.addAndGet(1);
}
@Override
public void onSuppressedRuleViolation(Report.SuppressedViolation violation) {
/*Not handled*/
}
@Override
public void onError(Report.ProcessingError error) {
ProgressBarListener.this.numErrors.addAndGet(1);
}
@Override
public void close() {
// Refresh progress bar on file analysis end (or file was in cache)
progressBar.step();
refreshProgressBar();
}
};
}
@Override
public void close() throws Exception {
progressBar.close();
}
}