private static DebtRemediationFunction remediationFunction(DebtRemediationFunction.Type function, @Nullable String coefficient, @Nullable String offset, RulesDefinition.DebtRemediationFunctions functions, String repoKey, String ruleKey) { if (DebtRemediationFunction.Type.LINEAR.equals(function) && coefficient != null) { return functions.linear(coefficient); } else if (DebtRemediationFunction.Type.CONSTANT_ISSUE.equals(function) && offset != null) { return functions.constantPerIssue(offset); } else if (DebtRemediationFunction.Type.LINEAR_OFFSET.equals(function) && coefficient != null && offset != null) { return functions.linearWithOffset(coefficient, offset); } else { throw new IllegalArgumentException(String.format("Debt definition on rule '%s:%s' is invalid", repoKey, ruleKey)); } }
public DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) { if (func.startsWith("Constant")) { return drf.constantPerIssue(constantCost.replace("mn", "min")); } if ("Linear".equals(func)) { return drf.linear(linearFactor.replace("mn", "min")); } return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min")); } }
public DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) { if(func.startsWith("Constant")) { return drf.constantPerIssue(constantCost.replace("mn", "min")); } if("Linear".equals(func)) { return drf.linear(linearFactor.replace("mn", "min")); } return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min")); } }
private static void defineFailedUnitTestRule(RulesDefinition.NewRepository repo) { RulesDefinition.NewRule rule = repo.createRule(CommonRuleKeys.FAILED_UNIT_TESTS); rule .setName("Failed unit tests should be fixed") .addTags("bug") .setHtmlDescription( "Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.") .setDebtRemediationFunction(rule.debtRemediationFunctions().linear("10min")) .setGapDescription("number of failed tests") .setSeverity(Severity.MAJOR); }
@Override public boolean setRemediation(NewRule sonarRule, SqaleRemediation remediation) { if(remediation instanceof SqaleLinearRemediation) { SqaleLinearRemediation linearRemediation = (SqaleLinearRemediation) remediation; sonarRule.setDebtRemediationFunction(sonarRule.debtRemediationFunctions().linear(linearRemediation.getCoeff())); sonarRule.setEffortToFixDescription(linearRemediation.getEffortToFixDescription()); return true; } else { return false; } }
private static void addRemediationCost(Collection<NewRule> rules) { Map<String, String> costByRule = getCostByRule(); for (NewRule newRule : rules) { String ruleKey = newRule.key(); if (costByRule.containsKey(ruleKey)) { DebtRemediationFunction linear = newRule.debtRemediationFunctions().linear(costByRule.get(ruleKey)); newRule.setDebtRemediationFunction(linear); } } }
private static void addRemediationCost(Collection<NewRule> rules) { Map<String, String> costByRule = getCostByRule(); for (NewRule newRule : rules) { String ruleKey = newRule.key(); if (costByRule.containsKey(ruleKey)) { DebtRemediationFunction linear = newRule.debtRemediationFunctions().linear(costByRule.get(ruleKey)); newRule.setDebtRemediationFunction(linear); } } }
private DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) { if (func.startsWith("Constant")) { return drf.constantPerIssue(constantCost.replace("mn", "min")); } if ("Linear".equals(func)) { return drf.linear(linearFactor.replace("mn", "min")); } return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min")); } }
public DebtRemediationFunction remediationFunction(DebtRemediationFunctions debt) { if (func.startsWith("Constant")) { return debt.constantPerIssue(constantCost.replace("mn", "min")); } if ("Linear".equals(func)) { return debt.linear(linearFactor.replace("mn", "min")); } return debt.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min")); } }
private static void defineSkippedUnitTestRule(RulesDefinition.NewRepository repo) { RulesDefinition.NewRule rule = repo.createRule(CommonRuleKeys.SKIPPED_UNIT_TESTS); rule.setName("Skipped unit tests should be either removed or fixed") .addTags("pitfall") .setHtmlDescription("Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.") .setDebtRemediationFunction(rule.debtRemediationFunctions().linear("10min")) .setGapDescription("number of skipped tests") .setSeverity(Severity.MAJOR); } }
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 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\"."); oneIssuePerLine .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("1min")) .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code"); repo.done(); }
private DebtRemediationFunction remediationFunction(DebtRemediationFunctions functions, String remediationFunction, String offset, String remediationFactor) { if ("CONSTANT_ISSUE".equalsIgnoreCase(remediationFunction)) { return functions.constantPerIssue(offset); } else if ("LINEAR".equalsIgnoreCase(remediationFunction)) { return functions.linear(remediationFactor); } else if ("LINEAR_OFFSET".equalsIgnoreCase(remediationFunction)) { return functions.linearWithOffset(remediationFactor, offset); } return null; }
private static DebtRemediationFunction remediationFunction(DebtRemediationFunction.Type function, @Nullable String coefficient, @Nullable String offset, RulesDefinition.DebtRemediationFunctions functions, String repoKey, String ruleKey) { if (DebtRemediationFunction.Type.LINEAR.equals(function) && coefficient != null) { return functions.linear(coefficient); } else if (DebtRemediationFunction.Type.CONSTANT_ISSUE.equals(function) && offset != null) { return functions.constantPerIssue(offset); } else if (DebtRemediationFunction.Type.LINEAR_OFFSET.equals(function) && coefficient != null && offset != null) { return functions.linearWithOffset(coefficient, offset); } else { throw new IllegalArgumentException(String.format("Debt definition on rule '%s:%s' is invalid", repoKey, ruleKey)); } }
.setHtmlDescription("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"); oneIssuePerFile.setDebtRemediationFunction(oneIssuePerFile.debtRemediationFunctions().linear(TEN_MIN)); oneIssuePerTestFile.setDebtRemediationFunction(oneIssuePerTestFile.debtRemediationFunctions().linear(TEN_MIN)); oneIssuePerDirectory.setDebtRemediationFunction(oneIssuePerDirectory.debtRemediationFunctions().linear(TEN_MIN)); oneDayDebtPerFile.setDebtRemediationFunction(oneDayDebtPerFile.debtRemediationFunctions().linear("1d")); .setType(RuleType.BUG); oneBugIssuePerLine .setDebtRemediationFunction(oneBugIssuePerLine.debtRemediationFunctions().linear("5min"));
private static void defineCommentDensityRule(RulesDefinition.NewRepository repo) { RulesDefinition.NewRule rule = repo.createRule(CommonRuleKeys.INSUFFICIENT_COMMENT_DENSITY); rule.setName("Source files should have a sufficient density of comment lines") .addTags("convention") .setHtmlDescription("An issue is created on a file as soon as the density of comment lines on this file is less than the required threshold. " + "The number of comment lines to be written in order to reach the required threshold is provided by each issue message.") .setDebtRemediationFunction(rule.debtRemediationFunctions().linear("2min")) .setGapDescription("number of lines required to meet minimum density") .setSeverity(Severity.MAJOR); rule.createParam(CommonRuleKeys.INSUFFICIENT_COMMENT_DENSITY_PROPERTY) .setName("The minimum required comment density") .setDefaultValue("25") .setType(RuleParamType.FLOAT); }
private static void defineLineCoverageRule(RulesDefinition.NewRepository repo) { RulesDefinition.NewRule rule = repo.createRule(CommonRuleKeys.INSUFFICIENT_LINE_COVERAGE); rule.setName("Lines should have sufficient coverage by tests") .addTags("bad-practice") .setHtmlDescription("An issue is created on a file as soon as the line coverage on this file is less than the required threshold. " + "It gives the number of lines to be covered in order to reach the required threshold.") .setDebtRemediationFunction(rule.debtRemediationFunctions().linear("2min")) .setGapDescription("number of lines under the coverage threshold") .setSeverity(Severity.MAJOR); rule.createParam(CommonRuleKeys.INSUFFICIENT_LINE_COVERAGE_PROPERTY) .setName("The minimum required line coverage ratio") .setDefaultValue("65") .setType(RuleParamType.FLOAT); }
private static void defineBranchCoverageRule(RulesDefinition.NewRepository repo) { RulesDefinition.NewRule rule = repo.createRule(CommonRuleKeys.INSUFFICIENT_BRANCH_COVERAGE); rule.setName("Branches should have sufficient coverage by tests") .addTags("bad-practice") .setHtmlDescription("An issue is created on a file as soon as the branch coverage on this file is less than the required threshold. " + "It gives the number of branches to be covered in order to reach the required threshold.") .setDebtRemediationFunction(rule.debtRemediationFunctions().linear("5min")) .setGapDescription("number of uncovered conditions") .setSeverity(Severity.MAJOR); rule.createParam(CommonRuleKeys.INSUFFICIENT_BRANCH_COVERAGE_PROPERTY) .setName("The minimum required branch coverage ratio") .setDefaultValue("65") .setType(RuleParamType.FLOAT); }
private static void defineFailedUnitTestRule(RulesDefinition.NewRepository repo) { RulesDefinition.NewRule rule = repo.createRule(CommonRuleKeys.FAILED_UNIT_TESTS); rule .setName("Failed unit tests should be fixed") .addTags("bug") .setHtmlDescription( "Test failures or errors generally indicate that regressions have been introduced. Those tests should be handled as soon as possible to reduce the cost to fix the corresponding regressions.") .setDebtRemediationFunction(rule.debtRemediationFunctions().linear("10min")) .setGapDescription("number of failed tests") .setSeverity(Severity.MAJOR); }
private static void defineSkippedUnitTestRule(RulesDefinition.NewRepository repo) { RulesDefinition.NewRule rule = repo.createRule(CommonRuleKeys.SKIPPED_UNIT_TESTS); rule.setName("Skipped unit tests should be either removed or fixed") .addTags("pitfall") .setHtmlDescription("Skipped unit tests are considered as dead code. Either they should be activated again (and updated) or they should be removed.") .setDebtRemediationFunction(rule.debtRemediationFunctions().linear("10min")) .setGapDescription("number of skipped tests") .setSeverity(Severity.MAJOR); } }
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 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\"."); oneIssuePerLine .setDebtRemediationFunction(hasTag.debtRemediationFunctions().linear("1min")) .setGapDescription("It takes about 1 minute to an experienced software craftsman to remove a line of code"); repo.done(); }