Added failOnError (PMD 7.3.0) support

This commit is contained in:
Erik C. Thauvin 2024-06-28 17:47:54 -07:00
parent 03fd552702
commit efce6b9729
Signed by: erik
GPG key ID: 776702A6A2DA330E
6 changed files with 70 additions and 21 deletions

View file

@ -32,7 +32,7 @@ public class PmdOperationBuild extends Project {
public PmdOperationBuild() {
pkg = "rife.bld.extension";
name = "bld-pmd";
version = version(1, 1, 1);
version = version(1, 1, 2);
javaRelease = 17;
@ -40,7 +40,7 @@ public class PmdOperationBuild extends Project {
autoDownloadPurge = true;
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
var pmd = version(7, 2, 0);
var pmd = version(7, 3, 0);
scope(compile)
.include(dependency("com.uwyn.rife2", "bld", version(1, 9, 1)))
.include(dependency("net.sourceforge.pmd", "pmd-java", pmd));

View file

@ -69,6 +69,10 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
* The encoding.
*/
private Charset encoding_ = StandardCharsets.UTF_8;
/**
* The fail on error toggle.
*/
private boolean failOnError_ = true;
/**
* The fail on violation toggle.
*/
@ -296,7 +300,28 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
}
/**
* Sets whether the build will continue on warnings.
* Sets whether the build will exit on recoverable errors.
* <p>
* Default is: {@code true}
* <p>
* Note: If only violations are found, see {@link #failOnViolation(boolean) failOnViolation}
*
* @param failOnError whether to exit and fail the build if recoverable errors occurred
* @return this operation
* @see #failOnViolation(boolean)
*/
public PmdOperation failOnError(boolean failOnError) {
failOnError_ = failOnError;
return this;
}
/**
* Sets whether the build will continue on violations.
* <p>
* Note: If additionally recoverable errors occurred, see {@link #failOnError(boolean) failOnError}
*
* @param failOnViolation whether to exit and fail the build if violations are found
* @return this operation
*/
public PmdOperation failOnViolation(boolean failOnViolation) {
failOnViolation_ = failOnViolation;
@ -411,6 +436,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
config.setAnalysisCacheLocation(cache_.toFile().getAbsolutePath());
}
config.setFailOnError(failOnError_);
config.setFailOnViolation(failOnViolation_);
if (languageVersions_ != null) {
@ -574,8 +600,8 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
*
* @param commandName the command name
* @param config the configuration
* @return the number of errors
* @throws RuntimeException if an error occurs
* @return the number of violations
* @throws ExitStatusException if an error occurs
*/
@SuppressWarnings({"PMD.CloseResource", "PMD.AvoidInstantiatingObjectsInLoops"})
public int performPmdAnalysis(String commandName, PMDConfiguration config) throws ExitStatusException {
@ -585,8 +611,9 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
LOGGER.log(Level.INFO, "[{0}] inputPaths{1}", new Object[]{commandName, inputPaths_});
LOGGER.log(Level.INFO, "[{0}] ruleSets{1}", new Object[]{commandName, ruleSets_});
}
var numErrors = report.getViolations().size();
if (numErrors > 0) {
var numViolations = report.getViolations().size();
if (numViolations > 0) {
for (var v : report.getViolations()) {
if (LOGGER.isLoggable(Level.WARNING) && !silent()) {
final String msg;
@ -608,7 +635,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
}
var violations = String.format(
"[%s] %d rule violations were found. See the report at: %s", commandName, numErrors,
"[%s] %d rule violations were found. See the report at: %s", commandName, numViolations,
config.getReportFilePath().toUri());
if (config.isFailOnViolation()) {
if (LOGGER.isLoggable(Level.SEVERE) && !silent()) {
@ -616,8 +643,10 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
}
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
} else if (LOGGER.isLoggable(Level.WARNING) && !silent()) {
LOGGER.warning(violations);
LOGGER.warning(violations);
}
} else if (pmd.getReporter().numErrors() > 0 && failOnError_) {
throw new ExitStatusException(ExitStatusException.EXIT_FAILURE);
} else {
var rules = pmd.getRulesets();
if (!rules.isEmpty()) {
@ -630,7 +659,7 @@ public class PmdOperation extends AbstractOperation<PmdOperation> {
}
}
}
return numErrors;
return numViolations;
}
/**

View file

@ -142,12 +142,6 @@ class PmdOperationTest {
assertThat(config.getSourceEncoding()).as("ISO_8859").isEqualTo(StandardCharsets.ISO_8859_1);
}
@Test
void testExecuteNoProject() {
var pmd = new PmdOperation();
assertThatCode(pmd::execute).isInstanceOf(ExitStatusException.class);
}
@Test
void testExecute() throws ExitStatusException {
var pmd = new PmdOperation().fromProject(new BaseProject());
@ -163,12 +157,30 @@ class PmdOperationTest {
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
}
@Test
void testExecuteNoProject() {
var pmd = new PmdOperation();
assertThatCode(pmd::execute).isInstanceOf(ExitStatusException.class);
}
@Test
void testFailOnError() {
var pmd = newPmdOperation().ruleSets("src/test/resources/xml/old.xml")
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
assertThatCode(() -> pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
.isInstanceOf(ExitStatusException.class);
assertThatCode(() -> pmd.failOnError(false).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
.doesNotThrowAnyException();
}
@Test
void testFailOnValidation() {
var pmd = newPmdOperation().ruleSets(DOCUMENTATION_XML)
.inputPaths(Path.of("src/test/resources/java/Documentation.java"));
assertThatCode(() -> pmd.failOnViolation(true).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
.isInstanceOf(ExitStatusException.class);
assertThatCode(() -> pmd.failOnViolation(false).performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME)))
.doesNotThrowAnyException();
}
@Test
@ -369,7 +381,7 @@ class PmdOperationTest {
@Test
void testRuleSetsEmpty() throws ExitStatusException {
var pmd = newPmdOperation().ruleSets("");
var pmd = newPmdOperation().ruleSets("").failOnError(false);
assertThat(pmd.performPmdAnalysis(TEST, pmd.initConfiguration(COMMAND_NAME))).isEqualTo(0);
}

View file

@ -1,7 +1,7 @@
<?xml version="1.0"?>
<ruleset name="test"
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="test"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>Erik's Ruleset</description>
<!-- BEST PRACTICES -->

View file

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<ruleset name="Basic"
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="Basic"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
The Basic ruleset contains a collection of good practices which should be followed.

View file

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
name="old"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>Deprecated (old) rule</description>
<rule ref="category/java/performance.xml/UnnecessaryWrapperObjectCreation"/>
</ruleset>