From bf0c2e6432fc59fee288a3d1a3df19c7edd49943 Mon Sep 17 00:00:00 2001 From: =?utf8?q?L=C3=A9o=20Geoffroy?= <99647462+leo-geoffroy-sonarsource@users.noreply.github.com> Date: Wed, 11 May 2022 10:35:22 +0200 Subject: [PATCH] SONAR-16303 Add section example to xoo plugin (#5914) --- .../sonar/xoo/rule/XooRulesDefinition.java | 124 +++++++++++------- 1 file changed, 79 insertions(+), 45 deletions(-) diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java index 11c01bde690..8052b9843c9 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java @@ -23,6 +23,7 @@ import javax.annotation.Nullable; import org.sonar.api.SonarRuntime; import org.sonar.api.rule.RuleScope; import org.sonar.api.rules.RuleType; +import org.sonar.api.server.rule.RuleDescriptionSection; import org.sonar.api.server.rule.RuleParamType; import org.sonar.api.server.rule.RulesDefinition; import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader; @@ -31,7 +32,13 @@ import org.sonar.xoo.Xoo; import org.sonar.xoo.Xoo2; import org.sonar.xoo.checks.Check; -import static org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version.*; +import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ASSESS_THE_PROBLEM_SECTION_KEY; +import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.HOW_TO_FIX_SECTION_KEY; +import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.INTRODUCTION_SECTION_KEY; +import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.RESOURCES_SECTION_KEY; +import static org.sonar.api.server.rule.RuleDescriptionSection.RuleDescriptionSectionKeys.ROOT_CAUSE_SECTION_KEY; +import static org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version.Y2017; +import static org.sonar.api.server.rule.RulesDefinition.OwaspTop10Version.Y2021; /** * Define all the coding rules that are supported on the repositories named "xoo" and "xoo2" @@ -64,11 +71,11 @@ public class XooRulesDefinition implements RulesDefinition { private static void defineRulesXoo2(Context context) { NewRepository repo = context.createRepository(XOO2_REPOSITORY, Xoo2.KEY).setName("Xoo2"); - NewRule hasTag = repo.createRule(HasTagSensor.RULE_KEY).setName("Has Tag") - .setHtmlDescription("Search for a given tag in Xoo files"); + NewRule hasTag = repo.createRule(HasTagSensor.RULE_KEY).setName("Has Tag"); + addAllDescriptionSections(hasTag, "Search for a given tag in Xoo files"); - NewRule oneIssuePerLine = repo.createRule(OneIssuePerLineSensor.RULE_KEY).setName("One Issue Per Line") - .setHtmlDescription("Generate an issue on each line of a file. It requires the metric \"lines\"."); + NewRule oneIssuePerLine = repo.createRule(OneIssuePerLineSensor.RULE_KEY).setName("One Issue Per Line"); + addAllDescriptionSections(oneIssuePerLine, "Generate an issue on each line of a file. It requires the metric \"lines\"."); oneIssuePerLine .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("1min")) .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code"); @@ -82,16 +89,17 @@ public class XooRulesDefinition implements RulesDefinition { new RulesDefinitionAnnotationLoader().load(repo, Check.ALL); NewRule hasTag = repo.createRule(HasTagSensor.RULE_KEY).setName("Has Tag") - .setActivatedByDefault(true) - .setHtmlDescription("Search for a given tag in Xoo files"); + .setActivatedByDefault(true); + addAllDescriptionSections(hasTag, "Search for a given tag in Xoo files"); hasTag .setDebtRemediationFunction(hasTag.debtRemediationFunctions().constantPerIssue("2min")); hasTag.createParam("tag") .setDefaultValue("xoo") .setDescription("The tag to search for"); - NewRule ruleWithParameters = repo.createRule("RuleWithParameters").setName("Rule with parameters") - .setHtmlDescription("Rule containing parameter of different types : boolean, integer, etc. For information, no issue will be linked to this rule."); + NewRule ruleWithParameters = repo.createRule("RuleWithParameters").setName("Rule with parameters"); + addAllDescriptionSections(ruleWithParameters, + "Rule containing parameter of different types : boolean, integer, etc. For information, no issue will be linked to this rule."); ruleWithParameters.createParam("string").setType(RuleParamType.STRING); ruleWithParameters.createParam("text").setType(RuleParamType.TEXT); ruleWithParameters.createParam("boolean").setType(RuleParamType.BOOLEAN); @@ -99,106 +107,112 @@ public class XooRulesDefinition implements RulesDefinition { ruleWithParameters.createParam("float").setType(RuleParamType.FLOAT); NewRule oneIssuePerLine = repo.createRule(OneIssuePerLineSensor.RULE_KEY).setName("One Issue Per Line") - .setHtmlDescription("Generate an issue on each line of a file. It requires the metric \"lines\".") .setTags("line"); + addAllDescriptionSections(oneIssuePerLine, "Generate an issue on each line of a file. It requires the metric \"lines\"."); oneIssuePerLine .setDebtRemediationFunction(oneIssuePerLine.debtRemediationFunctions().linear("1min")) .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code"); NewRule oneQuickFixPerLine = repo.createRule(OneQuickFixPerLineSensor.RULE_KEY).setName("One Quick Fix Per Line") - .setHtmlDescription("Generate an issue with quick fix available on each line of a file. It requires the metric \"lines\".") .setTags("line"); + addAllDescriptionSections(oneQuickFixPerLine, + "Generate an issue with quick fix available on each line of a file. It requires the metric \"lines\"."); + oneQuickFixPerLine .setDebtRemediationFunction(oneQuickFixPerLine.debtRemediationFunctions().linear("1min")) .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code"); - repo.createRule(OneIssueOnDirPerFileSensor.RULE_KEY).setName("One Issue On Dir Per File") - .setHtmlDescription("Generate issues on directories"); - - NewRule oneIssuePerFile = repo.createRule(OneIssuePerFileSensor.RULE_KEY).setName("One Issue Per File") - .setHtmlDescription("Generate an issue on each file"); + NewRule oneIssueOnDirPerFile = repo.createRule(OneIssueOnDirPerFileSensor.RULE_KEY).setName("One Issue On Dir Per File"); + addAllDescriptionSections(oneIssueOnDirPerFile, + "Generate issues on directories"); + NewRule oneIssuePerFile = repo.createRule(OneIssuePerFileSensor.RULE_KEY).setName("One Issue Per File"); oneIssuePerFile.setDebtRemediationFunction(oneIssuePerFile.debtRemediationFunctions().linear(TEN_MIN)); + addAllDescriptionSections(oneIssuePerFile, "Generate an issue on each file"); NewRule oneIssuePerTestFile = repo.createRule(OneIssuePerTestFileSensor.RULE_KEY).setName("One Issue Per Test File") - .setScope(RuleScope.TEST) - .setHtmlDescription("Generate an issue on each test file"); + .setScope(RuleScope.TEST); oneIssuePerTestFile.setDebtRemediationFunction(oneIssuePerTestFile.debtRemediationFunctions().linear("8min")); + addAllDescriptionSections(oneIssuePerTestFile, "Generate an issue on each test file"); NewRule oneBugIssuePerTestLine = repo.createRule(OneBugIssuePerTestLineSensor.RULE_KEY).setName("One Bug Issue Per Test Line") .setScope(RuleScope.TEST) - .setHtmlDescription("Generate a bug issue on each line of a test file. It requires the metric \"lines\".") .setType(RuleType.BUG); + addAllDescriptionSections(oneBugIssuePerTestLine, "Generate a bug issue on each line of a test file. It requires the metric \"lines\"."); + oneBugIssuePerTestLine .setDebtRemediationFunction(oneBugIssuePerTestLine.debtRemediationFunctions().linear("4min")); NewRule oneCodeSmellIssuePerTestLine = repo.createRule(OneCodeSmellIssuePerTestLineSensor.RULE_KEY).setName("One Code Smell Issue Per Test Line") .setScope(RuleScope.TEST) - .setHtmlDescription("Generate a code smell issue on each line of a test file. It requires the metric \"lines\".") .setType(RuleType.CODE_SMELL); + addAllDescriptionSections(oneCodeSmellIssuePerTestLine, "Generate a code smell issue on each line of a test file. It requires the metric \"lines\"."); + oneCodeSmellIssuePerTestLine .setDebtRemediationFunction(oneCodeSmellIssuePerTestLine.debtRemediationFunctions().linear("3min")); - NewRule oneIssuePerDirectory = repo.createRule(OneIssuePerDirectorySensor.RULE_KEY).setName("One Issue Per Directory") - .setHtmlDescription("Generate an issue on each non-empty directory"); + NewRule oneIssuePerDirectory = repo.createRule(OneIssuePerDirectorySensor.RULE_KEY).setName("One Issue Per Directory"); oneIssuePerDirectory.setDebtRemediationFunction(oneIssuePerDirectory.debtRemediationFunctions().linear(TEN_MIN)); + addAllDescriptionSections(oneIssuePerDirectory, "Generate an issue on each non-empty directory"); - NewRule oneDayDebtPerFile = repo.createRule(OneDayDebtPerFileSensor.RULE_KEY).setName("One Day Debt Per File") - .setHtmlDescription("Generate an issue on each file with a debt of one day"); + NewRule oneDayDebtPerFile = repo.createRule(OneDayDebtPerFileSensor.RULE_KEY).setName("One Day Debt Per File"); oneDayDebtPerFile.setDebtRemediationFunction(oneDayDebtPerFile.debtRemediationFunctions().linear("1d")); + addAllDescriptionSections(oneDayDebtPerFile, "Generate an issue on each file with a debt of one day"); - NewRule oneIssuePerModule = repo.createRule(OneIssuePerModuleSensor.RULE_KEY).setName("One Issue Per Module") - .setHtmlDescription("Generate an issue on each module"); + NewRule oneIssuePerModule = repo.createRule(OneIssuePerModuleSensor.RULE_KEY).setName("One Issue Per Module"); oneIssuePerModule .setDebtRemediationFunction(oneIssuePerModule.debtRemediationFunctions().linearWithOffset("25min", "1h")) .setGapDescription("A certified architect will need roughly half an hour to start working on removal of modules, " + "then it's about one hour per module."); + addAllDescriptionSections(oneIssuePerModule, "Generate an issue on each module"); - repo.createRule(OneBlockerIssuePerFileSensor.RULE_KEY).setName("One Blocker Issue Per File") - .setHtmlDescription("Generate a blocker issue on each file, whatever the severity declared in the Quality profile"); + NewRule oneBlockerIssuePerFile = repo.createRule(OneBlockerIssuePerFileSensor.RULE_KEY).setName("One Blocker Issue Per File"); + addAllDescriptionSections(oneBlockerIssuePerFile, "Generate a blocker issue on each file, whatever the severity declared in the Quality profile"); - repo.createRule(CustomMessageSensor.RULE_KEY).setName("Issue With Custom Message") - .setHtmlDescription("Generate an issue on each file with a custom message"); + NewRule issueWithCustomMessage = repo.createRule(CustomMessageSensor.RULE_KEY).setName("Issue With Custom Message"); + addAllDescriptionSections(issueWithCustomMessage, "Generate an issue on each file with a custom message"); - repo.createRule(RandomAccessSensor.RULE_KEY).setName("One Issue Per File with Random Access") - .setHtmlDescription("This issue is generated on each file"); + NewRule oneIssuePerFileWithRandomAccess = repo.createRule(RandomAccessSensor.RULE_KEY).setName("One Issue Per File with Random Access"); + addAllDescriptionSections(oneIssuePerFileWithRandomAccess, "This issue is generated on each file"); - repo.createRule(MultilineIssuesSensor.RULE_KEY).setName("Creates issues with ranges/multiple locations") - .setHtmlDescription("Issue with range and multiple locations"); + NewRule issueWithRangeAndMultipleLocations = repo.createRule(MultilineIssuesSensor.RULE_KEY).setName("Creates issues with ranges/multiple locations"); + addAllDescriptionSections(issueWithRangeAndMultipleLocations, "Issue with range and multiple locations"); - repo.createRule(OneIssuePerUnknownFileSensor.RULE_KEY).setName("Creates issues on each file with extension 'unknown'") - .setHtmlDescription("This issue is generated on each file with extenstion 'unknown'"); + NewRule issueOnEachFileWithExtUnknown = repo.createRule(OneIssuePerUnknownFileSensor.RULE_KEY).setName("Creates issues on each file with extension 'unknown'"); + addAllDescriptionSections(issueOnEachFileWithExtUnknown, "This issue is generated on each file with extenstion 'unknown'"); NewRule oneBugIssuePerLine = repo.createRule(OneBugIssuePerLineSensor.RULE_KEY).setName("One Bug Issue Per Line") - .setHtmlDescription("Generate a bug issue on each line of a file. It requires the metric \"lines\".") .setType(RuleType.BUG); oneBugIssuePerLine .setDebtRemediationFunction(oneBugIssuePerLine.debtRemediationFunctions().linear("5min")); + addAllDescriptionSections(oneBugIssuePerLine, "Generate a bug issue on each line of a file. It requires the metric \"lines\"."); NewRule oneCodeSmellIssuePerLine = repo.createRule(OneCodeSmellIssuePerLineSensor.RULE_KEY).setName("One Code Smell Issue Per Line") - .setHtmlDescription("Generate a code smell issue on each line of a file. It requires the metric \"lines\".") .setType(RuleType.CODE_SMELL); oneCodeSmellIssuePerLine - .setDebtRemediationFunction(oneBugIssuePerLine.debtRemediationFunctions().linear("9min")); + .setDebtRemediationFunction(oneCodeSmellIssuePerLine.debtRemediationFunctions().linear("9min")); + addAllDescriptionSections(oneCodeSmellIssuePerLine, "Generate a code smell issue on each line of a file. It requires the metric \"lines\"."); NewRule oneVulnerabilityIssuePerModule = repo.createRule(OneVulnerabilityIssuePerModuleSensor.RULE_KEY).setName("One Vulnerability Issue Per Module") - .setHtmlDescription("Generate an issue on each module") .setType(RuleType.VULNERABILITY); + addAllDescriptionSections(oneVulnerabilityIssuePerModule, "Generate an issue on each module"); + oneVulnerabilityIssuePerModule .setDebtRemediationFunction(oneVulnerabilityIssuePerModule.debtRemediationFunctions().linearWithOffset("25min", "1h")) .setGapDescription("A certified architect will need roughly half an hour to start working on removal of modules, " + "then it's about one hour per module."); - repo + NewRule templateofRule = repo .createRule("xoo-template") .setTemplate(true) - .setName("Template of rule") - .setHtmlDescription("Template to be overridden by custom rules"); + .setName("Template of rule"); + addAllDescriptionSections(templateofRule, "Template to be overridden by custom rules"); NewRule hotspot = repo.createRule(HotspotSensor.RULE_KEY) .setName("Find security hotspots") .setType(RuleType.SECURITY_HOTSPOT) - .setActivatedByDefault(false) - .setHtmlDescription("Search for Security Hotspots in Xoo files"); + .setActivatedByDefault(false); + addAllDescriptionSections(hotspot, "Search for Security Hotspots in Xoo files"); + hotspot .setDebtRemediationFunction(hotspot.debtRemediationFunctions().constantPerIssue("2min")); @@ -225,10 +239,30 @@ public class XooRulesDefinition implements RulesDefinition { .setType(OnePredefinedRuleExternalIssuePerLineSensor.TYPE) .setScope(RuleScope.ALL) .setHtmlDescription("Generates one external issue in each line") + .addDescriptionSection(descriptionSection(INTRODUCTION_SECTION_KEY, "Generates one external issue in each line")) .setName("One external issue per line") .setTags("riri", "fifi", "loulou"); repo.done(); } + private static void addAllDescriptionSections(NewRule rule, String description) { + rule + .setHtmlDescription(description) + .addDescriptionSection(descriptionSection(INTRODUCTION_SECTION_KEY, "Introduction: " + description)) + .addDescriptionSection(descriptionSection(ROOT_CAUSE_SECTION_KEY, "Root cause: " + description)) + .addDescriptionSection(descriptionSection(ASSESS_THE_PROBLEM_SECTION_KEY, "Assess the problem: " + description)) + .addDescriptionSection(descriptionSection(HOW_TO_FIX_SECTION_KEY, "How to fix: " + description)) + .addDescriptionSection(descriptionSection(RESOURCES_SECTION_KEY, + " Google
StackOverflow")) + .addDescriptionSection(descriptionSection("fake_section_to_be_ignored", + "fake_section_to_be_ignored")); + } + + private static RuleDescriptionSection descriptionSection(String sectionKey, String htmlDescription) { + return RuleDescriptionSection.builder() + .sectionKey(sectionKey) + .htmlContent(htmlDescription) + .build(); + } } -- 2.39.5