|
|
@@ -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, |
|
|
|
"<a href=\"www.google.fr\"> Google </a><br><a href=\"https://stackoverflow.com/\"> StackOverflow</a>")) |
|
|
|
.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(); |
|
|
|
} |
|
|
|
} |