*/
package org.sonar.server.rule;
+import java.util.Arrays;
+import java.util.List;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
import org.sonar.api.resources.Language;
import org.sonar.api.resources.Languages;
import org.sonar.api.rule.Severity;
import org.sonar.api.server.rule.RuleParamType;
import org.sonar.api.server.rule.RulesDefinition;
+import static org.sonar.api.rule.RuleStatus.DEPRECATED;
import static org.sonar.server.rule.CommonRuleKeys.commonRepositoryForLang;
/**
// It replaces the common-rules that are still embedded within plugins.
public class CommonRuleDefinitionsImpl implements CommonRuleDefinitions {
+ private static final List<String> LANGUAGES_TO_SKIP = List.of("terraform", "cloudformation", "web", "css", "xml", "yaml", "json", "jsp");
+ private static final String MINUTES_10 = "10min";
+
private final Languages languages;
public CommonRuleDefinitionsImpl(Languages languages) {
@Override
public void define(RulesDefinition.Context context) {
- for (Language language : languages.all()) {
+ for (Language language : getActiveLanguages(languages.all())) {
RulesDefinition.NewRepository repo = context.createRepository(commonRepositoryForLang(language.getKey()), language.getKey());
repo.setName("Common " + language.getName());
defineBranchCoverageRule(repo);
}
}
+ private static List<Language> getActiveLanguages(Language[] allLanguages) {
+ return Arrays.stream(allLanguages)
+ .filter(Predicate.not(language -> LANGUAGES_TO_SKIP.contains(language.getKey())))
+ .collect(Collectors.toList());
+ }
+
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")
.setName("The minimum required branch coverage ratio")
.setDefaultValue("65")
.setType(RuleParamType.FLOAT);
+ rule.setStatus(DEPRECATED);
}
private static void defineLineCoverageRule(RulesDefinition.NewRepository repo) {
.setName("The minimum required line coverage ratio")
.setDefaultValue("65")
.setType(RuleParamType.FLOAT);
+ rule.setStatus(DEPRECATED);
}
private static void defineCommentDensityRule(RulesDefinition.NewRepository repo) {
.setName("The minimum required comment density")
.setDefaultValue("25")
.setType(RuleParamType.FLOAT);
+ rule.setStatus(DEPRECATED);
}
private static void defineDuplicatedBlocksRule(RulesDefinition.NewRepository repo) {
rule.setName("Source files should not have any duplicated blocks")
.addTags("pitfall")
.setHtmlDescription("An issue is created on a file as soon as there is at least one block of duplicated code on this file")
- .setDebtRemediationFunction(rule.debtRemediationFunctions().linearWithOffset("10min", "10min"))
+ .setDebtRemediationFunction(rule.debtRemediationFunctions().linearWithOffset(MINUTES_10, MINUTES_10))
.setGapDescription("number of duplicate blocks")
- .setSeverity(Severity.MAJOR);
+ .setSeverity(Severity.MAJOR)
+ .setStatus(DEPRECATED);
}
private static void defineFailedUnitTestRule(RulesDefinition.NewRepository repo) {
.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"))
+ .setDebtRemediationFunction(rule.debtRemediationFunctions().linear(MINUTES_10))
.setGapDescription("number of failed tests")
- .setSeverity(Severity.MAJOR);
+ .setSeverity(Severity.MAJOR)
+ .setStatus(DEPRECATED);
}
private static void defineSkippedUnitTestRule(RulesDefinition.NewRepository repo) {
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"))
+ .setDebtRemediationFunction(rule.debtRemediationFunctions().linear(MINUTES_10))
.setGapDescription("number of skipped tests")
- .setSeverity(Severity.MAJOR);
+ .setSeverity(Severity.MAJOR)
+ .setStatus(DEPRECATED);
}
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.server.rule;
+
+import org.junit.Test;
+import org.sonar.api.impl.server.RulesDefinitionContext;
+import org.sonar.api.resources.AbstractLanguage;
+import org.sonar.api.resources.Language;
+import org.sonar.api.resources.Languages;
+import org.sonar.api.server.rule.RulesDefinition;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.sonar.api.rule.RuleStatus.DEPRECATED;
+
+public class CommonRuleDefinitionsImplTest {
+
+ @Test
+ public void instantiate_common_rules_for_correct_languages_only() {
+ CommonRuleDefinitionsImpl commonRuleDefinitions = new CommonRuleDefinitionsImpl(getLanguages());
+ RulesDefinition.Context underTest = new RulesDefinitionContext();
+ commonRuleDefinitions.define(underTest);
+
+ assertThat(underTest.repositories()).hasSize(3);
+ assertThat(underTest.repository("common-java")).isNotNull();
+ assertThat(underTest.repository("common-php")).isNotNull();
+ assertThat(underTest.repository("common-js")).isNotNull();
+
+ for (RulesDefinition.Repository repository : underTest.repositories()) {
+ assertThat(repository.rules()).hasSize(6);
+ for (RulesDefinition.Rule rule : repository.rules()) {
+ assertThat(rule.status()).isEqualTo(DEPRECATED);
+ }
+ }
+ }
+
+ private Languages getLanguages() {
+ return new Languages(
+ createLanguage("java"),
+ createLanguage("php"),
+ createLanguage("js"),
+ createLanguage("terraform"),
+ createLanguage("cloudformation"),
+ createLanguage("web"),
+ createLanguage("css"),
+ createLanguage("xml"),
+ createLanguage("yaml"),
+ createLanguage("json"),
+ createLanguage("jsp")
+ );
+ }
+
+ private Language createLanguage(String languageKey) {
+ return new AbstractLanguage(languageKey, languageKey + "_name") {
+ @Override
+ public String[] getFileSuffixes() {
+ return new String[0];
+ }
+ };
+ }
+
+}