diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java index e45086a60a..c553539331 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/AbstractAnalysisPmdSubcommand.java @@ -48,6 +48,12 @@ public abstract class AbstractAnalysisPmdSubcommand relativizeRootPaths; @Option(names = { "--relativize-paths-with", "-z"}, description = "Path relative to which directories are rendered in the report. " diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java index f629de248c..b949de739c 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/CpdCommand.java @@ -103,6 +103,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand configuration.addRelativizeRoots(relativizeRootPaths); } configuration.setFailOnViolation(failOnViolation); + configuration.setFailOnProcessingError(failOnProcessingError); configuration.setInputFilePath(fileListPath); if (inputPaths != null) { configuration.setInputPathList(new ArrayList<>(inputPaths)); @@ -134,7 +135,7 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand cpd.performAnalysis(report -> hasViolations.setValue(!report.getMatches().isEmpty())); boolean hasProcessingErrors = configuration.getReporter().numErrors() > 0; - if (hasProcessingErrors) { + if (hasProcessingErrors && configuration.isFailOnProcessingError()) { return CliExitCode.VIOLATIONS_OR_PROCESSING_ERRORS; } diff --git a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java index 4e15aa0f84..547feac371 100644 --- a/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java +++ b/pmd-cli/src/main/java/net/sourceforge/pmd/cli/commands/internal/PmdCommand.java @@ -270,6 +270,7 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand configuration.setSuppressMarker(suppressMarker); configuration.setThreads(threads); configuration.setFailOnViolation(failOnViolation); + configuration.setFailOnProcessingError(failOnProcessingError); configuration.setAnalysisCacheLocation(cacheLocation != null ? cacheLocation.toString() : null); configuration.setIgnoreIncrementalAnalysis(noCache); @@ -330,7 +331,7 @@ public class PmdCommand extends AbstractAnalysisPmdSubcommand if (pmdReporter.numErrors() > 0) { // processing errors are ignored return CliExitCode.ERROR; - } else if (stats.getNumErrors() > 0) { + } else if (stats.getNumErrors() > 0 && configuration.isFailOnProcessingError()) { return CliExitCode.VIOLATIONS_OR_PROCESSING_ERRORS; } else if (stats.getNumViolations() > 0 && configuration.isFailOnViolation()) { return CliExitCode.VIOLATIONS_FOUND; diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java index 22004ac5d3..6597b4c414 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/CpdCliTest.java @@ -244,6 +244,19 @@ class CpdCliTest extends BaseCliTest { }); } + @Test + void testExitCodeWithLexicalErrorsNoFail() throws Exception { + runCli(OK, + "--minimum-tokens", "10", + "-d", Paths.get(BASE_RES_PATH, "badandgood", "BadFile.java").toString(), + "--format", "text", + "--no-fail-on-processing-error") + .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, diff --git a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java index 275da2b43b..36a19974a5 100644 --- a/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java +++ b/pmd-cli/src/test/java/net/sourceforge/pmd/cli/PmdCliTest.java @@ -329,6 +329,17 @@ class PmdCliTest extends BaseCliTest { }); } + @Test + void exitStatusWithProcessingErrorsNoFail() throws Exception { + runCli(OK, "--use-version", "dummy-parserThrows", + "-d", srcDir.toString(), "-f", "text", "-R", RULESET_WITH_VIOLATION, + "--no-fail-on-processing-error") + .verify(r -> { + r.checkStdOut(containsString("someSource.dummy\t-\tParseException: Parse exception: ohio")); + r.checkStdErr(containsString("An error occurred while executing PMD.")); + }); + } + @Test void testZipFileAsSource() throws Exception { Path zipArchive = createTemporaryZipArchive("sources.zip"); diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java index f79609ad9c..6d737ec219 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/AbstractConfiguration.java @@ -46,6 +46,7 @@ public abstract class AbstractConfiguration { private Path ignoreFilePath; private List excludes = new ArrayList<>(); private boolean collectRecursive = true; + private boolean failOnProcessingError = true; protected AbstractConfiguration(LanguageRegistry languageRegistry, PmdReporter messageReporter) { @@ -377,4 +378,12 @@ public abstract class AbstractConfiguration { public void collectFilesRecursively(boolean collectRecursive) { this.collectRecursive = collectRecursive; } + + public boolean isFailOnProcessingError() { + return failOnProcessingError; + } + + public void setFailOnProcessingError(boolean failOnProcessingError) { + this.failOnProcessingError = failOnProcessingError; + } }