]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10321 Add scope to rule definition API
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Mon, 29 Jan 2018 16:09:19 +0000 (17:09 +0100)
committerGrégoire Aubert <gregoire.aubert@sonarsource.com>
Wed, 7 Feb 2018 10:32:38 +0000 (11:32 +0100)
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v71/SetRuleScopeToMainTest.java
server/sonar-server/src/main/java/org/sonar/server/rule/RegisterRules.java
server/sonar-server/src/main/java/org/sonar/server/rule/RuleCreator.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/SearchAction.java
server/sonar-server/src/test/java/org/sonar/server/rule/RegisterRulesTest.java
sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleScope.java [new file with mode: 0644]
sonar-plugin-api/src/main/java/org/sonar/api/server/rule/RulesDefinition.java
sonar-plugin-api/src/test/java/org/sonar/api/server/rule/RulesDefinitionTest.java

index fa1cb855b2bb601ea392ee0999a4383b28525456..70f8d253b460bc37a61d53b2488c2ea4aa69e48d 100644 (file)
@@ -37,7 +37,7 @@ public class XooPluginTest {
     SonarRuntime runtime = SonarRuntimeImpl.forSonarLint(Version.parse("5.4"));
     Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
     new XooPlugin().define(context);
-    assertThat(context.getExtensions()).hasSize(46).doesNotContain(CpdTokenizerSensor.class);
+    assertThat(context.getExtensions()).hasSize(47).doesNotContain(CpdTokenizerSensor.class);
   }
 
   @Test
@@ -45,7 +45,7 @@ public class XooPluginTest {
     SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER);
     Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
     new XooPlugin().define(context);
-    assertThat(context.getExtensions()).hasSize(49).contains(CpdTokenizerSensor.class);
+    assertThat(context.getExtensions()).hasSize(50).contains(CpdTokenizerSensor.class);
   }
 
   @Test
@@ -53,6 +53,6 @@ public class XooPluginTest {
     SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("6.6"), SonarQubeSide.SCANNER);
     Plugin.Context context = new PluginContextImpl.Builder().setSonarRuntime(runtime).build();
     new XooPlugin().define(context);
-    assertThat(context.getExtensions()).hasSize(50).contains(CpdTokenizerSensor.class);
+    assertThat(context.getExtensions()).hasSize(51).contains(CpdTokenizerSensor.class);
   }
 }
index bee42dd03497a397054609787cff6845c2940b0e..7de2430f0c15ac5215c0c7237804639110d12dbf 100644 (file)
@@ -42,7 +42,7 @@ public class XooRulesDefinitionTest {
     assertThat(repo).isNotNull();
     assertThat(repo.name()).isEqualTo("Xoo");
     assertThat(repo.language()).isEqualTo("xoo");
-    assertThat(repo.rules()).hasSize(18);
+    assertThat(repo.rules()).hasSize(19);
 
     RulesDefinition.Rule rule = repo.rule(OneIssuePerLineSensor.RULE_KEY);
     assertThat(rule.name()).isNotEmpty();
index 0a8c8b1398c7cdc9b6c5ab0ebfc95f3d4b2df003..4bcc99ae3a5254e2a451851cf92acfbcdf2305a2 100644 (file)
@@ -43,21 +43,6 @@ public class SetRuleScopeToMainTest {
     assertThat(countRowsWithValue(RuleScope.MAIN)).isEqualTo(2);
   }
 
-  @Test
-  public void support_large_number_of_rows() throws SQLException {
-    for (int i = 0; i < 2_000; i++) {
-      insertRow(i, null);
-    }
-
-    assertThat(countRowsWithValue(null)).isEqualTo(2000);
-    assertThat(countRowsWithValue(RuleScope.MAIN)).isZero();
-
-    underTest.execute();
-
-    assertThat(countRowsWithValue(RuleScope.MAIN)).isEqualTo(2_000);
-    assertThat(countRowsWithValue(null)).isEqualTo(0);
-  }
-
   @Test
   public void execute_is_reentreant() throws SQLException {
     insertRow(1, null);
index b41ec39163bb355b11cb08be5dee8687d65c54ca..3920e843356134be997c3a55a32e897d3190f226 100644 (file)
@@ -35,6 +35,7 @@ import org.apache.commons.lang.StringUtils;
 import org.picocontainer.Startable;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleScope;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rules.RuleType;
 import org.sonar.api.server.debt.DebtRemediationFunction;
@@ -242,7 +243,7 @@ public class RegisterRules implements Startable {
     return ruleDto;
   }
 
-  private static Scope toDtoScope(RulesDefinition.Scope scope) {
+  private static Scope toDtoScope(RuleScope scope) {
     switch (scope) {
       case ALL:
         return Scope.ALL;
index 98d5fc4a35006d17ee3ed824abf94e79e744cbaa..04e5d624d7b33daf6d3494f0f251adaec96e2a66 100644 (file)
@@ -172,6 +172,7 @@ public class RuleCreator {
       .setDefRemediationGapMultiplier(templateRuleDto.getDefRemediationGapMultiplier())
       .setDefRemediationBaseEffort(templateRuleDto.getDefRemediationBaseEffort())
       .setGapDescription(templateRuleDto.getGapDescription())
+      .setScope(templateRuleDto.getScope())
       .setSystemTags(templateRuleDto.getSystemTags())
       .setCreatedAt(system2.now())
       .setUpdatedAt(system2.now());
index c95096ddb9cc619035120f7d4ea541d8e95eb81b..54bb7015319e999af7f81ee4f9e8143463195560 100644 (file)
@@ -40,6 +40,7 @@ import org.sonar.api.rule.RuleKey;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
+import org.sonar.api.server.ws.Change;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -130,7 +131,9 @@ public class SearchAction implements RulesWsAction {
   public void define(WebService.NewController controller) {
     WebService.NewAction action = controller.createAction(ACTION)
       .addPagingParams(100, MAX_LIMIT)
-      .setHandler(this);
+      .setHandler(this)
+      .setChangelog(new Change("7.1", "The field 'scope' has been added to the response"))
+      .setChangelog(new Change("7.1", "The field 'scope' has been added to the 'f' parameter"));
 
     action.createParam(FACETS)
       .setDescription("Comma-separated list of the facets to be computed. No facet is computed by default.")
@@ -145,9 +148,9 @@ public class SearchAction implements RulesWsAction {
         "<li>\"debtRemFn\" becomes \"remFn\"</li>" +
         "<li>\"effortToFixDescription\" becomes \"gapDescription\"</li>" +
         "<li>\"debtOverloaded\" becomes \"remFnOverloaded\"</li>" +
-        "</ul>" +
-        "In 7.1, the field 'scope' has been added.")
+        "</ul>")
       .setPossibleValues(Ordering.natural().sortedCopy(OPTIONAL_FIELDS));
+
     Iterator<String> it = OPTIONAL_FIELDS.iterator();
     paramFields.setExampleValue(format("%s,%s", it.next(), it.next()));
     doDefinition(action);
@@ -191,8 +194,7 @@ public class SearchAction implements RulesWsAction {
       "<li>\"debtRemFnOffset\" becomes \"remFnBaseEffort\"</li>" +
       "<li>\"defaultDebtRemFnOffset\" becomes \"defaultRemFnBaseEffort\"</li>" +
       "<li>\"debtOverloaded\" becomes \"remFnOverloaded\"</li>" +
-      "</ul>" +
-      "In 7.1, a new field 'scope' has been added to the response.")
+      "</ul>")
       .setResponseExample(getClass().getResource("search-example.json"))
       .setSince("4.4")
       .setHandler(this);
index ba26b7075ebf9163852f72c69b7662055d0485fb..4bf6459bf56be049dff5c05452c35aee81b0ab45 100644 (file)
@@ -28,6 +28,7 @@ import org.sonar.api.config.internal.MapSettings;
 import org.sonar.api.resources.Language;
 import org.sonar.api.resources.Languages;
 import org.sonar.api.rule.RuleKey;
+import org.sonar.api.rule.RuleScope;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rules.RuleType;
 import org.sonar.api.server.debt.DebtRemediationFunction;
@@ -565,7 +566,7 @@ public class RegisterRulesTest {
         .setSeverity(BLOCKER)
         .setInternalKey("config1")
         .setTags("tag1", "tag2", "tag3")
-        .setScope(Scope.ALL)
+        .setScope(RuleScope.ALL)
         .setType(RuleType.CODE_SMELL)
         .setStatus(RuleStatus.BETA)
         .setGapDescription("squid.S115.effortToFix");
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleScope.java b/sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleScope.java
new file mode 100644 (file)
index 0000000..2d476e2
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.api.rule;
+
+/**
+ * @since 7.1
+ *
+ */
+public enum RuleScope {
+  MAIN, TEST, ALL;
+
+  public static RuleScope defaultScope() {
+    return MAIN;
+  }
+}
index 58f3d47b9e6eb857684649ff4c8ca606e3f5e426..c7633fc3c545e5c0d82b41ea80cee63db01d2c37 100644 (file)
@@ -38,6 +38,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.ExtensionPoint;
 import org.sonar.api.ce.ComputeEngineSide;
+import org.sonar.api.rule.RuleScope;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
@@ -693,7 +694,7 @@ public interface RulesDefinition {
     private final Map<String, NewParam> paramsByKey = new HashMap<>();
     private final DebtRemediationFunctions functions;
     private boolean activatedByDefault;
-    private Scope scope;
+    private RuleScope scope;
 
     private NewRule(@Nullable String pluginKey, String repoKey, String key) {
       this.pluginKey = pluginKey;
@@ -710,14 +711,14 @@ public interface RulesDefinition {
      * @since 7.1
      */
     @CheckForNull
-    public Scope scope() {
+    public RuleScope scope() {
       return this.scope;
     }
 
     /**
      * @since 7.1
      */
-    public NewRule setScope(Scope scope) {
+    public NewRule setScope(RuleScope scope) {
       this.scope = scope;
       return this;
     }
@@ -967,7 +968,7 @@ public interface RulesDefinition {
     private final Map<String, Param> params;
     private final RuleStatus status;
     private final boolean activatedByDefault;
-    private final Scope scope;
+    private final RuleScope scope;
 
     private Rule(Repository repository, NewRule newRule) {
       this.pluginKey = newRule.pluginKey;
@@ -983,7 +984,7 @@ public interface RulesDefinition {
       this.status = newRule.status;
       this.debtRemediationFunction = newRule.debtRemediationFunction;
       this.gapDescription = newRule.gapDescription;
-      this.scope = newRule.scope == null ? Scope.MAIN : newRule.scope;
+      this.scope = newRule.scope == null ? RuleScope.MAIN : newRule.scope;
       this.type = newRule.type == null ? RuleTagsToTypeConverter.convert(newRule.tags) : newRule.type;
       this.tags = ImmutableSortedSet.copyOf(Sets.difference(newRule.tags, RuleTagsToTypeConverter.RESERVED_TAGS));
       Map<String, Param> paramsBuilder = new HashMap<>();
@@ -1013,12 +1014,12 @@ public interface RulesDefinition {
     public String name() {
       return name;
     }
-    
+
     /**
      * @since 7.1
      * @return
      */
-    public Scope scope() {
+    public RuleScope scope() {
       return scope;
     }
 
@@ -1180,10 +1181,6 @@ public interface RulesDefinition {
     }
   }
 
-  enum Scope {
-    ALL, MAIN, TEST;
-  }
-
   @Immutable
   class Param {
     private final String key;
index 7a426129bb76c9dd95e89ad6b6c8a78fccd1603a..64f3b0a96e3c9bdac63581757935a08b2645f5eb 100644 (file)
@@ -23,11 +23,11 @@ import java.net.URL;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.api.rule.RuleScope;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.api.rule.Severity;
 import org.sonar.api.rules.RuleType;
 import org.sonar.api.server.debt.DebtRemediationFunction;
-import org.sonar.api.server.rule.RulesDefinition.Scope;
 import org.sonar.api.utils.log.LogTester;
 
 import static org.assertj.core.api.Assertions.assertThat;
@@ -82,7 +82,7 @@ public class RulesDefinitionTest {
       .setInternalKey("/something")
       .setStatus(RuleStatus.BETA)
       .setTags("one", "two")
-      .setScope(Scope.ALL)
+      .setScope(RuleScope.ALL)
       .addTags("two", "three", "four");
 
     newRepo.createRule("ABC").setName("ABC").setMarkdownDescription("ABC");
@@ -92,7 +92,7 @@ public class RulesDefinitionTest {
     assertThat(repo.rules()).hasSize(2);
 
     RulesDefinition.Rule rule = repo.rule("NPE");
-    assertThat(rule.scope()).isEqualTo(Scope.ALL);
+    assertThat(rule.scope()).isEqualTo(RuleScope.ALL);
     assertThat(rule.key()).isEqualTo("NPE");
     assertThat(rule.name()).isEqualTo("Detect NPE");
     assertThat(rule.severity()).isEqualTo(Severity.BLOCKER);
@@ -209,7 +209,7 @@ public class RulesDefinitionTest {
     RulesDefinition.Rule rule = context.repository("findbugs").rule("NPE");
     assertThat(rule.name()).isEqualTo("NullPointer");
   }
-  
+
   @Test
   public void default_scope_should_be_main() {
     RulesDefinition.NewRepository newFindbugs = context.createRepository("findbugs", "java");
@@ -217,7 +217,7 @@ public class RulesDefinitionTest {
     newFindbugs.done();
 
     RulesDefinition.Rule rule = context.repository("findbugs").rule("key");
-    assertThat(rule.scope()).isEqualTo(Scope.MAIN);
+    assertThat(rule.scope()).isEqualTo(RuleScope.MAIN);
   }
 
   @Test