diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java index 0eda16cd36..40a29a537f 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java @@ -457,7 +457,7 @@ public class PMD { // already been initialized at this point try { int violations = PMD.doPMD(configuration); - if (violations > 0) { + if (violations > 0 && configuration.isFailOnViolation()) { status = PMDCommandLineInterface.VIOLATIONS_FOUND; } else { status = 0; diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java index e85b5ea475..c8774fa28d 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/PMDConfiguration.java @@ -101,6 +101,7 @@ public class PMDConfiguration extends AbstractConfiguration { private boolean reportShortNames = false; private Properties reportProperties = new Properties(); private boolean showSuppressedViolations = false; + private boolean failOnViolation = true; private boolean stressTest; private boolean benchmark; @@ -493,4 +494,22 @@ public class PMDConfiguration extends AbstractConfiguration { public void setBenchmark(boolean benchmark) { this.benchmark = benchmark; } + + /** + * Whether PMD should exit with status 4 (the default behavior, true) if violations + * are found or just with 0 (to not break the build, e.g.). + * @return failOnViolation + */ + public boolean isFailOnViolation() { + return failOnViolation; + } + + /** + * Sets whether PMD should exit with status 4 (the default behavior, true) if violations + * are found or just with 0 (to not break the build, e.g.). + * @param failOnViolation failOnViolation + */ + public void setFailOnViolation(boolean failOnViolation) { + this.failOnViolation = failOnViolation; + } } \ No newline at end of file diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java index d523eb11d0..44a693bd39 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cli/PMDParameters.java @@ -78,6 +78,9 @@ public class PMDParameters { @Parameter(names = "-auxclasspath", description = "Specifies the classpath for libraries used by the source code. This is used by the type resolution. Alternatively, a 'file://' URL to a text file containing path elements on consecutive lines can be specified.") private String auxclasspath; + @Parameter(names = {"-failOnViolation", "--failOnViolation"}, arity = 1, description = "By default PMD exits with status 4 if violations are found. Disable this option with '-failOnViolation false' to exit with 0 instead and just write the report.") + private boolean failOnViolation = true; + // this has to be a public static class, so that JCommander can use it! public static class PropertyConverter implements IStringConverter { @@ -135,6 +138,7 @@ public class PMDParameters { configuration.setStressTest(params.isStress()); configuration.setSuppressMarker(params.getSuppressmarker()); configuration.setThreads(params.getThreads()); + configuration.setFailOnViolation(params.isFailOnViolation()); LanguageVersion languageVersion = LanguageRegistry.findLanguageVersionByTerseName(params.getLanguage() + " " + params.getVersion()); if(languageVersion != null) { @@ -224,6 +228,10 @@ public class PMDParameters { return format; } + public boolean isFailOnViolation() { + return failOnViolation; + } + /** * @return the uri alternative to source directory. */ diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java index f0edb03fe3..7edabf1c00 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/cpd/CPDCommandLineInterface.java @@ -89,7 +89,11 @@ public class CPDCommandLineInterface { cpd.go(); if (cpd.getMatches().hasNext()) { System.out.println(arguments.getRenderer().render(cpd.getMatches())); - setStatusCodeOrExit(DUPLICATE_CODE_FOUND); + if (arguments.isFailOnViolation()) { + setStatusCodeOrExit(DUPLICATE_CODE_FOUND); + } else { + setStatusCodeOrExit(0); + } } else { setStatusCodeOrExit(0); } 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 91c4564e96..06de46bd32 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 @@ -92,6 +92,9 @@ public class CPDConfiguration extends AbstractConfiguration { @Parameter(names = { "--help", "-h" }, description = "Print help text", required = false, help = true) private boolean help; + @Parameter(names = {"--failOnViolation", "-failOnViolation"}, arity = 1, description = "By default CPD exits with status 4 if code duplications are found. Disable this option with '-failOnViolation false' to exit with 0 instead and just write the report.") + private boolean failOnViolation = true; + // this has to be a public static class, so that JCommander can use it! public static class LanguageConverter implements IStringConverter { @@ -402,4 +405,12 @@ public class CPDConfiguration extends AbstractConfiguration { public void setSkipBlocksPattern(String skipBlocksPattern) { this.skipBlocksPattern = skipBlocksPattern; } + + public boolean isFailOnViolation() { + return failOnViolation; + } + + public void setFailOnViolation(boolean failOnViolation) { + this.failOnViolation = failOnViolation; + } } diff --git a/pmd-java/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java b/pmd-java/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java index ea71a7ffce..857bfbbc83 100644 --- a/pmd-java/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java +++ b/pmd-java/src/test/java/net/sourceforge/pmd/cpd/CPDCommandLineInterfaceTest.java @@ -50,6 +50,21 @@ public class CPDCommandLineInterfaceTest { Assert.assertEquals(4, Integer.parseInt(System.getProperty(CPDCommandLineInterface.STATUS_CODE_PROPERTY))); } + /** + * Test ignore identifiers argument with failOnViolation=false + */ + @Test + public void testIgnoreIdentifiersFailOnViolationFalse() throws Exception { + runCPD("--minimum-tokens", "34", "--language", "java", + "--files", "src/test/resources/net/sourceforge/pmd/cpd/clitest/", + "--ignore-identifiers", + "--failOnViolation", "false"); + + String out = bufferStdout.toString("UTF-8"); + Assert.assertTrue(out.contains("Found a 7 line (36 tokens) duplication")); + Assert.assertEquals(0, Integer.parseInt(System.getProperty(CPDCommandLineInterface.STATUS_CODE_PROPERTY))); + } + /** * Test excludes option. */ diff --git a/src/site/markdown/overview/changelog.md b/src/site/markdown/overview/changelog.md index 7d6e02c1d9..4b3ad93c29 100644 --- a/src/site/markdown/overview/changelog.md +++ b/src/site/markdown/overview/changelog.md @@ -11,6 +11,10 @@ * [#1344](https://sourceforge.net/p/pmd/bugs/1344/): AbstractNaming should check reverse * [#1361](https://sourceforge.net/p/pmd/bugs/1361/): ShortVariable and ShortMethodName configuration +* [#1414](https://sourceforge.net/p/pmd/bugs/1414/): Command line parameter to disable "failOnViolation" behavior + PMD and CPD Command Line Interfaces have a new optional parameter: `failOnViolation`. Executing PMD with the option + `-failOnViolation false` will perform the PMD checks but won't fail the build and still exit with status 0. + This is useful if you only want to generate the report with violations but don't want to fail your build. **New Rules:** diff --git a/src/site/markdown/usage/cpd-usage.md b/src/site/markdown/usage/cpd-usage.md index 22813eb7b8..729d14804f 100644 --- a/src/site/markdown/usage/cpd-usage.md +++ b/src/site/markdown/usage/cpd-usage.md @@ -129,6 +129,13 @@ The options "minimum-tokens" and "files" are the two required options; there are no + + --failOnViolation {true|false} + By default CPD exits with status 4 if code duplications are found. + Disable this option with '--failOnViolation false' to exit with 0 instead and just write the report. + no + + --ignore-literals Ignore number values and string contents when comparing text @@ -231,7 +238,7 @@ This behavior has been introduced to ease CPD integration into scripts or hooks, - +
0Everything is fine, now code duplications found
1Couldn't understand command line parameters or CPD exited with an exception
4At least one code duplication has been detected
4At least one code duplication has been detected unless '--failOnViolation false' is used.
diff --git a/src/site/markdown/usage/running.md.vm b/src/site/markdown/usage/running.md.vm index b95f0e9e0c..28f0158a40 100644 --- a/src/site/markdown/usage/running.md.vm +++ b/src/site/markdown/usage/running.md.vm @@ -190,6 +190,14 @@ The tool comes with a rather extensive help text, simply running with `-help`! no + + -failOnViolation {true|false} + By default PMD exits with status 4 if violations are found. + Disable this option with '-failOnViolation false' to exit with 0 instead and just write the report. + + no + + @@ -202,7 +210,7 @@ This behavior has been introduced to ease PMD integration into scripts or hooks, - +
0Everything is fine, now violations found
1Couldn't understand command line parameters or PMD exited with an exception
4At least one violation has been detected
4At least one violation has been detected unless '-failOnViolation false' is set.