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 d9f900a3a6..482f321ee9 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 @@ -9,6 +9,7 @@ import static net.sourceforge.pmd.renderers.CodeClimateRule.CODECLIMATE_REMEDIAT import java.io.IOException; import java.io.Writer; +import java.util.Arrays; import java.util.Iterator; import org.apache.commons.lang3.StringUtils; @@ -16,6 +17,7 @@ import org.apache.commons.lang3.StringUtils; import com.google.gson.Gson; import net.sourceforge.pmd.PMD; +import net.sourceforge.pmd.PropertyDescriptor; import net.sourceforge.pmd.Rule; import net.sourceforge.pmd.RuleViolation; @@ -79,22 +81,9 @@ public class CodeClimateRenderer extends AbstractIncrementingRenderer { break; } - issue.remediation_points = REMEDIATION_POINTS_DEFAULT; - if(rule.hasDescriptor(CODECLIMATE_REMEDIATION_MULTIPLIER)) { - issue.remediation_points *= rule.getProperty(CODECLIMATE_REMEDIATION_MULTIPLIER); - } + issue.remediation_points = getRemediationPoints(rule); + issue.categories = getCategories(rule); - if(rule.hasDescriptor(CODECLIMATE_CATEGORIES)) { - Object[] categories = rule.getProperty(CODECLIMATE_CATEGORIES); - issue.categories = new String[categories.length]; - for (int i = 0; i < categories.length; i++) { - issue.categories[i] = String.valueOf(categories[i]); - } - } - else { - issue.categories = CODECLIMATE_DEFAULT_CATEGORIES; - } - return issue; } @@ -122,19 +111,58 @@ public class CodeClimateRenderer extends AbstractIncrementingRenderer { private String getBody(RuleViolation rv) { Rule rule = rv.getRule(); - String result = "### Description" + PMD.EOL + - cleaned( rule.getDescription() ); + String result = "## " + rule.getName() + PMD.EOL + PMD.EOL + + "Since: PMD " + rule.getSince() + PMD.EOL + PMD.EOL + + "Priority: " + rule.getPriority() + PMD.EOL + PMD.EOL + + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): " + Arrays.toString(getCategories(rule)).replaceAll("[\\[\\]]","") + PMD.EOL + PMD.EOL + + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): " + getRemediationPoints(rule) + PMD.EOL + PMD.EOL + + cleaned(rule.getDescription()); if(!rule.getExamples().isEmpty()) { - result += PMD.EOL + "### Example" + PMD.EOL; + result += PMD.EOL + PMD.EOL + "Example(s):" + PMD.EOL + PMD.EOL; for(String snippet : rule.getExamples()) { - result += "```java " + PMD.EOL + - snippet + PMD.EOL + - "``` "; + result += "```java " + PMD.EOL + snippet + PMD.EOL + "``` "; + } + } + + if(!rule.getPropertyDescriptors().isEmpty()) { + result += PMD.EOL + PMD.EOL + "This rule has the following properties:" + PMD.EOL + PMD.EOL; + result += "Name | Default Value | Description" + PMD.EOL; + result += "--- | --- | ---" + PMD.EOL; + + for(PropertyDescriptor property : rule.getPropertyDescriptors()) { + result += property.name() + " | " + property.defaultValue() + " | " + property.description() + PMD.EOL; } } return result; } + + private int getRemediationPoints(Rule rule) { + int remediation_points = REMEDIATION_POINTS_DEFAULT; + + if(rule.hasDescriptor(CODECLIMATE_REMEDIATION_MULTIPLIER)) { + remediation_points *= rule.getProperty(CODECLIMATE_REMEDIATION_MULTIPLIER); + } + + return remediation_points; + } + + private String[] getCategories(Rule rule) { + String[] result; + + if(rule.hasDescriptor(CODECLIMATE_CATEGORIES)) { + Object[] categories = rule.getProperty(CODECLIMATE_CATEGORIES); + result = new String[categories.length]; + for (int i = 0; i < categories.length; i++) { + result[i] = String.valueOf(categories[i]); + } + } + else { + result = CODECLIMATE_DEFAULT_CATEGORIES; + } + + return result; + } } 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 b3b8c36fe7..26c1e065ab 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 @@ -14,7 +14,7 @@ public class CodeClimateRendererTest extends AbstractRendererTst { @Override public String getExpected() { - return "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\",\"content\":{\"body\":\"### Description" + PMD.EOL + "desc\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"n/a\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}" + "\u0000" + PMD.EOL; + return "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\",\"content\":{\"body\":\"## Foo" + PMD.EOL + PMD.EOL + "Since: PMD null" + PMD.EOL + PMD.EOL + "Priority: Low" + PMD.EOL + PMD.EOL + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style" + PMD.EOL + PMD.EOL + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000" + PMD.EOL + PMD.EOL + "desc" + PMD.EOL + PMD.EOL + "This rule has the following properties:" + PMD.EOL + PMD.EOL + "Name | Default Value | Description" + PMD.EOL + "--- | --- | ---" + PMD.EOL + "violationSuppressRegex | null | Suppress violations with messages matching a regular expression" + PMD.EOL + "violationSuppressXPath | null | Suppress violations on nodes which match a given relative XPath expression." + PMD.EOL + "\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"n/a\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}" + "\u0000" + PMD.EOL; } @Override @@ -24,8 +24,8 @@ public class CodeClimateRendererTest extends AbstractRendererTst { @Override public String getExpectedMultiple() { - return "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\",\"content\":{\"body\":\"### Description" + PMD.EOL + "desc\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"n/a\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}" + "\u0000" + PMD.EOL + - "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\",\"content\":{\"body\":\"### Description" + PMD.EOL + "desc\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"n/a\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}" + "\u0000" + PMD.EOL; + return "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\",\"content\":{\"body\":\"## Foo" + PMD.EOL + PMD.EOL + "Since: PMD null" + PMD.EOL + PMD.EOL + "Priority: Low" + PMD.EOL + PMD.EOL + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style" + PMD.EOL + PMD.EOL + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000" + PMD.EOL + PMD.EOL + "desc" + PMD.EOL + PMD.EOL + "This rule has the following properties:" + PMD.EOL + PMD.EOL + "Name | Default Value | Description" + PMD.EOL + "--- | --- | ---" + PMD.EOL + "violationSuppressRegex | null | Suppress violations with messages matching a regular expression" + PMD.EOL + "violationSuppressXPath | null | Suppress violations on nodes which match a given relative XPath expression." + PMD.EOL + "\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"n/a\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}" + "\u0000" + PMD.EOL + + "{\"type\":\"issue\",\"check_name\":\"Foo\",\"description\":\"blah\",\"content\":{\"body\":\"## Foo" + PMD.EOL + PMD.EOL + "Since: PMD null" + PMD.EOL + PMD.EOL + "Priority: Low" + PMD.EOL + PMD.EOL + "[Categories](https://github.com/codeclimate/spec/blob/master/SPEC.md#categories): Style" + PMD.EOL + PMD.EOL + "[Remediation Points](https://github.com/codeclimate/spec/blob/master/SPEC.md#remediation-points): 50000" + PMD.EOL + PMD.EOL + "desc" + PMD.EOL + PMD.EOL + "This rule has the following properties:" + PMD.EOL + PMD.EOL + "Name | Default Value | Description" + PMD.EOL + "--- | --- | ---" + PMD.EOL + "violationSuppressRegex | null | Suppress violations with messages matching a regular expression" + PMD.EOL + "violationSuppressXPath | null | Suppress violations on nodes which match a given relative XPath expression." + PMD.EOL + "\"},\"categories\":[\"Style\"],\"location\":{\"path\":\"n/a\",\"lines\":{\"begin\":1,\"end\":1}},\"severity\":\"info\",\"remediation_points\":50000}" + "\u0000" + PMD.EOL; } public static junit.framework.Test suite() {