[cli] CPD: Add new exit code 5: VIOLATIONS_OR_PROCESSING_ERRORS

This commit is contained in:
Andreas Dangel 2024-05-02 18:51:16 +02:00
parent a2139be00b
commit 468266d58d
No known key found for this signature in database
GPG Key ID: 93450DF2DF9A3FA3
3 changed files with 53 additions and 10 deletions

View File

@ -133,6 +133,11 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand<CPDConfiguration>
MutableBoolean hasViolations = new MutableBoolean();
cpd.performAnalysis(report -> hasViolations.setValue(!report.getMatches().isEmpty()));
boolean hasProcessingErrors = configuration.getReporter().numErrors() > 0;
if (hasProcessingErrors) {
return CliExitCode.VIOLATIONS_OR_PROCESSING_ERRORS;
}
if (hasViolations.booleanValue() && configuration.isFailOnViolation()) {
return CliExitCode.VIOLATIONS_FOUND;
}

View File

@ -10,10 +10,10 @@ import net.sourceforge.pmd.PMDConfiguration;
* The execution result of any given command.
*/
public enum CliExitCode {
/** No errors, no violations. This is exit code {@code 0}. */
/** No errors, no processing errors, no violations. This is exit code {@code 0}. */
OK(0),
/**
* Errors were detected, PMD may have not run to the end.
* Unexpected errors were detected, PMD may have not run to the end.
* This is exit code {@code 1}.
*/
ERROR(1),
@ -23,11 +23,23 @@ public enum CliExitCode {
*/
USAGE_ERROR(2),
/**
* No errors, but PMD found violations. This is exit code {@code 4}.
* This is only returned if {@link PMDConfiguration#isFailOnViolation()}
* is set (CLI flag {@code --failOnViolation}).
* No errors, but PMD found either duplications/violations or couldn't analyze all
* files due to parsing/lexing problems. This is exit code {@code 4}.
*
* <p>This is only returned if {@link PMDConfiguration#isFailOnViolation()}
* is set. It can be disabled by using CLI flag {@code --no-fail-on-violation}.
*/
VIOLATIONS_FOUND(4);
VIOLATIONS_FOUND(4),
/**
* PMD did run, but there were either duplications/violations
* or processing errors or both.
*
* <p>In case you find processing errors: Please report them</p>
*
* <p>If cli flag --no-fail-on-processing-errors is used, then this
* exit code is not used. In such case, either 0 or 4 is returned.</p>
*/
VIOLATIONS_OR_PROCESSING_ERRORS(5);
private final int exitCode;
@ -45,6 +57,7 @@ public enum CliExitCode {
case 1: return ERROR;
case 2: return USAGE_ERROR;
case 4: return VIOLATIONS_FOUND;
case 5: return VIOLATIONS_OR_PROCESSING_ERRORS;
default:
throw new IllegalArgumentException("Not a known exit code: " + i);
}

View File

@ -6,6 +6,7 @@ package net.sourceforge.pmd.cli;
import static net.sourceforge.pmd.cli.internal.CliExitCode.OK;
import static net.sourceforge.pmd.cli.internal.CliExitCode.VIOLATIONS_FOUND;
import static net.sourceforge.pmd.cli.internal.CliExitCode.VIOLATIONS_OR_PROCESSING_ERRORS;
import static net.sourceforge.pmd.util.CollectionUtil.listOf;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.Matchers.containsString;
@ -128,14 +129,14 @@ class CpdCliTest extends BaseCliTest {
@Test
void testWrongCliOptionResultsInErrorLoggingAfterDir() throws Exception {
// --ignore-identifiers doesn't take an argument anymore - it is interpreted as a file for inputPaths
final CliExecutionResult result = runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--dir", SRC_DIR, "--ignore-identifiers", "false");
final CliExecutionResult result = runCli(VIOLATIONS_OR_PROCESSING_ERRORS, "--minimum-tokens", "34", "--dir", SRC_DIR, "--ignore-identifiers", "false");
result.checkStdErr(containsString("No such file false"));
}
@Test
void testWrongCliOptionResultsInErrorLoggingBeforeDir() throws Exception {
// --ignore-identifiers doesn't take an argument anymore - it is interpreted as a file for inputPaths
final CliExecutionResult result = runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--ignore-identifiers", "false", "--dir", SRC_DIR);
final CliExecutionResult result = runCli(VIOLATIONS_OR_PROCESSING_ERRORS, "--minimum-tokens", "34", "--ignore-identifiers", "false", "--dir", SRC_DIR);
result.checkStdErr(containsString("No such file false"));
}
@ -152,7 +153,7 @@ class CpdCliTest extends BaseCliTest {
*/
@Test
void testIgnoreIdentifiers() throws Exception {
runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--dir", SRC_DIR, "--ignore-identifiers", "false", "--debug")
runCli(VIOLATIONS_FOUND, "--minimum-tokens", "34", "--dir", SRC_DIR, "--ignore-identifiers", "--debug")
.verify(result -> result.checkStdOut(containsString(
"Found a 14 line (89 tokens) duplication"
)));
@ -220,7 +221,7 @@ class CpdCliTest extends BaseCliTest {
*/
@Test
void testSkipLexicalErrors() throws Exception {
runCli(VIOLATIONS_FOUND,
runCli(VIOLATIONS_OR_PROCESSING_ERRORS,
"--minimum-tokens", "10",
"-d", BASE_RES_PATH + "badandgood/",
"--format", "text",
@ -231,6 +232,30 @@ class CpdCliTest extends BaseCliTest {
});
}
@Test
void testExitCodeWithLexicalErrors() throws Exception {
runCli(VIOLATIONS_OR_PROCESSING_ERRORS,
"--minimum-tokens", "10",
"-d", Paths.get(BASE_RES_PATH, "badandgood", "BadFile.java").toString(),
"--format", "text")
.verify(r -> {
r.checkStdErr(containsPattern("Error while tokenizing: Lexical error in file '.*?BadFile\\.java'"));
r.checkStdOut(emptyString());
});
}
@Test
void testExitCodeWithLexicalErrorsAndSkipLexical() throws Exception {
runCli(VIOLATIONS_OR_PROCESSING_ERRORS,
"--minimum-tokens", "10",
"-d", Paths.get(BASE_RES_PATH, "badandgood", "BadFile.java").toString(),
"--format", "text",
"--skip-lexical-errors")
.verify(r -> {
r.checkStdErr(containsPattern("Skipping file: Lexical error in file .*?BadFile\\.java"));
r.checkStdOut(emptyString());
});
}
@Test
void jsShouldFindDuplicatesWithDifferentFileExtensions() throws Exception {