From 25b9e4f739b1a323433c935e919a5ee4fd8e5759 Mon Sep 17 00:00:00 2001 From: Alban Auzeill Date: Tue, 8 Aug 2023 17:31:00 +0200 Subject: [PATCH] Support Clean Code Impacts and Attributes in ExternalRuleLoader --- .../analyzer/commons/ExternalRuleLoader.java | 129 +++++++- .../commons/ExternalRuleLoaderTest.java | 310 +++++++++++++++--- .../analyzer/commons/mylinter.json | 54 +++ pom.xml | 2 +- 4 files changed, 436 insertions(+), 59 deletions(-) diff --git a/commons/src/main/java/org/sonarsource/analyzer/commons/ExternalRuleLoader.java b/commons/src/main/java/org/sonarsource/analyzer/commons/ExternalRuleLoader.java index 9cb4e585..0ff42395 100644 --- a/commons/src/main/java/org/sonarsource/analyzer/commons/ExternalRuleLoader.java +++ b/commons/src/main/java/org/sonarsource/analyzer/commons/ExternalRuleLoader.java @@ -24,15 +24,22 @@ import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; import javax.annotation.CheckForNull; +import javax.annotation.Nullable; import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.sonar.api.SonarRuntime; import org.sonar.api.batch.rule.Severity; +import org.sonar.api.issue.impact.SoftwareQuality; +import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RulesDefinition.NewRepository; import org.sonar.api.server.rule.RulesDefinition.NewRule; +import org.sonar.api.utils.Version; /** * Creates external rule repository based on json file in the format [ { "key": "...", "name": "..." }, ... ] @@ -55,21 +62,40 @@ public class ExternalRuleLoader { private static final String DESCRIPTION_ONLY_URL = "See description of %s rule %s at the %s website."; private static final String DESCRIPTION_WITH_URL = "

%s

See more at the %s website.

"; private static final String DESCRIPTION_FALLBACK = "This is external rule %s:%s. No details are available."; + public static final Version API_VERSION_SUPPORTING_CLEAN_CODE_IMPACTS_AND_ATTIBUTES = Version.create(10, 1); private final String linterKey; private final String linterName; private final String languageKey; + private final boolean isCleanCodeImpactsAndAttributesSupported; private Map rulesMap = new HashMap<>(); + /** + * @deprecated Use the constructor that also provide the SonarRuntime argument to determine if you can use + * the new Clean Code attributes and impacts API. + * Then you should test "isCleanCodeImpactsAndAttributesSupported()" before using codeAttribute and codeImpacts. + */ + @Deprecated(since = "2.6") public ExternalRuleLoader(String linterKey, String linterName, String pathToMetadata, String languageKey) { + this(linterKey, linterName, pathToMetadata, languageKey, null); + } + + public ExternalRuleLoader(String linterKey, String linterName, String pathToMetadata, String languageKey, @Nullable SonarRuntime sonarRuntime) { this.linterKey = linterKey; this.linterName = linterName; this.languageKey = languageKey; + isCleanCodeImpactsAndAttributesSupported = sonarRuntime != null && + sonarRuntime.getApiVersion().isGreaterThanOrEqual(API_VERSION_SUPPORTING_CLEAN_CODE_IMPACTS_AND_ATTIBUTES); + loadMetadataFile(pathToMetadata); } + public boolean isCleanCodeImpactsAndAttributesSupported() { + return isCleanCodeImpactsAndAttributesSupported; + } + public void createExternalRuleRepository(org.sonar.api.server.rule.RulesDefinition.Context context) { NewRepository externalRepo = context.createExternalRepository(linterKey, languageKey).setName(linterName); @@ -78,14 +104,15 @@ public void createExternalRuleRepository(org.sonar.api.server.rule.RulesDefiniti newRule.setHtmlDescription(rule.getDescription(linterKey, linterName)); newRule.setDebtRemediationFunction(newRule.debtRemediationFunctions().constantPerIssue(rule.constantDebtMinutes + "min")); newRule.setType(rule.type); + newRule.setSeverity(rule.severity.name()); + if (rule.codeAttribute != null && rule.codeImpacts != null) { + newRule.setCleanCodeAttribute(rule.codeAttribute); + rule.codeImpacts.forEach(newRule::addDefaultImpact); + } if (rule.tags != null) { newRule.setTags(rule.tags); } - - if (rule.severity != null) { - newRule.setSeverity(rule.severity); - } } externalRepo.done(); @@ -106,13 +133,33 @@ public RuleType ruleType(String ruleKey) { public Severity ruleSeverity(String ruleKey) { ExternalRule externalRule = rulesMap.get(ruleKey); - if (externalRule != null && externalRule.severity != null) { - return Severity.valueOf(externalRule.severity); + if (externalRule != null) { + return externalRule.severity; } else { return DEFAULT_SEVERITY; } } + @Nullable + public CleanCodeAttribute codeAttribute(String ruleKey) { + ExternalRule externalRule = rulesMap.get(ruleKey); + if (externalRule != null) { + return externalRule.codeAttribute; + } else { + return null; + } + } + + @Nullable + public Map codeImpacts(String ruleKey) { + ExternalRule externalRule = rulesMap.get(ruleKey); + if (externalRule != null) { + return externalRule.codeImpacts; + } else { + return null; + } + } + public Long ruleConstantDebtMinutes(String ruleKey) { ExternalRule externalRule = rulesMap.get(ruleKey); if (externalRule != null) { @@ -128,7 +175,7 @@ private void loadMetadataFile(String pathToMetadata) { List> rules = new JsonParser().parseArray(inputStreamReader); for (Map rule : rules) { - ExternalRule externalRule = new ExternalRule(rule); + ExternalRule externalRule = new ExternalRule(rule, isCleanCodeImpactsAndAttributesSupported); rulesMap.put(externalRule.key, externalRule); } @@ -141,6 +188,7 @@ private static class ExternalRule { final String key; final String name; final RuleType type; + final Severity severity; @CheckForNull final String url; @@ -151,12 +199,15 @@ private static class ExternalRule { @CheckForNull final String[] tags; + final Long constantDebtMinutes; + @CheckForNull - final String severity; + final CleanCodeAttribute codeAttribute; - final Long constantDebtMinutes; + @CheckForNull + final Map codeImpacts; - public ExternalRule(Map rule) { + public ExternalRule(Map rule, boolean isCleanCodeImpactsAndAttributesSupported) { this.key = (String) rule.get("key"); this.name = (String) rule.get("name"); this.url = (String) rule.get("url"); @@ -168,13 +219,61 @@ public ExternalRule(Map rule) { } else { this.tags = null; } - this.severity = (String) rule.get("severity"); - String inputType = (String) rule.get("type"); - if (inputType != null) { - type = RuleType.valueOf(inputType); + type = getType(rule); + severity = getSeverity(rule); + if (isCleanCodeImpactsAndAttributesSupported) { + codeAttribute = getCodeAttribute(rule); + codeImpacts = getCodeImpacts(rule); } else { - type = DEFAULT_ISSUE_TYPE; + codeAttribute = null; + codeImpacts = null; + } + } + + private static RuleType getType(Map rule) { + String strType = (String) rule.get("type"); + if (strType != null) { + return RuleType.valueOf(strType); + } else { + return DEFAULT_ISSUE_TYPE; + } + } + + private static Severity getSeverity(Map rule) { + String strSeverity = (String) rule.get("severity"); + if (strSeverity != null) { + return Severity.valueOf(strSeverity); + } else { + return DEFAULT_SEVERITY; + } + } + + @Nullable + private static CleanCodeAttribute getCodeAttribute(Map rule) { + JSONObject code = (JSONObject) rule.get("code"); + if (code != null) { + String attribute = (String) code.get("attribute"); + if (attribute != null) { + return CleanCodeAttribute.valueOf(attribute); + } + } + return null; + } + + @Nullable + private static Map getCodeImpacts(Map rule) { + JSONObject code = (JSONObject) rule.get("code"); + if (code != null) { + JSONObject impacts = (JSONObject) code.get("impacts"); + if (impacts != null) { + Map map = new LinkedHashMap<>(); + impacts.forEach( + (k, v) -> map.put(SoftwareQuality.valueOf((String) k), + org.sonar.api.issue.impact.Severity.valueOf((String) v))); + return map; + } } + return null; } String getDescription(String linterKey, String linterName) { diff --git a/commons/src/test/java/org/sonarsource/analyzer/commons/ExternalRuleLoaderTest.java b/commons/src/test/java/org/sonarsource/analyzer/commons/ExternalRuleLoaderTest.java index 4a6f83a3..8f4ea324 100644 --- a/commons/src/test/java/org/sonarsource/analyzer/commons/ExternalRuleLoaderTest.java +++ b/commons/src/test/java/org/sonarsource/analyzer/commons/ExternalRuleLoaderTest.java @@ -19,79 +19,303 @@ */ package org.sonarsource.analyzer.commons; +import java.util.Map; +import java.util.Set; +import javax.annotation.Nullable; +import org.assertj.core.api.SoftAssertions; import org.junit.Test; +import org.sonar.api.SonarEdition; +import org.sonar.api.SonarQubeSide; +import org.sonar.api.SonarRuntime; import org.sonar.api.batch.rule.Severity; +import org.sonar.api.internal.SonarRuntimeImpl; +import org.sonar.api.issue.impact.SoftwareQuality; +import org.sonar.api.rules.CleanCodeAttribute; import org.sonar.api.rules.RuleType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.server.rule.RulesDefinition.Repository; import org.sonar.api.server.rule.RulesDefinition.Rule; +import org.sonar.api.utils.Version; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.api.batch.rule.Severity.BLOCKER; +import static org.sonar.api.batch.rule.Severity.INFO; +import static org.sonar.api.batch.rule.Severity.MAJOR; +import static org.sonar.api.batch.rule.Severity.MINOR; +import static org.sonar.api.issue.impact.Severity.HIGH; +import static org.sonar.api.issue.impact.Severity.LOW; +import static org.sonar.api.issue.impact.Severity.MEDIUM; +import static org.sonar.api.issue.impact.SoftwareQuality.MAINTAINABILITY; +import static org.sonar.api.issue.impact.SoftwareQuality.RELIABILITY; +import static org.sonar.api.issue.impact.SoftwareQuality.SECURITY; +import static org.sonar.api.rules.CleanCodeAttribute.IDENTIFIABLE; +import static org.sonar.api.rules.CleanCodeAttribute.RESPECTFUL; +import static org.sonar.api.rules.RuleType.BUG; +import static org.sonar.api.rules.RuleType.CODE_SMELL; +import static org.sonar.api.rules.RuleType.VULNERABILITY; public class ExternalRuleLoaderTest { + private static final SonarRuntime RUNTIME_10_0 = SonarRuntimeImpl.forSonarQube(Version.create(10, 0), SonarQubeSide.SERVER, SonarEdition.DEVELOPER); + private static final SonarRuntime RUNTIME_10_1 = SonarRuntimeImpl.forSonarQube(Version.create(10, 1), SonarQubeSide.SERVER, SonarEdition.DEVELOPER); + @Test - public void test() throws Exception { - RulesDefinition.Context context = new RulesDefinition.Context(); - ExternalRuleLoader externalRuleLoader = new ExternalRuleLoader( - "my-linter-key", - "MyLinter", - "org/sonarsource/analyzer/commons/mylinter.json", - "mylang"); + public void test_getters_runtime_10_0() { + ExternalRuleLoader loader = loadMyLinterJson(RUNTIME_10_0); + assertThat(loader.isCleanCodeImpactsAndAttributesSupported()).isFalse(); - assertThat(externalRuleLoader.ruleKeys()).containsOnly("bug-rule", "code-smell-rule", "vulnerability-rule", "no-type-rule"); + assertRule(loader, "not-existing-key", CODE_SMELL, MAJOR, 5L, null, null); + assertRule(loader, "bug-rule", BUG, MAJOR, 42L, null, null); + assertRule(loader, "code-smell-rule", CODE_SMELL, MAJOR, 5L, null, null); + assertRule(loader, "vulnerability-rule", VULNERABILITY, INFO, 5L, null, null); + assertRule(loader, "identifiable-low-maintainability-rule", BUG, MINOR, 5L, null, null); + assertRule(loader, "no-type-rule", CODE_SMELL, BLOCKER, 5L, null, null); + } - assertThat(externalRuleLoader.ruleType("not-existing-key")).isEqualTo(RuleType.CODE_SMELL); - assertThat(externalRuleLoader.ruleSeverity("not-existing-key")).isEqualTo(Severity.MAJOR); - assertThat(externalRuleLoader.ruleConstantDebtMinutes("not-existing-key")).isEqualTo(5L); + @Test + public void test_getters_null_runtime() { + ExternalRuleLoader loader = loadMyLinterJson(null); + assertThat(loader.isCleanCodeImpactsAndAttributesSupported()).isFalse(); + assertRule(loader, "bug-rule", BUG, MAJOR, 42L, null, null); + assertRule(loader, "identifiable-low-maintainability-rule", BUG, MINOR, 5L, null, null); + } - externalRuleLoader.createExternalRuleRepository(context); + @Test + public void test_getters_runtime_10_1() { + ExternalRuleLoader loader = loadMyLinterJson(RUNTIME_10_1); + assertThat(loader.isCleanCodeImpactsAndAttributesSupported()).isTrue(); - assertThat(externalRuleLoader.ruleType("not-existing-key")).isEqualTo(RuleType.CODE_SMELL); - assertThat(externalRuleLoader.ruleType("bug-rule")).isEqualTo(RuleType.BUG); - assertThat(externalRuleLoader.ruleSeverity("bug-rule")).isEqualTo(Severity.MAJOR); - assertThat(externalRuleLoader.ruleConstantDebtMinutes("bug-rule")).isEqualTo(42L); - assertThat(externalRuleLoader.ruleType("code-smell-rule")).isEqualTo(RuleType.CODE_SMELL); - assertThat(externalRuleLoader.ruleType("vulnerability-rule")).isEqualTo(RuleType.VULNERABILITY); - assertThat(externalRuleLoader.ruleConstantDebtMinutes("vulnerability-rule")).isEqualTo(5L); - assertThat(externalRuleLoader.ruleSeverity("vulnerability-rule")).isEqualTo(Severity.INFO); - assertThat(externalRuleLoader.ruleType("no-type-rule")).isEqualTo(RuleType.CODE_SMELL); - - checkRepository(context); + assertRule(loader, + "bug-rule", + BUG, + MAJOR, + 42L, + null, + null); + + assertRule(loader, + "identifiable-low-maintainability-rule", + BUG, + MINOR, + 5L, + IDENTIFIABLE, + Map.of(MAINTAINABILITY, LOW)); } - private static void checkRepository(RulesDefinition.Context context) { + @Test + public void test_repository_10_0() { + ExternalRuleLoader externalRuleLoader = loadMyLinterJson(RUNTIME_10_0); + RulesDefinition.Context context = new RulesDefinition.Context(); + externalRuleLoader.createExternalRuleRepository(context); + assertThat(context.repositories()).hasSize(1); + Repository repository = context.repository("external_my-linter-key"); assertThat(repository.isExternal()).isTrue(); assertThat(repository.name()).isEqualTo("MyLinter"); assertThat(repository.language()).isEqualTo("mylang"); - assertThat(repository.rules()).hasSize(4); + assertThat(repository.rules()).hasSize(8); + + assertRule(repository, + "bug-rule", + "Bug Rule Name", + "Bug Rule Description", + BUG, + "MAJOR", + "42min", + null, + Map.of(), + Set.of() + ); + + assertRule(repository, + "code-smell-rule", + "Code Smell Name", + "See description of MyLinter rule code-smell-rule at the MyLinter website.", + CODE_SMELL, + "MAJOR", + "5min", + null, + Map.of(), + Set.of("tag1", "tag2") + ); + + assertRule(repository, + "vulnerability-rule", + "Vulnerability Name", + "

Bug Rule Description

See more at the MyLinter website.

", + VULNERABILITY, + "INFO", + "5min", + null, + Map.of(), + Set.of() + ); + + assertRule(repository, + "no-type-rule", + "No Type Name", + "This is external rule my-linter-key:no-type-rule. No details are available.", + CODE_SMELL, + "BLOCKER", + "5min", + null, + Map.of(), + Set.of() + ); + + assertRule(repository, + "identifiable-low-maintainability-rule", + "Identifiable Low Maintainability Name", + "

Identifiable Rule Description

See more at the MyLinter website.

", + BUG, + "MINOR", + "5min", + null, + Map.of(), + Set.of() + ); + + assertRule(repository, + "respectful-reliability-and-security", + "Respectful Reliability and Security", + "Respectful Reliability and Security Description", + VULNERABILITY, + "MAJOR", + "5min", + null, + Map.of(), + Set.of() + ); - checkRules(repository); } - private static void checkRules(Repository repository) { - Rule rule1 = repository.rule("bug-rule"); - Rule rule2 = repository.rule("code-smell-rule"); - Rule rule3 = repository.rule("vulnerability-rule"); - Rule rule4 = repository.rule("no-type-rule"); + @Test + public void test_repository_10_1() { + ExternalRuleLoader externalRuleLoader = loadMyLinterJson(RUNTIME_10_1); + RulesDefinition.Context context = new RulesDefinition.Context(); + externalRuleLoader.createExternalRuleRepository(context); + + assertThat(context.repositories()).hasSize(1); + + Repository repository = context.repository("external_my-linter-key"); + assertThat(repository.rules()).hasSize(8); - assertThat(rule1.htmlDescription()).isEqualTo("Bug Rule Description"); - assertThat(rule2.htmlDescription()).isEqualTo("See description of MyLinter rule code-smell-rule at the MyLinter website."); - assertThat(rule3.htmlDescription()).isEqualTo("

Bug Rule Description

See more at the MyLinter website.

"); - assertThat(rule4.htmlDescription()).isEqualTo("This is external rule my-linter-key:no-type-rule. No details are available."); + assertRule(repository, + "bug-rule", + "Bug Rule Name", + "Bug Rule Description", + BUG, + "MAJOR", + "42min", + null, + Map.of(), + Set.of() + ); - assertThat(rule1.tags()).isEmpty(); - assertThat(rule2.tags()).containsOnly("tag1", "tag2"); + assertRule(repository, + "identifiable-low-maintainability-rule", + "Identifiable Low Maintainability Name", + "

Identifiable Rule Description

See more at the MyLinter website.

", + BUG, + "MINOR", + "5min", + IDENTIFIABLE, + Map.of(MAINTAINABILITY, LOW), + Set.of() + ); - assertThat(rule1.debtRemediationFunction().baseEffort()).isEqualTo("42min"); - assertThat(rule2.debtRemediationFunction().baseEffort()).isEqualTo("5min"); + assertRule(repository, + "respectful-reliability-and-security", + "Respectful Reliability and Security", + "Respectful Reliability and Security Description", + VULNERABILITY, + "MAJOR", + "5min", + RESPECTFUL, + Map.of(RELIABILITY, MEDIUM, SECURITY, HIGH), + Set.of() + ); - assertThat(rule2.severity()).isEqualTo("MAJOR"); - assertThat(rule3.severity()).isEqualTo("INFO"); - assertThat(rule4.severity()).isEqualTo("BLOCKER"); + assertRule(repository, + "missing-code-attribute", + "Missing Code Attribute", + "This is external rule my-linter-key:missing-code-attribute. No details are available.", + BUG, + "MINOR", + "5min", + null, + Map.of(), + Set.of() + ); - assertThat(rule1.name()).isEqualTo("Bug Rule Name"); + assertRule(repository, + "missing-impacts", + "Missing impacts", + "Missing impacts Description", + BUG, + "MINOR", + "5min", + null, + Map.of(), + Set.of() + ); } + + private static void assertRule(ExternalRuleLoader externalRuleLoader, String ruleKey, + RuleType expectedRuleType, Severity expectedRuleSeverity, Long expectedDebtMinutes, + CleanCodeAttribute expectedCodeAttribute, Map expectedCodeImpacts) { + SoftAssertions softly = new SoftAssertions(); + softly.assertThat(externalRuleLoader.ruleType(ruleKey)).as("ruleType of " + ruleKey).isEqualTo(expectedRuleType); + softly.assertThat(externalRuleLoader.ruleSeverity(ruleKey)).as("ruleSeverity of " + ruleKey).isEqualTo(expectedRuleSeverity); + softly.assertThat(externalRuleLoader.codeAttribute(ruleKey)).as("codeAttribute of " + ruleKey).isEqualTo(expectedCodeAttribute); + softly.assertThat(externalRuleLoader.codeImpacts(ruleKey)).as("codeImpacts of " + ruleKey).isEqualTo(expectedCodeImpacts); + softly.assertThat(externalRuleLoader.ruleConstantDebtMinutes(ruleKey)) + .as("ruleConstantDebtMinutes of " + ruleKey).isEqualTo(expectedDebtMinutes); + softly.assertAll(); + } + + private static void assertRule(Repository repository, String ruleKey, String expectedName, String expectedDescription, + RuleType expectedRuleType, String expectedRuleSeverity, String expectedDebtMinutes, + CleanCodeAttribute expectedCodeAttribute, Map expectedCodeImpacts, + Set expectedTags) { + SoftAssertions softly = new SoftAssertions(); + Rule rule = repository.rule(ruleKey); + assertThat(rule.name()).isEqualTo(expectedName); + assertThat(rule.htmlDescription()).isEqualTo(expectedDescription); + softly.assertThat(rule.type()).as("type of " + ruleKey).isEqualTo(expectedRuleType); + softly.assertThat(rule.severity()).as("severity of " + ruleKey).isEqualTo(expectedRuleSeverity); + softly.assertThat(rule.cleanCodeAttribute()).as("cleanCodeAttribute of " + ruleKey).isEqualTo(expectedCodeAttribute); + softly.assertThat(rule.defaultImpacts()).as("defaultImpacts of " + ruleKey).isEqualTo(expectedCodeImpacts); + softly.assertThat(rule.debtRemediationFunction().baseEffort()) + .as("debtRemediationFunction of " + ruleKey).isEqualTo(expectedDebtMinutes); + softly.assertThat(rule.tags()).as("tags of " + ruleKey).isEqualTo(expectedTags); + softly.assertAll(); + } + + + private static ExternalRuleLoader loadMyLinterJson(@Nullable SonarRuntime sonarRuntime) { + String linterKey = "my-linter-key"; + String linterName = "MyLinter"; + String pathToMetadata = "org/sonarsource/analyzer/commons/mylinter.json"; + String languageKey = "mylang"; + ExternalRuleLoader loader; + if (sonarRuntime != null) { + loader = new ExternalRuleLoader(linterKey, linterName, pathToMetadata, languageKey, sonarRuntime); + } else { + loader = new ExternalRuleLoader(linterKey, linterName, pathToMetadata, languageKey); + } + assertThat(loader.ruleKeys()).containsOnly( + "bug-rule", + "code-smell-rule", + "vulnerability-rule", + "identifiable-low-maintainability-rule", + "respectful-reliability-and-security", + "missing-code-attribute", + "missing-impacts", + "no-type-rule" + ); + return loader; + } + } diff --git a/commons/src/test/resources/org/sonarsource/analyzer/commons/mylinter.json b/commons/src/test/resources/org/sonarsource/analyzer/commons/mylinter.json index a3748bd5..ca38ce45 100644 --- a/commons/src/test/resources/org/sonarsource/analyzer/commons/mylinter.json +++ b/commons/src/test/resources/org/sonarsource/analyzer/commons/mylinter.json @@ -24,6 +24,60 @@ "severity": "INFO" }, + { + "key": "identifiable-low-maintainability-rule", + "name": "Identifiable Low Maintainability Name", + "type": "BUG", + "severity": "MINOR", + "code": { + "impacts": { + "MAINTAINABILITY": "LOW" + }, + "attribute": "IDENTIFIABLE" + }, + "description": "Identifiable Rule Description", + "url": "http://www.mylinter.org/identifiable-rule" + }, + + { + "key": "respectful-reliability-and-security", + "name": "Respectful Reliability and Security", + "type": "VULNERABILITY", + "severity": "MAJOR", + "code": { + "impacts": { + "RELIABILITY": "MEDIUM", + "SECURITY": "HIGH" + }, + "attribute": "RESPECTFUL" + }, + "description": "Respectful Reliability and Security Description" + }, + + { + "key": "missing-code-attribute", + "name": "Missing Code Attribute", + "type": "BUG", + "severity": "MINOR", + "code": { + "impacts": { + "RELIABILITY": "MEDIUM", + "SECURITY": "HIGH" + } + } + }, + + { + "key": "missing-impacts", + "name": "Missing impacts", + "type": "BUG", + "severity": "MINOR", + "code": { + "attribute": "RESPECTFUL" + }, + "description": "Missing impacts Description" + }, + { "key": "no-type-rule", "name": "No Type Name", diff --git a/pom.xml b/pom.xml index 1174fe2e..22fc0c7b 100644 --- a/pom.xml +++ b/pom.xml @@ -73,7 +73,7 @@ - 10.0.0.695 + 10.1.0.794 10.1.0.73491 3.17.1 3.0.2