diff --git a/docs/pages/pmd/userdocs/cpd/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md
index 7560694e1d..2457b13c0f 100644
--- a/docs/pages/pmd/userdocs/cpd/cpd.md
+++ b/docs/pages/pmd/userdocs/cpd/cpd.md
@@ -132,8 +132,8 @@ exactly identical.
description="Don't scan subdirectories. By default, subdirectories are considered."
%}
{% include custom/cli_option_row.html options="--skip-lexical-errors"
- description="Skip files which can't be tokenized due to invalid characters instead of aborting CPD.
- By default, CPD analysis is stopped on the first error."
+ description="Deprecated Skip files which can't be tokenized due to invalid characters instead of aborting CPD.
+ By default, CPD analysis is stopped on the first error. This is deprecated. Use `--fail-on-error` instead."
%}
{% include custom/cli_option_row.html options="--format,-f"
option_arg="format"
@@ -439,8 +439,10 @@ Andy Glover wrote an Ant task for CPD; here's how to use it:
default="false"
%}
{% include custom/cli_option_row.html options="skipLexicalErrors"
- description="Skip files which can't be tokenized due to invalid characters instead of aborting CPD."
- default="false"
+ description="Deprecated Skip files which can't be tokenized
+ due to invalid characters instead of aborting CPD. This parameter is deprecated and
+ ignored since PMD 7.2.0. It is now by default true. Use `failOnError` instead to fail the build."
+ default="true"
%}
{% include custom/cli_option_row.html options="skipBlocks"
description="Enables or disabled skipping of blocks like a pre-processor. See also option skipBlocksPattern."
diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md
index edb8ce6deb..fd4c83473a 100644
--- a/docs/pages/release_notes.md
+++ b/docs/pages/release_notes.md
@@ -65,11 +65,14 @@ Since this release, PMD will also expose any getter returning a collection of an
a build with errors will now fail and with that parameter, the previous behavior can be restored.
This parameter is available for both PMD and CPD.
+* The CLI parameter `--skip-lexical-errors` is deprecated. Use the new parameter `--[no-]--fail-on-error` instead.
+
##### Ant
* CPDTask has a new parameter `failOnError`. In controls, whether to fail the build if any recoverable errors occurred.
By default, the build will fail. CPD will still create a report with all detected duplications, but the report might
be incomplete.
+* The parameter `skipLexicalError` in CPDTask is deprecated. Use the new parameter `failOnError` instead.
#### Deprecated API
diff --git a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java
index 31fcd37600..423f48d41c 100644
--- a/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java
+++ b/pmd-ant/src/main/java/net/sourceforge/pmd/ant/CPDTask.java
@@ -75,6 +75,7 @@ public class CPDTask extends Task {
private boolean ignoreIdentifiers;
private boolean ignoreAnnotations;
private boolean ignoreUsings;
+ @Deprecated
private boolean skipLexicalErrors;
private boolean skipDuplicateFiles;
private boolean skipBlocks = true;
@@ -100,7 +101,14 @@ public class CPDTask extends Task {
config.setOnlyRecognizeLanguage(config.getLanguageRegistry().getLanguageById(language));
config.setSourceEncoding(Charset.forName(encoding));
config.setSkipDuplicates(skipDuplicateFiles);
- config.setSkipLexicalErrors(skipLexicalErrors);
+
+ if (skipLexicalErrors) {
+ log("skipLexicalErrors is deprecated and ignored. Lexical errors are now by default skipped. Use failOnError=\"false\" to not fail the build.", Project.MSG_WARN);
+ failOnError = false;
+ }
+
+ // implicitly enable skipLexicalErrors, so that we can fail the build at the end. A report is created in any case.
+ config.setSkipLexicalErrors(true);
config.setIgnoreAnnotations(ignoreAnnotations);
config.setIgnoreLiterals(ignoreLiterals);
@@ -132,7 +140,6 @@ public class CPDTask extends Task {
log(ioe.toString(), Project.MSG_ERR);
throw new BuildException("IOException during task execution", ioe);
} catch (ReportException re) {
- re.printStackTrace();
log(re.toString(), Project.MSG_ERR);
throw new BuildException("ReportException during task execution", re);
} finally {
@@ -229,6 +236,10 @@ public class CPDTask extends Task {
this.ignoreUsings = value;
}
+ /**
+ * @deprecated Use {@link #setFailOnError(boolean)} instead.
+ */
+ @Deprecated
public void setSkipLexicalErrors(boolean skipLexicalErrors) {
this.skipLexicalErrors = skipLexicalErrors;
}
diff --git a/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/cpdtasktest.xml b/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/cpdtasktest.xml
index aef5c73621..922e4a2a9a 100644
--- a/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/cpdtasktest.xml
+++ b/pmd-ant/src/test/resources/net/sourceforge/pmd/ant/xml/cpdtasktest.xml
@@ -17,7 +17,7 @@
-
+
@@ -25,7 +25,7 @@
-
+
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 a02723b1b0..fe8a835774 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
@@ -68,8 +68,12 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand
@Option(names = "--ignore-sequences", description = "Ignore sequences of identifiers and literals")
private boolean ignoreIdentifierAndLiteralSequences;
+ /**
+ * @deprecated Use {@link #failOnError} instead.
+ */
@Option(names = "--skip-lexical-errors",
- description = "Skip files which can't be tokenized due to invalid characters, instead of aborting with an error.")
+ description = "Skip files which can't be tokenized due to invalid characters, instead of aborting with an error. Deprecated - use --[no-]fail-on-error instead.")
+ @Deprecated
private boolean skipLexicalErrors;
@Option(names = "--no-skip-blocks",
@@ -124,6 +128,14 @@ public class CpdCommand extends AbstractAnalysisPmdSubcommand
configuration.setSourceEncoding(encoding.getEncoding());
configuration.setInputUri(uri);
+ if (skipLexicalErrors) {
+ configuration.getReporter().warn("--skip-lexical-errors is deprecated. Use --no-fail-on-error instead.");
+ configuration.setFailOnError(false);
+ }
+
+ // implicitly enable skipLexicalErrors, so that we can fail the build at the end. A report is created in any case.
+ configuration.setSkipLexicalErrors(true);
+
return configuration;
}
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 fd8a60d379..c7eab5f88f 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
@@ -221,7 +221,7 @@ class CpdCliTest extends BaseCliTest {
*/
@Test
void testSkipLexicalErrors() throws Exception {
- runCli(RECOVERED_ERRORS_OR_VIOLATIONS,
+ runCli(VIOLATIONS_FOUND,
"--minimum-tokens", "10",
"-d", BASE_RES_PATH + "badandgood/",
"--format", "text",
@@ -239,7 +239,7 @@ class CpdCliTest extends BaseCliTest {
"-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.checkStdErr(containsPattern("Skipping file: Lexical error in file '.*?BadFile\\.java'"));
r.checkStdOut(emptyString());
});
}
@@ -252,14 +252,14 @@ class CpdCliTest extends BaseCliTest {
"--format", "text",
"--no-fail-on-error")
.verify(r -> {
- r.checkStdErr(containsPattern("Error while tokenizing: Lexical error in file '.*?BadFile\\.java'"));
+ r.checkStdErr(containsPattern("Skipping file: Lexical error in file '.*?BadFile\\.java'"));
r.checkStdOut(emptyString());
});
}
@Test
void testExitCodeWithLexicalErrorsAndSkipLexical() throws Exception {
- runCli(RECOVERED_ERRORS_OR_VIOLATIONS,
+ runCli(OK,
"--minimum-tokens", "10",
"-d", Paths.get(BASE_RES_PATH, "badandgood", "BadFile.java").toString(),
"--format", "text",
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java
index edce7c8945..acc2a1d6ac 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDConfiguration.java
@@ -65,6 +65,7 @@ public class CPDConfiguration extends AbstractConfiguration {
private boolean ignoreIdentifierAndLiteralSequences = false;
+ @Deprecated
private boolean skipLexicalErrors = false;
private boolean noSkipBlocks = false;
@@ -226,10 +227,20 @@ public class CPDConfiguration extends AbstractConfiguration {
this.ignoreIdentifierAndLiteralSequences = ignoreIdentifierAndLiteralSequences;
}
+ /**
+ * @deprecated This option will be removed. With {@link #isFailOnError()}, you can
+ * control whether lexical errors should fail the build or not.
+ */
+ @Deprecated
public boolean isSkipLexicalErrors() {
return skipLexicalErrors;
}
+ /**
+ * @deprecated This option will be removed. With {@link #setFailOnError(boolean)}, you can
+ * control whether lexical errors should fail the build or not.
+ */
+ @Deprecated
public void setSkipLexicalErrors(boolean skipLexicalErrors) {
this.skipLexicalErrors = skipLexicalErrors;
}
diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java
index ccc2b6c686..fb47dc0a31 100644
--- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java
+++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CpdAnalysis.java
@@ -151,6 +151,9 @@ public final class CpdAnalysis implements AutoCloseable {
@SuppressWarnings("PMD.CloseResource")
public void performAnalysis(Consumer consumer) {
+ if (configuration.isSkipLexicalErrors()) {
+ LOGGER.warn("The option skipLexicalErrors is deprecated. Use failOnError instead.");
+ }
try (SourceManager sourceManager = new SourceManager(files.getCollectedFiles())) {
Map tokenizers =