diff --git a/docs/_data/sidebars/pmd_sidebar.yml b/docs/_data/sidebars/pmd_sidebar.yml index 0d6145cd6c..6c84019247 100644 --- a/docs/_data/sidebars/pmd_sidebar.yml +++ b/docs/_data/sidebars/pmd_sidebar.yml @@ -55,6 +55,21 @@ entries: - title: PMD CLI reference url: /pmd_userdocs_cli_reference.html output: web, pdf + - title: PMD Report formats + url: /pmd_userdocs_report_formats.html + output: web, pdf + - title: null + output: web, pdf + subfolders: + - title: CPD reference + output: web, pdf + subfolderitems: + - title: Copy-paste detection + url: /pmd_userdocs_cpd.html + output: web, pdf + - title: CPD Report formats + url: /pmd_userdocs_cpd_report_formats.html + output: web, pdf - title: null output: web, pdf subfolders: @@ -88,9 +103,6 @@ entries: - title: Testing your rules url: /pmd_userdocs_extending_testing.html output: web, pdf - - title: Copy-paste detection - url: /pmd_userdocs_cpd.html - output: web, pdf - title: null output: web, pdf subfolders: diff --git a/docs/pages/pmd/userdocs/cli_reference.md b/docs/pages/pmd/userdocs/cli_reference.md index ca45b101de..a43c809081 100644 --- a/docs/pages/pmd/userdocs/cli_reference.md +++ b/docs/pages/pmd/userdocs/cli_reference.md @@ -198,76 +198,5 @@ Example: ## Available Report Formats PMD comes with many different renderers. -The mnemonics in bold are used to select them on the command line, as -arguments to the `-format` option. Some formats accept *properties*, -which can be specified with the `-property` option on the command-line. +All formats are described at [PMD Report formats](pmd_userdocs_report_formats.html) -* **codeclimate**: Renderer for Code Climate JSON format. - -* **csv**: Comma-separated values tabular format. - - Properties: - - * problem: Include problem column. Default: true. - * package: Include package column. Default: true. - * file: Include file column. Default: true. - * priority: Include priority column. Default: true. - * line: Include line column. Default: true. - * desc: Include description column. Default: true. - * ruleSet: Include Rule set column. Default: true. - * rule: Include Rule column. Default: true. - -* **emacs**: GNU Emacs integration. - -* **html**: HTML format. - - Properties: - - * linePrefix: Prefix for line number anchor in the source file. - * linkPrefix: Path to HTML source. - -* **ideaj**: IntelliJ IDEA integration. - - Properties: - - * classAndMethodName: Class and method name, pass `.method` when processing a directory. - * sourcePath: - * fileName: - -* **summaryhtml**: Summary HTML format. - - Properties: - - * linePrefix: Prefix for line number anchor in the source file. - * linkPrefix: Path to HTML source. - -* **text**: Text format. - -* **textcolor**: Text format, with color support (requires ANSI console support, e.g. xterm, rxvt, etc.). - - Properties: - - * color: Enables colors with anything other than `false` or `0`. Default: yes. - -* **textpad**: TextPad integration. - -* **vbhtml**: Vladimir Bossicard HTML format. - -* **xml**: XML format. - - Properties: - - * encoding: XML encoding format, defaults to UTF-8. - -* **xslt**: XML with a XSL transformation applied. - - Properties: - - * encoding: XML encoding format, defaults to UTF-8. - * xsltFilename: The XSLT file name. - -* **yahtml**: Yet Another HTML format. - - Properties: - - * outputDir: Output directory. diff --git a/docs/pages/pmd/userdocs/cpd.md b/docs/pages/pmd/userdocs/cpd/cpd.md similarity index 99% rename from docs/pages/pmd/userdocs/cpd.md rename to docs/pages/pmd/userdocs/cpd/cpd.md index e9843661fe..bb341e8e2a 100644 --- a/docs/pages/pmd/userdocs/cpd.md +++ b/docs/pages/pmd/userdocs/cpd/cpd.md @@ -239,6 +239,7 @@ This behavior has been introduced to ease CPD integration into scripts or hooks, * csv_with_linecount_per_file * vs +For details, see [CPD Report Formats](pmd_userdocs_cpd_report_formats.html). ## Ant task diff --git a/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md new file mode 100644 index 0000000000..d224b28ee7 --- /dev/null +++ b/docs/pages/pmd/userdocs/cpd/cpd_report_formats.md @@ -0,0 +1,220 @@ +--- +title: Report formats for CPD +tags: [cpd, userdocs] +keywords: [formats, renderers] +summary: "Overview of the built-in report formats for CPD" +permalink: pmd_userdocs_cpd_report_formats.html +author: Andreas Dangel +--- + +## Overview + +CPD collects occurrences of found duplications and provides them to the selected report format. +Each found code duplication appears in one or more other files, so that each code duplication can +have multiple locations. Not all report formats display all locations. + +The following examples always describe the same duplications: + +1. a code block of 239 tokens spanning 33 lines in RuleReferenceTest. This is a duplication within the same file. +2. a code block of 110 tokens spanning 16 lines in JaxenXPathRuleQueryTest. This is a duplication that appears + 3 times within the same file. + + +## text + +This is the default format. + +All duplications are reported one after another. For each duplication, the complete code snippet is output. +Each duplication is separated by `======`. + +Example: + +``` +Found a 33 line (239 tokens) duplication in the following files: +Starting at line 32 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java +Starting at line 68 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java + + public void testOverride() { + final StringProperty PROPERTY1_DESCRIPTOR = new StringProperty("property1", "Test property", null, 0f); + MockRule rule = new MockRule(); + rule.definePropertyDescriptor(PROPERTY1_DESCRIPTOR); + rule.setLanguage(LanguageRegistry.getLanguage(Dummy2LanguageModule.NAME)); + rule.setName("name1"); + rule.setProperty(PROPERTY1_DESCRIPTOR, "value1"); + rule.setMessage("message1"); + rule.setDescription("description1"); + rule.addExample("example1"); + rule.setExternalInfoUrl("externalInfoUrl1"); + rule.setPriority(RulePriority.HIGH); + + final StringProperty PROPERTY2_DESCRIPTOR = new StringProperty("property2", "Test property", null, 0f); + RuleReference ruleReference = new RuleReference(); + ruleReference.setRule(rule); + ruleReference.definePropertyDescriptor(PROPERTY2_DESCRIPTOR); + ruleReference.setLanguage(LanguageRegistry.getLanguage(DummyLanguageModule.NAME)); + ruleReference + .setMinimumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.3")); + ruleReference + .setMaximumLanguageVersion(LanguageRegistry.getLanguage(DummyLanguageModule.NAME).getVersion("1.7")); + ruleReference.setDeprecated(true); + ruleReference.setName("name2"); + ruleReference.setProperty(PROPERTY1_DESCRIPTOR, "value2"); + ruleReference.setProperty(PROPERTY2_DESCRIPTOR, "value3"); + ruleReference.setMessage("message2"); + ruleReference.setDescription("description2"); + ruleReference.addExample("example2"); + ruleReference.setExternalInfoUrl("externalInfoUrl2"); + ruleReference.setPriority(RulePriority.MEDIUM_HIGH); + + validateOverridenValues(PROPERTY1_DESCRIPTOR, PROPERTY2_DESCRIPTOR, ruleReference); +===================================================================== +Found a 16 line (110 tokens) duplication in the following files: +Starting at line 66 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +Starting at line 88 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +Starting at line 110 of /home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java + + JaxenXPathRuleQuery query = createQuery(xpath); + List ruleChainVisits = query.getRuleChainVisits(); + Assert.assertEquals(2, ruleChainVisits.size()); + Assert.assertTrue(ruleChainVisits.contains("dummyNode")); + // Note: Having AST_ROOT in the rule chain visits is probably a mistake. But it doesn't hurt, it shouldn't + // match a real node name. + Assert.assertTrue(ruleChainVisits.contains(JaxenXPathRuleQuery.AST_ROOT)); + + DummyNodeWithListAndEnum dummy = new DummyNodeWithListAndEnum(1); + RuleContext data = new RuleContext(); + data.setLanguageVersion(LanguageRegistry.findLanguageByTerseName("dummy").getDefaultVersion()); + + query.evaluate(dummy, data); + // note: the actual xpath queries are only available after evaluating + Assert.assertEquals(2, query.nodeNameToXPaths.size()); + Assert.assertEquals("self::node()[(attribute::Test1 = \"false\")][(attribute::Test2 = \"true\")]", query.nodeNameToXPaths.get("dummyNode").get(0).toString()); +``` + + +## xml + +This format uses XML to output the duplications in a more structured format. + +Example: + +```xml + + + + + + + + + + + + ruleChainVisits = query.getRuleChainVisits(); + Assert.assertEquals(2, ruleChainVisits.size()); + Assert.assertTrue(ruleChainVisits.contains("dummyNode")); + // Note: Having AST_ROOT in the rule chain visits is probably a mistake. But it doesn't hurt, it shouldn't + // match a real node name. + Assert.assertTrue(ruleChainVisits.contains(JaxenXPathRuleQuery.AST_ROOT)); + + DummyNodeWithListAndEnum dummy = new DummyNodeWithListAndEnum(1); + RuleContext data = new RuleContext(); + data.setLanguageVersion(LanguageRegistry.findLanguageByTerseName("dummy").getDefaultVersion()); + + query.evaluate(dummy, data); + // note: the actual xpath queries are only available after evaluating + Assert.assertEquals(2, query.nodeNameToXPaths.size()); + Assert.assertEquals("self::node()[(attribute::Test1 = \"false\")][(attribute::Test2 = \"true\")]", query.nodeNameToXPaths.get("dummyNode").get(0).toString());]]> + + +``` + + +## csv + +This outputs the duplication as comma separated values. It only reports the duplication size (number +of lines and tokens) and the number of occurrences. After that, the begin lines and filenames are reported on +after another. + +Example: + +``` +lines,tokens,occurrences +33,239,2,32,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java,68,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java +16,110,3,66,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,88,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,110,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +``` + + +## csv_with_linecount_per_file + +This format is similar to "csv", but it has one difference: The duplication size in number of lines is reported +for each occurrence separately. While the tokens are the same, due to formatting or comments, the code blocks might be +different. Whitespace and comments are usually ignored when finding duplicated code. + +In each line, the duplication size in tokens is reported, then the number of occurrences. And after that, for each +file, the begin line, the number of duplicated lines and the filename. + +Example: + +``` +tokens,occurrences +239,2,32,33,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java,68,33,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenc +eTest.java +110,3,66,16,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,88,16,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java,110,16,/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java +``` + + +## vs + +This outputs the duplication in a format, that Visual Studio. CPD can be added as a external tool and the output +is shown in the console. You can then click on the filenames to jump to the source where the duplication is located. + +Each occurrence of a duplication is reported in a separate line, that's why in this example, we have 5 lines. + +Example: + +``` +/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java(32): Between lines 32 and 65 +/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/RuleReferenceTest.java(68): Between lines 68 and 101 +/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java(66): Between lines 66 and 82 +/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java(88): Between lines 88 and 104 +/home/pmd/source/pmd-core/src/test/java/net/sourceforge/pmd/lang/rule/xpath/JaxenXPathRuleQueryTest.java(110): Between lines 110 and 126 +``` diff --git a/docs/pages/pmd/userdocs/pmd_report_formats.md b/docs/pages/pmd/userdocs/pmd_report_formats.md new file mode 100644 index 0000000000..ff7fd639e7 --- /dev/null +++ b/docs/pages/pmd/userdocs/pmd_report_formats.md @@ -0,0 +1,339 @@ +--- +title: Report formats for PMD +tags: [pmd, userdocs] +keywords: [formats, renderers] +summary: "Overview of the built-in report formats for CPD" +permalink: pmd_userdocs_report_formats.html +author: Andreas Dangel +--- + +## Overview + +PMD can report the found rule violations in various formats. Some formats can +be customized further via properties. Violations might also be suppressed and there might +be processing errors or configuration errors. Not all report formats display all information. + +The header of the sections below are used to select the format on the command line, as +arguments to the `-format` option. When a format accepts *properties*, +those can be specified with the `-property` / `-P` option on the command-line. + +{% include note.html content="Suppressed violations are only reported, if the CLI parameter `-showsuppressed` is set." %} + +## codeclimate + +Renderer for Code Climate JSON format. + +This format is used when running PMD within [Code Climate](https://codeclimate.com/). +The renderer will stream JSON objects, each object is a own issue (a PMD rule violation). Each issue +is separated by the null character (`\0`). + +The format is specified here: . + +The code climate format doesn't support suppressed violations. It also doesn't report any errors. But it contains +the full rule details for each reported rule violation. + +Example: + +``` +{"type":"issue","check_name":"GuardLogStatement","description":"Logger calls should be surrounded by log level guards.","content":{"body":"## GuardLogStatement\n\nSince: PMD 5.1.0\n\nPriority: Medium High\n\n[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style\n\n[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000\n\nWhenever using a log level, one should check if the loglevel is actually enabled, or otherwise skip the associate String creation and manipulation.\n\n### Example:\n\n```java\n\n\n // Add this for performance\n if (log.isDebugEnabled() { ...\n log.debug('log something' + ' and ' + 'concat strings');\n\n \n``` \n\n### [PMD properties](https://pmd.github.io/pmd-6.22.0/pmd_devdocs_working_with_properties.html)\n\nName | Value | Description\n--- | --- | ---\nviolationSuppressRegex | | Suppress violations with messages matching a regular expression\nviolationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\nlogLevels | trace,debug,info,warn,error,log,finest,finer,fine,info,warning,severe | LogLevels to guard\nguardsMethods | isTraceEnabled,isDebugEnabled,isInfoEnabled,isWarnEnabled,isErrorEnabled,isLoggable | Method use to guard the log statement\n"},"categories":["Style"],"location":{"path":"/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java","lines":{"begin":124,"end":125}},"severity":"normal","remediation_points":50000} +{"type":"issue","check_name":"ForLoopCanBeForeach","description":"This for loop can be replaced by a foreach loop","content":{"body":"## ForLoopCanBeForeach\n\nSince: PMD 6.0.0\n\nPriority: Medium\n\n[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style\n\n[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000\n\nReports loops that can be safely replaced with the foreach syntax. The rule considers loops over lists, arrays and iterators. A loop is safe to replace if it only uses the index variable to access an element of the list or array, only has one update statement, and loops through *every* element of the list or array left to right.\n\n### Example:\n\n```java\n\n\npublic class MyClass {\n void loop(List l) {\n for (int i = 0; i < l.size(); i++) { // pre Java 1.5\n System.out.println(l.get(i));\n }\n\n for (String s : l) { // post Java 1.5\n System.out.println(s);\n }\n }\n}\n\n \n``` \n\n### [PMD properties](https://pmd.github.io/pmd-6.22.0/pmd_devdocs_working_with_properties.html)\n\nName | Value | Description\n--- | --- | ---\nviolationSuppressRegex | | Suppress violations with messages matching a regular expression\nviolationSuppressXPath | | Suppress violations on nodes which match a given relative XPath expression.\n"},"categories":["Style"],"location":{"path":"/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java","lines":{"begin":58,"end":62}},"severity":"normal","remediation_points":50000} +``` + +## csv + +Comma-separated values tabular format. + +This format only renders rule violations. Suppressed violations or errors are ignored. + +Example: + +``` +"Problem","Package","File","Priority","Line","Description","Rule set","Rule" +"1","net.sourceforge.pmd","/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java","2","124","Logger calls should be surrounded by log level guards.","Best Practices","GuardLogStatement" +"1","net.sourceforge.pmd.benchmark","/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java","3","58","This for loop can be replaced by a foreach loop","Best Practices","ForLoopCanBeForeach" +``` + +This format can be configured to display only certain columns. In order to not show the problem counter and package +columns, use these CLI parameters additionally: `-property problem=false -property package=false` + +**Properties:** + +* problem: Include problem column. Default: true. +* package: Include package column. Default: true. +* file: Include file column. Default: true. +* priority: Include priority column. Default: true. +* line: Include line column. Default: true. +* desc: Include description column. Default: true. +* ruleSet: Include Rule set column. Default: true. +* rule: Include Rule column. Default: true. + +## emacs + +GNU Emacs integration. + +Example: + +``` +/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java:124: Logger calls should be surrounded by log level guards. +/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java:58: This for loop can be replaced by a foreach loop +``` + +## html + +HTML format. + +This renderer provides two properties. If these are provided, then a link to the source where the violations +have been found is rendered. The following example has been created with `-property linkPrefix=https://github.com/pmd/pmd/blob/master/ -property linePrefix=L -shortnames -d pmd`. + +When using [Maven JXR Plugin](https://maven.apache.org/jxr/maven-jxr-plugin/index.html) to generate a html view +of the project's sources, then the property "htmlExtension" needs to be set to "true". This will then replace the +normal source file extensions (e.g. ".java") with ".html", so that the generated html pages are referenced. + +[Example](report-examples/pmd-report-html.html) + +**Properties:** + +* linePrefix: Prefix for line number anchor in the source file. +* linkPrefix: Path to HTML source. +* htmlExtension: Replace file extension with .html for the links (default: false) + +## ideaj + +IntelliJ IDEA integration. + +{% include warning.html content="This format can only be used as described in [Tools: IDEA](pmd_userdocs_tools.html#idea)." %} + +It has two ways of calling: + +1. For a single file: then all three properties need to be provided + +`run.sh pmd -d src/Foo.java -R rulesets/java/quickstart.xml -f ideaj -P fileName=src/Foo.java -P sourcePath=/home/pmd/src -P classAndMethodName=Foo` + +2. For a directory: then the fileName property can be omitted + +`run.sh pmd -d src -R rulesets/java/quickstart.xml -f ideaj -P sourcePath=/home/pmd/src -P classAndMethodName=.method` + +Example: + +``` +Logger calls should be surrounded by log level guards. + at Foo(:124) +This for loop can be replaced by a foreach loop + at Foo(:58) +``` + +**Properties:** + +* classAndMethodName: Class and method name, pass `.method` when processing a directory. +* sourcePath: +* fileName: + +## summaryhtml + +Summary HTML format. + +This is the [html renderer](#html) but with an extra section, the summarizes the violations per rule. + +[Example](report-examples/pmd-report-summaryhtml.html) + +**Properties:** + +* linePrefix: Prefix for line number anchor in the source file. +* linkPrefix: Path to HTML source. +* htmlExtension: Replace file extension with .html for the links (default: false) + +## text (default) + +This is the default format. + +This format outputs one line per violation. At the end, processing errors, suppressed violations +and configuration errors are reported. + +Example: + +``` +/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java:124: Logger calls should be surrounded by log level guards. +/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java:58: This for loop can be replaced by a foreach loop +/home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java - PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java +CloseResource rule violation suppressed by Annotation in /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/PMD.java +LoosePackageCoupling - No packages or classes specified +``` + +## textcolor + +Text format, with color support (requires ANSI console support, e.g. xterm, rxvt, etc.). + +Example: + +
+* file: ./pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java
+    src:  RuleContext.java:124:125
+    rule: GuardLogStatement
+    msg:  Logger calls should be surrounded by log level guards.
+    code: LOG.warning("The method RuleContext::setSourceCodeFilename(String) has been deprecated and will be removed."
+
+* file: ./pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java
+    src:  Benchmarker.java:58:62
+    rule: ForLoopCanBeForeach
+    msg:  This for loop can be replaced by a foreach loop
+    code: for (int i = 0; i < args.length; i++) {
+
+
+
+Summary:
+
+net.sourceforge.pmd.RuleContext : 1
+net.sourceforge.pmd.benchmark.Benchmarker : 1
+* file: ./pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
+    err:  PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
+net.sourceforge.pmd.PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:24)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
+    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
+    at java.base/java.lang.Thread.run(Thread.java:832)
+Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
+Was expecting one of:
+    "extends" ...
+    "implements" ...
+    "{" ...
+    "<" ...
+    
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12713)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12597)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1554)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:732)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:639)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:373)
+    at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
+    at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
+    ... 10 more
+
+
+* rule: LoosePackageCoupling
+    err:  No packages or classes specified
+
+* errors:   2
+* warnings: 2
+
+ +**Properties:** + +* color: Enables colors with anything other than `false` or `0`. Default: yes. + +## textpad + +TextPad integration. + +Example: + +``` +/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java(124, GuardLogStatement): Logger calls should be surrounded by log level guards. +/home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java(58, ForLoopCanBeForeach): This for loop can be replaced by a foreach loop +``` + +## vbhtml + +Vladimir Bossicard HTML format. + + +## xml + +XML format. + +This format is a XML document, that can be validated by a XSD schema. The schema is [report_2_0_0.xsd](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/resources/report_2_0_0.xsd). + +Example: + +```xml + + + + +Logger calls should be surrounded by log level guards. + + + + +This for loop can be replaced by a foreach loop + + + + + + + + +``` + +**Properties:** + +* encoding: XML encoding format, defaults to UTF-8. + +## xslt + +XML with a XSL transformation applied. + +PMD provides one built-in stylesheet, that is used by default, if no other +stylesheet with the property "xsltFilename" is specified. It is called [pmd-nicerhtml.xsl](https://github.com/pmd/pmd/blob/master/pmd-core/src/main/resources/pmd-nicerhtml.xsl) and can be used for customization. + +[Example with pmd-nicerhtml.xsl](report-examples/pmd-report-pmd-nicerhtml.html) + +**Properties:** + +* encoding: XML encoding format, defaults to UTF-8. +* xsltFilename: The XSLT file name. + +## yahtml + +Yet Another HTML format. + +This renderer creates an html file per analyzed source file, hence you need to specify a output directory. +The output directory must exist. If not specified, the html files are created in the current directory. + +[Example](report-examples/pmd-report-yahtml/index.html) + +**Properties:** + +* outputDir: Output directory. diff --git a/docs/pages/pmd/userdocs/tools/tools.md b/docs/pages/pmd/userdocs/tools/tools.md index b8427311fe..b3e8d550c9 100644 --- a/docs/pages/pmd/userdocs/tools/tools.md +++ b/docs/pages/pmd/userdocs/tools/tools.md @@ -243,11 +243,11 @@ Here's how to set it up as an "External Tool": * Name: PMD * Description: PMD, good for what ails you. * Menu: Select the "Main menu", "Project views", "Editor menu", and "Search results" checkboxes. - * Program: $JDKPath$\bin\java.exe + * Program: `c:\pmd\bin\pmd.bat` * For the next parameter you'll need to plug in the location of your PMD installation and the rulesets you want to use * Parameters: - `-cp %CLASSPATH%;c:\pmd\lib\pmd-{{pmd.site.version}}.jar;c:\pmd\lib\asm-3.2.jar;c:\pmd\lib\jaxen-1.1.1.jar net.sourceforge.pmd.PMD "$FilePath$" ideaj unusedcode,imports "$Sourcepath$" $FileClass$.method $FileName$` + `-d "$FilePath$" -f ideaj -R rulesets/java/quickstart.xml -P sourcePath="$Sourcepath$" -P classAndMethodName=$FileClass$.method -P fileName=$FileName$` That's pretty much it. Now you can right click on a source directory and select PMD, it'll run recursively on the source files, and the results should diff --git a/docs/pages/release_notes.md b/docs/pages/release_notes.md index 1c86a1b374..32f53654d7 100644 --- a/docs/pages/release_notes.md +++ b/docs/pages/release_notes.md @@ -47,8 +47,10 @@ Note that XPath 1.0 support, the default XPath version, is deprecated since PMD * [#2399](https://github.com/pmd/pmd/issues/2399): \[apex] ApexCRUDViolation: false positive with security enforced with line break * core * [#2019](https://github.com/pmd/pmd/issues/2019): \[core] Insufficient deprecation warnings for XPath attributes +* doc * [#2355](https://github.com/pmd/pmd/issues/2355): \[doc] Improve documentation about incremental analysis * [#2356](https://github.com/pmd/pmd/issues/2356): \[doc] Add missing doc about pmd.github.io + * [#2413](https://github.com/pmd/pmd/issues/2413): \[doc] Improve documentation about the available renderers (PMD/CPD) * java * [#2378](https://github.com/pmd/pmd/issues/2378): \[java] AbstractJUnitRule has bad performance on large code bases * java-bestpractices diff --git a/docs/report-examples/pmd-report-html.html b/docs/report-examples/pmd-report-html.html new file mode 100644 index 0000000000..2c1c41342d --- /dev/null +++ b/docs/report-examples/pmd-report-html.html @@ -0,0 +1,67 @@ +PMD +

PMD report

Problems found

+ + + + + + + + + + + + + +
#FileLineProblem
1pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java124Logger calls should be surrounded by log level guards.
2pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java58This for loop can be replaced by a foreach loop

Processing errors

+ + + + + +
FileProblem
pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
net.sourceforge.pmd.PMDException: Error while parsing pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:24)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
+    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
+    at java.base/java.lang.Thread.run(Thread.java:832)
+Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
+Was expecting one of:
+    "extends" ...
+    "implements" ...
+    "{" ...
+    "<" ...
+    
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12713)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12597)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1554)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:732)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:639)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:373)
+    at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
+    at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
+    ... 10 more
+

Suppressed warnings

+ + + + + + + + +
FileLineRuleNOPMD or AnnotationReason
pmd-core/src/main/java/net/sourceforge/pmd/PMD.java505CloseResourceAnnotation

Configuration errors

+ + + + + +
RuleProblem
LoosePackageCouplingNo packages or classes specified
\ No newline at end of file diff --git a/docs/report-examples/pmd-report-pmd-nicerhtml.html b/docs/report-examples/pmd-report-pmd-nicerhtml.html new file mode 100644 index 0000000000..702d8b1e8f --- /dev/null +++ b/docs/report-examples/pmd-report-pmd-nicerhtml.html @@ -0,0 +1,223 @@ + + + + + PMD 6.22.0 Report + + + + + + + + +
+ +

PMD 6.22.0 Report. Generated on 2020-04-11 - 19:23:45

+
+
+

Summary

+ + + + + + + + + + + + + + + + + + + +
FilesTotal +
Priority 1
+
+
Priority 2
+
+
Priority 3
+
+
Priority 4
+
+
Priority 5
+
2201100
+
+

Rules

+ + + + + + + + + + + + + + + + +
RuleViolationsSeverity
+ [Best Practices] GuardLogStatement1 +
2
+
+ [Best Practices] ForLoopCanBeForeach1 +
3
+
+
+

Files

+ + + + + + + + + + + + + + + + + + + + + + + + + +
File +
5
+
+
4
+
+
3
+
+
2
+
+
1
+
+ /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java + 00010
+ /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java + 00100
+
+
+

File /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java

+ + + + + + + + + + + +
ViolationError DescriptionLine
+
2
+
+ [Best Practices.GuardLogStatement] + - + +Logger calls should be surrounded by log level guards. + + 124 - 125
+
Back to top + +

File /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java

+ + + + + + + + + + + +
ViolationError DescriptionLine
+
3
+
+ [Best Practices.ForLoopCanBeForeach] + - + +This for loop can be replaced by a foreach loop + + 58 - 62
+
Back to top +
+ + \ No newline at end of file diff --git a/docs/report-examples/pmd-report-summaryhtml.html b/docs/report-examples/pmd-report-summaryhtml.html new file mode 100644 index 0000000000..92dc3e1f72 --- /dev/null +++ b/docs/report-examples/pmd-report-summaryhtml.html @@ -0,0 +1,74 @@ +PMD +

Summary

+ + + + +
Rule nameNumber of violations
GuardLogStatement1
ForLoopCanBeForeach1
+

Detail

+

PMD report

Problems found

+ + + + + + + + + + + + + +
#FileLineProblem
1pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java124Logger calls should be surrounded by log level guards.
2pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java58This for loop can be replaced by a foreach loop

Processing errors

+ + + + + +
FileProblem
pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
net.sourceforge.pmd.PMDException: Error while parsing pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:1)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
+    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
+    at java.base/java.lang.Thread.run(Thread.java:834)
+Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
+Was expecting one of:
+    "extends" ...
+    "implements" ...
+    "{" ...
+    "<" ...
+    
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12731)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12615)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1574)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:779)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:686)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:420)
+    at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
+    at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
+    ... 10 more
+

Suppressed warnings

+ + + + + + + + +
FileLineRuleNOPMD or AnnotationReason
pmd-core/src/main/java/net/sourceforge/pmd/PMD.java505CloseResourceAnnotation

Configuration errors

+ + + + + +
RuleProblem
LoosePackageCouplingNo packages or classes specified
\ No newline at end of file diff --git a/docs/report-examples/pmd-report-vbhtml.html b/docs/report-examples/pmd-report-vbhtml.html new file mode 100644 index 0000000000..f6ce69c610 --- /dev/null +++ b/docs/report-examples/pmd-report-vbhtml.html @@ -0,0 +1,42 @@ +PMD
+ +
 /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/RuleContext.java
124   Logger calls should be surrounded by log level guards.
+ +
 /home/pmd/source/pmd-core/src/main/java/net/sourceforge/pmd/benchmark/Benchmarker.java
58   This for loop can be replaced by a foreach loop

 Problems found
/home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
net.sourceforge.pmd.PMDException: Error while parsing /home/pmd/source/pmd-core/src/test/resources/net/sourceforge/pmd/cpd/files/file_with_ISO-8859-1_encoding.java
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:110)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:89)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCode(SourceCodeProcessor.java:51)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:78)
+    at net.sourceforge.pmd.processor.PmdRunnable.call(PmdRunnable.java:24)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
+    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
+    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)
+    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)
+    at java.base/java.lang.Thread.run(Thread.java:832)
+Caused by: net.sourceforge.pmd.lang.java.ast.ParseException: Encountered " "-" "- "" at line 6, column 30.
+Was expecting one of:
+    "extends" ...
+    "implements" ...
+    "{" ...
+    "<" ...
+    
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.generateParseException(JavaParser.java:12713)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.jj_consume_token(JavaParser.java:12597)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceBody(JavaParser.java:1554)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.ClassOrInterfaceDeclaration(JavaParser.java:732)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.TypeDeclaration(JavaParser.java:639)
+    at net.sourceforge.pmd.lang.java.ast.JavaParser.CompilationUnit(JavaParser.java:373)
+    at net.sourceforge.pmd.lang.java.AbstractJavaParser.parse(AbstractJavaParser.java:62)
+    at net.sourceforge.pmd.SourceCodeProcessor.parse(SourceCodeProcessor.java:121)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSource(SourceCodeProcessor.java:185)
+    at net.sourceforge.pmd.SourceCodeProcessor.processSourceCodeWithoutCache(SourceCodeProcessor.java:107)
+    ... 10 more
+
 Configuration problems found
LoosePackageCouplingNo packages or classes specified
diff --git a/docs/report-examples/pmd-report-yahtml/Benchmarker.html b/docs/report-examples/pmd-report-yahtml/Benchmarker.html new file mode 100644 index 0000000000..2e0da807d1 --- /dev/null +++ b/docs/report-examples/pmd-report-yahtml/Benchmarker.html @@ -0,0 +1,15 @@ + + + + + PMD - Benchmarker + + +

Class View

+

Class: Benchmarker

+ + + +
MethodViolation
findBooleanSwitch
Rule:ForLoopCanBeForeach
Description:This for loop can be replaced by a foreach loop
Line:58 and 62
+ + diff --git a/docs/report-examples/pmd-report-yahtml/RuleContext.html b/docs/report-examples/pmd-report-yahtml/RuleContext.html new file mode 100644 index 0000000000..1f401103f4 --- /dev/null +++ b/docs/report-examples/pmd-report-yahtml/RuleContext.html @@ -0,0 +1,15 @@ + + + + + PMD - RuleContext + + +

Class View

+

Class: RuleContext

+ + + +
MethodViolation
setSourceCodeFilename
Rule:GuardLogStatement
Description:Logger calls should be surrounded by log level guards.
Line:124 and 125
+ + diff --git a/docs/report-examples/pmd-report-yahtml/index.html b/docs/report-examples/pmd-report-yahtml/index.html new file mode 100644 index 0000000000..c8a696b998 --- /dev/null +++ b/docs/report-examples/pmd-report-yahtml/index.html @@ -0,0 +1,20 @@ + + + + + PMD + + +

Package View

+ + + + + + + + + +
PackageClass#
Aggregate - 2
net - 2
net.sourceforge - 2
net.sourceforge.pmd - 2
net.sourceforge.pmd RuleContext 1
net.sourceforge.pmd.benchmark - 1
net.sourceforge.pmd.benchmark Benchmarker 1
+ + diff --git a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java index 4cc5645b92..0463368e8a 100644 --- a/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java +++ b/pmd-core/src/main/java/net/sourceforge/pmd/renderers/CodeClimateRenderer.java @@ -33,7 +33,7 @@ public class CodeClimateRenderer extends AbstractIncrementingRenderer { public static final int REMEDIATION_POINTS_DEFAULT = 50000; public static final String[] CODECLIMATE_DEFAULT_CATEGORIES = new String[] {"Style"}; - // Note: required by https://github.com/codeclimate/spec/blob/master/SPEC.md + // Note: required by https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md protected static final String NULL_CHARACTER = "\u0000"; protected static final List INTERNAL_DEV_PROPERTIES = Arrays.asList("version", "xpath"); private static final String PMD_PROPERTIES_URL = getPmdPropertiesURL(); @@ -146,9 +146,9 @@ public class CodeClimateRenderer extends AbstractIncrementingRenderer { private String getBody() { String result = "## " + rule.getName() + "\\n\\n" + "Since: PMD " + rule.getSince() + "\\n\\n" + "Priority: " + rule.getPriority() + "\\n\\n" - + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): " + + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): " + Arrays.toString(getCategories()).replaceAll("[\\[\\]]", "") + "\\n\\n" - + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): " + + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): " + getRemediationPoints() + "\\n\\n" + cleaned(rule.getDescription()); if (!rule.getExamples().isEmpty()) { diff --git a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java index 28ca250b06..c81b425668 100644 --- a/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java +++ b/pmd-core/src/test/java/net/sourceforge/pmd/renderers/CodeClimateRendererTest.java @@ -30,8 +30,8 @@ public class CodeClimateRendererTest extends AbstractRendererTest { public String getExpected() { return "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\"," + "\"content\":{\"body\":\"## Foo\\n\\nSince: PMD null\\n\\nPriority: Low\\n\\n" - + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style\\n\\n" - + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000\\n\\n" + + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "desc\\n\\n" + "### [PMD properties](https://pmd.github.io/latest/pmd_devdocs_working_with_properties.html)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" @@ -45,8 +45,8 @@ public class CodeClimateRendererTest extends AbstractRendererTest { public String getExpectedWithProperties() { return "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\"," + "\"content\":{\"body\":\"## Foo\\n\\nSince: PMD null\\n\\nPriority: Low\\n\\n" - + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style\\n\\n" - + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000\\n\\n" + + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "desc\\n\\n" + "### [PMD properties](https://pmd.github.io/latest/pmd_devdocs_working_with_properties.html)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" @@ -67,8 +67,8 @@ public class CodeClimateRendererTest extends AbstractRendererTest { public String getExpectedMultiple() { return "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\"," + "\"content\":{\"body\":\"## Foo\\n\\nSince: PMD null\\n\\nPriority: Low\\n\\n" - + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style\\n\\n" - + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000\\n\\n" + + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "desc\\n\\n" + "### [PMD properties](https://pmd.github.io/latest/pmd_devdocs_working_with_properties.html)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" @@ -77,8 +77,8 @@ public class CodeClimateRendererTest extends AbstractRendererTest { + "\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"" + getSourceCodeFilename() + "\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}" + "\u0000" + PMD.EOL + "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\"," + "\"content\":{\"body\":\"## Foo\\n\\nSince: PMD null\\n\\nPriority: Low\\n\\n" - + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style\\n\\n" - + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000\\n\\n" + + "[Categories](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#categories): Style\\n\\n" + + "[Remediation Points](https://github.com/codeclimate/platform/blob/master/spec/analyzers/SPEC.md#remediation-points): 50000\\n\\n" + "desc\\n\\n" + "### [PMD properties](https://pmd.github.io/latest/pmd_devdocs_working_with_properties.html)\\n\\n" + "Name | Value | Description\\n" + "--- | --- | ---\\n" diff --git a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java index 1ab25d40a6..66d8c45a7e 100644 --- a/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java +++ b/pmd-doc/src/main/java/net/sourceforge/pmd/docs/DeadLinksChecker.java @@ -177,6 +177,12 @@ public class DeadLinksChecker { } else { linkOk = linkTarget.isEmpty() || htmlPages.contains(linkTarget); } + + // maybe a local file + if (!linkOk) { + Path localResource = docsDirectory.resolve(linkTarget); + linkOk = Files.exists(localResource); + } } if (!linkOk) {