]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7470 Drop ability to manage manual rules from backend
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Thu, 24 Mar 2016 15:23:28 +0000 (16:23 +0100)
committerTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Tue, 29 Mar 2016 17:11:55 +0000 (19:11 +0200)
18 files changed:
it/it-tests/src/test/java/it/Category2Suite.java
it/it-tests/src/test/java/it/rule/ManualRulesTest.java [deleted file]
it/it-tests/src/test/resources/rule/ManualRulesTest/create_edit_delete_manual_rule.html [deleted file]
server/sonar-server/src/main/java/org/sonar/server/computation/issue/BaseIssuesLoader.java
server/sonar-server/src/main/java/org/sonar/server/issue/workflow/IsManual.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/issue/workflow/IssueWorkflow.java
server/sonar-server/src/main/java/org/sonar/server/qualityprofile/RuleActivatorContext.java
server/sonar-server/src/main/java/org/sonar/server/rule/ws/RepositoriesAction.java
server/sonar-server/src/test/java/org/sonar/server/issue/workflow/IsManualTest.java [deleted file]
server/sonar-server/src/test/java/org/sonar/server/issue/workflow/IssueWorkflowTest.java
server/sonar-server/src/test/java/org/sonar/server/qualityprofile/RuleActivatorMediumTest.java
server/sonar-server/src/test/java/org/sonar/server/rule/ws/RepositoriesActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories.json
server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_manual.json [deleted file]
sonar-plugin-api/src/main/java/org/sonar/api/rule/RuleKey.java
sonar-scanner-engine/src/main/java/org/sonar/batch/issue/tracking/LocalIssueTracking.java
sonar-scanner-engine/src/test/java/org/sonar/batch/mediumtest/issuesmode/IssueModeAndReportsMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/batch/mediumtest/issuesmode/ScanOnlyChangedTest.java

index 23087b451c80f49c10ea309e4bb3ff3f3b414cc3..32894d3bc81688a65bb4f023162bd81afe932f1d 100644 (file)
@@ -39,7 +39,6 @@ import it.qualityModel.MaintainabilityRatingMeasureTest;
 import it.qualityModel.TechnicalDebtInIssueChangelogTest;
 import it.qualityModel.TechnicalDebtTest;
 import it.qualityModel.TechnicalDebtWidgetTest;
-import it.rule.ManualRulesTest;
 import it.test.CoverageTest;
 import it.test.CoverageTrackingTest;
 import it.test.NewCoverageTest;
@@ -73,8 +72,6 @@ import static util.ItUtils.xooPlugin;
   IssueWorkflowTest.class,
   ManualIssueRelocationTest.class,
   NewIssuesMeasureTest.class,
-  // rule
-  ManualRulesTest.class,
   // debt
   MaintainabilityRatingMeasureTest.class,
   TechnicalDebtInIssueChangelogTest.class,
diff --git a/it/it-tests/src/test/java/it/rule/ManualRulesTest.java b/it/it-tests/src/test/java/it/rule/ManualRulesTest.java
deleted file mode 100644 (file)
index da5d233..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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 it.rule;
-
-import com.sonar.orchestrator.Orchestrator;
-import com.sonar.orchestrator.selenium.Selenese;
-import it.Category2Suite;
-import java.sql.Connection;
-import java.sql.SQLException;
-import org.junit.AfterClass;
-import org.junit.Before;
-import org.junit.ClassRule;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import util.QaOnly;
-import util.selenium.SeleneseTest;
-
-@Category(QaOnly.class)
-@Ignore("will be removed with MMF-233")
-public class ManualRulesTest {
-
-  @ClassRule
-  public static final Orchestrator ORCHESTRATOR = Category2Suite.ORCHESTRATOR;
-
-  @Before
-  public void setup() throws Exception {
-    ORCHESTRATOR.resetData();
-    deleteManualRules();
-  }
-
-  @AfterClass
-  public static void purgeManualRules() {
-    deleteManualRules();
-  }
-
-  @Test
-  public void manual_rules() {
-    new SeleneseTest(Selenese.builder().setHtmlTestsInClasspath("manual-rules",
-          "/rule/ManualRulesTest/create_edit_delete_manual_rule.html"
-        ).build()
-    ).runOn(ORCHESTRATOR);
-  }
-
-  protected static void deleteManualRules() {
-    try {
-      Connection connection = ORCHESTRATOR.getDatabase().openConnection();
-      connection.prepareStatement("DELETE FROM rules WHERE rules.plugin_name='manual'").execute();
-    } catch (SQLException e) {
-      throw new IllegalStateException("Fail to remove manual rules", e);
-    }
-  }
-
-}
diff --git a/it/it-tests/src/test/resources/rule/ManualRulesTest/create_edit_delete_manual_rule.html b/it/it-tests/src/test/resources/rule/ManualRulesTest/create_edit_delete_manual_rule.html
deleted file mode 100644 (file)
index 3ea7358..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head profile="http://selenium-ide.openqa.org/profiles/test-case">
-  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-  <title>create_edit_delete_manual_rule</title>
-</head>
-<body>
-<table cellpadding="1" cellspacing="1" border="1">
-  <tbody>
-  <tr>
-    <td>open</td>
-    <td>/sessions/new</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>type</td>
-    <td>login</td>
-    <td>admin</td>
-  </tr>
-  <tr>
-    <td>type</td>
-    <td>password</td>
-    <td>admin</td>
-  </tr>
-  <tr>
-    <td>clickAndWait</td>
-    <td>commit</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>open</td>
-    <td>/coding_rules</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForVisible</td>
-    <td>css=.js-create-manual-rule</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>css=.js-create-manual-rule</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForVisible</td>
-    <td>coding-rules-manual-rule-creation-create</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>type</td>
-    <td>name=name</td>
-    <td>New rule</td>
-  </tr>
-  <tr>
-    <td>type</td>
-    <td>name=key</td>
-    <td>New_rule</td>
-  </tr>
-  <tr>
-    <td>type</td>
-    <td>name=markdown_description</td>
-    <td>This is a new rule</td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>coding-rules-manual-rule-creation-create</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForElementPresent</td>
-    <td>css=.coding-rules-detail-header</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForText</td>
-    <td>css=.coding-rule-details</td>
-    <td>glob:*New rule*This is a new rule*</td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>coding-rules-detail-manual-rule-change</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForVisible</td>
-    <td>coding-rules-manual-rule-creation-create</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>type</td>
-    <td>name=markdown_description</td>
-    <td>Description updated</td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>coding-rules-manual-rule-creation-create</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForText</td>
-    <td>css=.coding-rule-details</td>
-    <td>glob:*New rule*Description updated*</td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>coding-rules-detail-rule-delete</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForVisible</td>
-    <td>css=[data-confirm=&quot;yes&quot;]</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>click</td>
-    <td>css=[data-confirm=&quot;yes&quot;]</td>
-    <td></td>
-  </tr>
-  <tr>
-    <td>waitForNotText</td>
-    <td>css=.search-navigator-workspace-list</td>
-    <td>glob:*New rule*</td>
-  </tr>
-  </tbody>
-</table>
-</body>
-</html>
index c0ed27429a7d696d944c9cb419b1628423df230d..26f51039c372ff09ec537fdca04023f4313f0657 100644 (file)
@@ -81,7 +81,7 @@ public class BaseIssuesLoader {
   }
 
   private boolean isActive(RuleKey ruleKey) {
-    return ruleKey.isManual() || activeRulesHolder.get(ruleKey).isPresent();
+    return activeRulesHolder.get(ruleKey).isPresent();
   }
 
   /**
diff --git a/server/sonar-server/src/main/java/org/sonar/server/issue/workflow/IsManual.java b/server/sonar-server/src/main/java/org/sonar/server/issue/workflow/IsManual.java
deleted file mode 100644 (file)
index 56336ad..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.issue.workflow;
-
-import org.sonar.api.issue.Issue;
-import org.sonar.api.issue.condition.Condition;
-
-enum IsManual implements Condition {
-  INSTANCE;
-
-  @Override
-  public boolean matches(Issue issue) {
-    return issue.ruleKey().isManual();
-  }
-}
index e5a76c9fcfda123b964a08b794b37893664fe363..37a6d23fac709b3f15e564aa3a124d6db592d389 100644 (file)
@@ -86,13 +86,8 @@ public class IssueWorkflow implements Startable {
         .from(Issue.STATUS_RESOLVED).to(Issue.STATUS_REOPENED)
         .functions(new SetResolution(null))
         .build())
-      .transition(Transition.builder(DefaultTransitions.REOPEN)
-        .conditions(IsManual.INSTANCE)
-        .from(Issue.STATUS_CLOSED).to(Issue.STATUS_REOPENED)
-        .functions(new SetResolution(null), new SetCloseDate(false))
-        .build())
 
-    // resolve as false-positive
+      // resolve as false-positive
       .transition(Transition.builder(DefaultTransitions.FALSE_POSITIVE)
         .from(Issue.STATUS_OPEN).to(Issue.STATUS_RESOLVED)
         .functions(new SetResolution(Issue.RESOLUTION_FALSE_POSITIVE), UnsetAssignee.INSTANCE)
@@ -109,7 +104,7 @@ public class IssueWorkflow implements Startable {
         .requiredProjectPermission(UserRole.ISSUE_ADMIN)
         .build())
 
-    // resolve as won't fix
+      // resolve as won't fix
       .transition(Transition.builder(DefaultTransitions.WONT_FIX)
         .from(Issue.STATUS_OPEN).to(Issue.STATUS_RESOLVED)
         .functions(new SetResolution(Issue.RESOLUTION_WONT_FIX), UnsetAssignee.INSTANCE)
@@ -151,16 +146,16 @@ public class IssueWorkflow implements Startable {
         .build())
       .transition(Transition.builder(AUTOMATIC_CLOSE_TRANSITION)
         .from(Issue.STATUS_RESOLVED).to(Issue.STATUS_CLOSED)
-        .conditions(new OrCondition(IsBeingClosed.INSTANCE, IsManual.INSTANCE))
+        .conditions(IsBeingClosed.INSTANCE)
         .functions(SetClosed.INSTANCE, new SetCloseDate(true))
         .automatic()
         .build())
 
-    // Reopen issues that are marked as resolved but that are still alive.
-    // Manual issues are kept resolved.
+      // Reopen issues that are marked as resolved but that are still alive.
+      // Manual issues are kept resolved.
       .transition(Transition.builder("automaticreopen")
         .from(Issue.STATUS_RESOLVED).to(Issue.STATUS_REOPENED)
-        .conditions(new NotCondition(IsBeingClosed.INSTANCE), new HasResolution(Issue.RESOLUTION_FIXED), new NotCondition(IsManual.INSTANCE))
+        .conditions(new NotCondition(IsBeingClosed.INSTANCE), new HasResolution(Issue.RESOLUTION_FIXED))
         .functions(new SetResolution(null), new SetCloseDate(false))
         .automatic()
         .build());
index fd0f840ee465c029ef99d043c32390e3d114e5ac..f564481fa832d786a31478b9a8cbdd305c9443e2 100644 (file)
 package org.sonar.server.qualityprofile;
 
 import com.google.common.collect.Maps;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Map;
+import javax.annotation.CheckForNull;
+import javax.annotation.Nullable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.rule.RuleStatus;
 import org.sonar.db.qualityprofile.ActiveRuleDto;
@@ -30,13 +35,6 @@ import org.sonar.db.rule.RuleDto;
 import org.sonar.db.rule.RuleParamDto;
 import org.sonar.server.exceptions.BadRequestException;
 
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
-
-import java.util.Collection;
-import java.util.Date;
-import java.util.Map;
-
 class RuleActivatorContext {
 
   private final Date initDate = new Date();
@@ -232,9 +230,6 @@ class RuleActivatorContext {
     if (rule.isTemplate()) {
       throw new BadRequestException("Rule template can't be activated on a Quality profile: " + rule.getKey());
     }
-    if (rule.getKey().isManual()) {
-      throw new BadRequestException("Manual rule can't be activated on a Quality profile: " + rule.getKey());
-    }
     if (!profile.getLanguage().equals(rule.getLanguage())) {
       throw new BadRequestException(String.format("Rule %s and profile %s have different languages", rule.getKey(), profile.getKey()));
     }
index 0a92388baccbdc941b7d1294adac803065fb0664..ac06c0aea8b3d35dd56c5bbe800b882f8959bcc4 100644 (file)
@@ -26,8 +26,8 @@ import java.util.Collection;
 import java.util.List;
 import java.util.SortedMap;
 import java.util.regex.Pattern;
+import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
-import org.sonar.api.rule.RuleKey;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -102,15 +102,12 @@ public class RepositoriesAction implements RulesWsAction {
     return result;
   }
 
-  private Collection<Repo> listRepositories(String languageKey) {
+  private Collection<Repo> listRepositories(@CheckForNull String languageKey) {
     List<Repo> allRepos = Lists.newArrayList();
     Collection<Repository> reposFromPlugins = languageKey == null ? repositories.repositories() : repositories.repositoriesForLang(languageKey);
     for (Repository repo : reposFromPlugins) {
       allRepos.add(new Repo(repo));
     }
-    if (languageKey == null) {
-      allRepos.add(new Repo(RuleKey.MANUAL_REPOSITORY_KEY, "Manual Rule", "None"));
-    }
     return allRepos;
   }
 
diff --git a/server/sonar-server/src/test/java/org/sonar/server/issue/workflow/IsManualTest.java b/server/sonar-server/src/test/java/org/sonar/server/issue/workflow/IsManualTest.java
deleted file mode 100644 (file)
index c845803..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact 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.issue.workflow;
-
-import org.junit.Test;
-import org.sonar.api.rule.RuleKey;
-import org.sonar.core.issue.DefaultIssue;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.server.issue.workflow.IsManual.INSTANCE;
-
-public class IsManualTest {
-
-  @Test
-  public void should_match() {
-    DefaultIssue issue = new DefaultIssue();
-    assertThat(INSTANCE.matches(issue.setRuleKey(RuleKey.of(RuleKey.MANUAL_REPOSITORY_KEY, "R1")))).isTrue();
-    assertThat(INSTANCE.matches(issue.setRuleKey(RuleKey.of("java", "R1")))).isFalse();
-  }
-
-}
index 6b1e4549c5f60965b179ecb1a8181b39d2deff2a..5c8f378e789ab1e4396829c4cd222a8ed1eb226a 100644 (file)
@@ -45,7 +45,6 @@ import static org.sonar.api.issue.Issue.STATUS_CONFIRMED;
 import static org.sonar.api.issue.Issue.STATUS_OPEN;
 import static org.sonar.api.issue.Issue.STATUS_REOPENED;
 import static org.sonar.api.issue.Issue.STATUS_RESOLVED;
-import static org.sonar.api.rule.RuleKey.MANUAL_REPOSITORY_KEY;
 
 public class IssueWorkflowTest {
 
@@ -117,20 +116,6 @@ public class IssueWorkflowTest {
     assertThat(transitions).isEmpty();
   }
 
-  @Test
-  public void list_out_transitions_from_status_closed_on_manual_issue() {
-    workflow.start();
-
-    // Manual issue because of reporter
-    DefaultIssue issue = new DefaultIssue()
-      .setKey("ABCDE")
-      .setStatus(STATUS_CLOSED)
-      .setRuleKey(RuleKey.of("manual", "Performance"));
-
-    List<Transition> transitions = workflow.outTransitions(issue);
-    assertThat(keys(transitions)).containsOnly("reopen");
-  }
-
   @Test
   public void fail_if_unknown_status_when_listing_transitions() {
     workflow.start();
@@ -271,81 +256,6 @@ public class IssueWorkflowTest {
     assertThat(issue.assignee()).isNull();
   }
 
-  /**
-   * User marks the manual issue as resolved -> issue is automatically
-   * closed.
-   */
-  @Test
-  public void automatically_close_resolved_manual_issue() {
-    DefaultIssue issue = new DefaultIssue()
-      .setKey("ABCDE")
-      .setStatus(STATUS_OPEN)
-      .setRuleKey(RuleKey.of(MANUAL_REPOSITORY_KEY, "Performance"));
-
-    workflow.start();
-
-    assertThat(workflow.outTransitions(issue)).containsOnly(
-      Transition.create("confirm", "OPEN", "CONFIRMED"),
-      Transition.create("resolve", "OPEN", "RESOLVED"),
-      Transition.create("falsepositive", "OPEN", "RESOLVED"),
-      Transition.create("wontfix", "OPEN", "RESOLVED"));
-
-    workflow.doTransition(issue, "resolve", mock(IssueChangeContext.class));
-    assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
-    assertThat(issue.status()).isEqualTo("RESOLVED");
-
-    assertThat(workflow.outTransitions(issue)).containsOnly(
-      Transition.create("reopen", "RESOLVED", "REOPENED"));
-
-    workflow.doAutomaticTransition(issue, mock(IssueChangeContext.class));
-    assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
-    assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
-  }
-
-  /**
-   * Manual issue is fixed because the file does not exist anymore
-   * or the tracking engine did not find the associated code
-   * -> the issue is closed
-   */
-  @Test
-  public void automatically_close_manual_issue_on_deleted_code() {
-    DefaultIssue issue = new DefaultIssue()
-      .setKey("ABCDE")
-      .setStatus(STATUS_OPEN)
-      .setRuleKey(RuleKey.of(MANUAL_REPOSITORY_KEY, "Performance"))
-      .setBeingClosed(true);
-
-    workflow.start();
-
-    workflow.doAutomaticTransition(issue, mock(IssueChangeContext.class));
-    assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
-    assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
-  }
-
-  /**
-   * Corner-case : the manual issue was marked as resolved by user but at the same 
-   * time the file or the associated line was deleted.
-   */
-  @Test
-  public void automatically_close_resolved_manual_issue_on_deleted_code() {
-    DefaultIssue issue = new DefaultIssue()
-      .setKey("ABCDE")
-      .setRuleKey(RuleKey.of(MANUAL_REPOSITORY_KEY, "Performance"))
-
-      // resolved by user
-      .setResolution(RESOLUTION_FIXED)
-      .setStatus(STATUS_RESOLVED)
-
-      // but unmatched by tracking engine
-      .setBeingClosed(true);
-
-    workflow.start();
-
-    workflow.doAutomaticTransition(issue, mock(IssueChangeContext.class));
-    assertThat(issue.resolution()).isEqualTo(RESOLUTION_FIXED);
-    assertThat(issue.status()).isEqualTo(STATUS_CLOSED);
-  }
-
   @Test
   public void manual_issues_be_confirmed_then_kept_open() {
     // Manual issue because of reporter
index be82422bbaa7320a43c8d46516b2d928408c3549..fc500642101cbbfbe89c03078417e81b3668b280 100644 (file)
@@ -78,7 +78,6 @@ import static org.sonar.server.qualityprofile.QProfileTesting.XOO_P3_KEY;
 // TODO Replace ServerTester by EsTester and DbTester
 public class RuleActivatorMediumTest {
 
-  static final RuleKey MANUAL_RULE_KEY = RuleKey.of(RuleKey.MANUAL_REPOSITORY_KEY, "m1");
   static final RuleKey TEMPLATE_RULE_KEY = RuleKey.of("xoo", "template1");
   static final RuleKey CUSTOM_RULE_KEY = RuleKey.of("xoo", "custom1");
 
@@ -119,12 +118,10 @@ public class RuleActivatorMediumTest {
     RuleDto xooRule2 = newXooX2().setSeverity("INFO");
     RuleDto xooTemplateRule1 = newTemplateRule(TEMPLATE_RULE_KEY)
       .setSeverity("MINOR").setLanguage("xoo");
-    RuleDto manualRule = newDto(MANUAL_RULE_KEY);
     db.ruleDao().insert(dbSession, javaRule);
     db.ruleDao().insert(dbSession, xooRule1);
     db.ruleDao().insert(dbSession, xooRule2);
     db.ruleDao().insert(dbSession, xooTemplateRule1);
-    db.ruleDao().insert(dbSession, manualRule);
     db.ruleDao().insertRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1)
       .setName("max").setDefaultValue("10").setType(RuleParamType.INTEGER.type()));
     db.ruleDao().insertRuleParam(dbSession, xooRule1, RuleParamDto.createFor(xooRule1)
@@ -439,19 +436,6 @@ public class RuleActivatorMediumTest {
     }
   }
 
-  @Test
-  public void fail_to_activate_if_manual_rule() {
-    RuleActivation activation = new RuleActivation(MANUAL_RULE_KEY);
-
-    try {
-      activate(activation, XOO_P1_KEY);
-      fail();
-    } catch (BadRequestException e) {
-      assertThat(e).hasMessage("Manual rule can't be activated on a Quality profile: manual:m1");
-      verifyZeroActiveRules(XOO_P1_KEY);
-    }
-  }
-
   @Test
   public void fail_to_activate_if_unknown_profile() {
     try {
@@ -878,7 +862,7 @@ public class RuleActivatorMediumTest {
     verifyZeroActiveRules(XOO_P1_KEY);
     assertThat(tester.get(RuleIndex.class)
       .search(new RuleQuery().setRepositories(Arrays.asList("bulk")), new SearchOptions()).getTotal())
-      .isEqualTo(bulkSize);
+        .isEqualTo(bulkSize);
 
     // 1. bulk activate all the rules
     BulkChangeResult result = ruleActivator.bulkActivate(
@@ -1119,8 +1103,7 @@ public class RuleActivatorMediumTest {
       if (activeRule.key().equals(activeRuleKey)) {
         found = true;
         assertThat(activeRule.severity()).isEqualTo(expectedSeverity);
-        assertThat(activeRule.inheritance()).isEqualTo(expectedInheritance == null ? ActiveRule.Inheritance.NONE :
-          ActiveRule.Inheritance.valueOf(expectedInheritance));
+        assertThat(activeRule.inheritance()).isEqualTo(expectedInheritance == null ? ActiveRule.Inheritance.NONE : ActiveRule.Inheritance.valueOf(expectedInheritance));
 
         // Dates should be set
         assertThat(activeRule.createdAt()).isNotNull();
index a87c6fd5455b0a699d291ace4371c227b15d841f..34d9fd65dd1ff478be3af4dfc7ba9c568f805a98 100644 (file)
@@ -66,7 +66,6 @@ public class RepositoriesActionTest {
 
   @Test
   public void should_list_repositories() throws Exception {
-
     tester = new WsTester(new RulesWs(new RepositoriesAction(repositories)));
 
     newRequest().execute().assertJson(this.getClass(), "repositories.json");
@@ -75,7 +74,6 @@ public class RepositoriesActionTest {
     newRequest().setParam("q", "common").execute().assertJson(this.getClass(), "repositories_common.json");
     newRequest().setParam("q", "squid").execute().assertJson(this.getClass(), "repositories_squid.json");
     newRequest().setParam("q", "sonar").execute().assertJson(this.getClass(), "repositories_sonar.json");
-    newRequest().setParam("q", "manu").execute().assertJson(this.getClass(), "repositories_manual.json");
     newRequest().setParam("q", "sonar").setParam("ps", "2").execute().assertJson(this.getClass(), "repositories_limited.json");
     newRequest().setParam("ps", "4").execute().assertJson(this.getClass(), "repositories.json");
     newRequest().setParam("ps", "100").execute().assertJson(this.getClass(), "repositories.json");
index b99c5aa6fb17b3e797d7bee4b9447657b76bb866..aa68c0aee792163125eb4601b039bcbbc5261ad2 100644 (file)
@@ -1,10 +1,5 @@
 {
   "repositories": [
-    {
-      "key": "manual",
-      "name": "Manual Rule",
-      "language": "None"
-    },
     {
       "key": "squid",
       "name": "SonarQube",
@@ -21,4 +16,4 @@
       "language": "ws"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_manual.json b/server/sonar-server/src/test/resources/org/sonar/server/rule/ws/RepositoriesActionTest/repositories_manual.json
deleted file mode 100644 (file)
index 4b36d12..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-{
-  "repositories": [
-    {
-      "key": "manual",
-      "name": "Manual Rule",
-      "language": "None"
-    }
-  ]
-}
\ No newline at end of file
index 668fd8fcef04907d01104e1540ae4368b1f523a1..324aba1fd0e8ce49d2c1c940e22ba894dca39618 100644 (file)
@@ -33,7 +33,12 @@ import javax.annotation.concurrent.Immutable;
 @Immutable
 public class RuleKey implements Serializable, Comparable<RuleKey> {
 
+  /**
+   * @deprecated since 5.5, manual rule feature has been dropped
+   */
+  @Deprecated
   public static final String MANUAL_REPOSITORY_KEY = "manual";
+
   private final String repository;
   private final String rule;
 
@@ -77,8 +82,12 @@ public class RuleKey implements Serializable, Comparable<RuleKey> {
     return rule;
   }
 
+  /**
+   * @deprecated since 5.5, manual rule feature has been dropped
+   */
+  @Deprecated
   public boolean isManual() {
-    return MANUAL_REPOSITORY_KEY.equals(repository);
+    return false;
   }
 
   @Override
index 21a89cdb95c5f8f8098df09bc89d0baa3979d719..13f5a7744058fb9bb7e028ae6a6af4a6b61c95ff 100644 (file)
@@ -34,7 +34,6 @@ import org.sonar.api.batch.fs.InputFile.Status;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.rule.ActiveRule;
 import org.sonar.api.batch.rule.ActiveRules;
-import org.sonar.api.issue.Issue;
 import org.sonar.api.resources.ResourceUtils;
 import org.sonar.batch.analysis.DefaultAnalysisMode;
 import org.sonar.batch.index.BatchComponent;
@@ -90,7 +89,7 @@ public class LocalIssueTracking {
 
         Tracking<TrackedIssue, ServerIssueFromWs> track = tracker.track(rawIssues, baseIssues);
 
-        addUnmatchedFromServer(track.getUnmatchedBases(), sourceHashHolder, trackedIssues);
+        addUnmatchedFromServer(track.getUnmatchedBases(), trackedIssues);
         mergeMatched(track, trackedIssues, rIssues);
         addUnmatchedFromReport(track.getUnmatchedRaws(), trackedIssues, analysisDate);
       }
@@ -201,14 +200,11 @@ public class LocalIssueTracking {
     }
   }
 
-  private void addUnmatchedFromServer(Iterable<ServerIssueFromWs> unmatchedIssues, SourceHashHolder sourceHashHolder, Collection<TrackedIssue> mergeTo) {
+  private void addUnmatchedFromServer(Iterable<ServerIssueFromWs> unmatchedIssues, Collection<TrackedIssue> mergeTo) {
     for (ServerIssueFromWs unmatchedIssue : unmatchedIssues) {
       org.sonar.scanner.protocol.input.ScannerInput.ServerIssue unmatchedPreviousIssue = unmatchedIssue.getDto();
       TrackedIssue unmatched = IssueTransformer.toTrackedIssue(unmatchedPreviousIssue);
-      if (unmatchedIssue.getRuleKey().isManual() && !Issue.STATUS_CLOSED.equals(unmatchedPreviousIssue.getStatus())) {
-        relocateManualIssue(unmatched, unmatchedIssue, sourceHashHolder);
-      }
-      updateUnmatchedIssue(unmatched, false /* manual issues can be kept open */);
+      updateUnmatchedIssue(unmatched);
       mergeTo.add(unmatched);
     }
   }
@@ -223,40 +219,21 @@ public class LocalIssueTracking {
   private void addIssuesOnDeletedComponents(Collection<TrackedIssue> issues) {
     for (org.sonar.scanner.protocol.input.ScannerInput.ServerIssue previous : serverIssueRepository.issuesOnMissingComponents()) {
       TrackedIssue dead = IssueTransformer.toTrackedIssue(previous);
-      updateUnmatchedIssue(dead, true);
+      updateUnmatchedIssue(dead);
       issues.add(dead);
     }
   }
 
-  private void updateUnmatchedIssue(TrackedIssue issue, boolean forceEndOfLife) {
+  private void updateUnmatchedIssue(TrackedIssue issue) {
     ActiveRule activeRule = activeRules.find(issue.getRuleKey());
     issue.setNew(false);
 
-    boolean manualIssue = issue.getRuleKey().isManual();
     boolean isRemovedRule = activeRule == null;
 
     if (isRemovedRule) {
       IssueTransformer.resolveRemove(issue);
-    } else if (forceEndOfLife || !manualIssue) {
+    } else {
       IssueTransformer.close(issue);
     }
   }
-
-  private static void relocateManualIssue(TrackedIssue newIssue, ServerIssueFromWs oldIssue, SourceHashHolder sourceHashHolder) {
-    Integer previousLine = oldIssue.getLine();
-    if (previousLine == null) {
-      return;
-    }
-
-    Collection<Integer> newLinesWithSameHash = sourceHashHolder.getNewLinesMatching(previousLine);
-    if (newLinesWithSameHash.isEmpty()) {
-      if (previousLine > sourceHashHolder.getHashedSource().length()) {
-        IssueTransformer.resolveRemove(newIssue);
-      }
-    } else if (newLinesWithSameHash.size() == 1) {
-      Integer newLine = newLinesWithSameHash.iterator().next();
-      newIssue.setStartLine(newLine);
-      newIssue.setEndLine(newLine);
-    }
-  }
 }
index e02c84ec71a73ce1dbeb8707d48311a65599e037..c3ba10d7abc242ef103f5de51c8f4f0e6cb82dc8 100644 (file)
  */
 package org.sonar.batch.mediumtest.issuesmode;
 
-import org.apache.commons.lang.StringUtils;
-
-import org.sonar.api.utils.log.LoggerLevel;
-import org.assertj.core.api.Condition;
-import org.sonar.batch.issue.tracking.TrackedIssue;
 import com.google.common.collect.ImmutableMap;
-
 import java.io.File;
 import java.io.IOException;
 import java.text.ParseException;
@@ -33,17 +27,20 @@ import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
-
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.apache.commons.lang.StringUtils;
+import org.assertj.core.api.Condition;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.utils.log.LogTester;
+import org.sonar.api.utils.log.LoggerLevel;
 import org.sonar.batch.bootstrapper.IssueListener;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 import org.sonar.batch.mediumtest.BatchMediumTester;
 import org.sonar.batch.mediumtest.TaskResult;
 import org.sonar.batch.scan.report.ConsoleReport;
@@ -51,6 +48,7 @@ import org.sonar.scanner.protocol.Constants.Severity;
 import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue;
 import org.sonar.xoo.XooPlugin;
 import org.sonar.xoo.rule.XooRulesDefinition;
+
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class IssueModeAndReportsMediumTest {
@@ -76,12 +74,9 @@ public class IssueModeAndReportsMediumTest {
     .registerPlugin("xoo", new XooPlugin())
     .addDefaultQProfile("xoo", "Sonar Way")
     .addRules(new XooRulesDefinition())
-    .addRule("manual:MyManualIssue", "manual", "MyManualIssue", "My manual issue")
-    .addRule("manual:MyManualIssueDup", "manual", "MyManualIssue", "My manual issue")
     .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo")
     .addActiveRule("xoo", "OneIssueOnDirPerFile", null, "OneIssueOnDirPerFile", "MAJOR", null, "xoo")
     .addActiveRule("xoo", "OneIssuePerModule", null, "OneIssuePerModule", "MAJOR", null, "xoo")
-    .addActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null)
     .setPreviousAnalysisDate(new Date())
     // Existing issue that is still detected
     .mockServerIssue(ServerIssue.newBuilder().setKey("xyz")
@@ -116,18 +111,6 @@ public class IssueModeAndReportsMediumTest {
       .setCreationDate(date("14/03/2004"))
       .setStatus("OPEN")
       .build())
-    // Manual issue
-    .mockServerIssue(ServerIssue.newBuilder().setKey("manual")
-      .setModuleKey("sample")
-      .setPath("xources/hello/HelloJava.xoo")
-      .setRuleRepository("manual")
-      .setRuleKey("MyManualIssue")
-      .setLine(1)
-      .setSeverity(Severity.MAJOR)
-      .setCreationDate(date("14/03/2004"))
-      .setChecksum(DigestUtils.md5Hex("packagehello;"))
-      .setStatus("OPEN")
-      .build())
     .build();
 
   @Before
@@ -172,7 +155,7 @@ public class IssueModeAndReportsMediumTest {
     }
     System.out.println("new: " + newIssues + " open: " + openIssues + " resolved " + resolvedIssue);
     assertThat(newIssues).isEqualTo(16);
-    assertThat(openIssues).isEqualTo(3);
+    assertThat(openIssues).isEqualTo(2);
     assertThat(resolvedIssue).isEqualTo(1);
     
     // progress report
@@ -214,7 +197,7 @@ public class IssueModeAndReportsMediumTest {
       .property("sonar.xoo.enablePostJob", "true")
       .start();
 
-    assertThat(logTester.logs()).contains("Resolved issues: 1", "Open issues: 19");
+    assertThat(logTester.logs()).contains("Resolved issues: 1", "Open issues: 18");
   }
 
   private String getReportLog() {
@@ -272,8 +255,8 @@ public class IssueModeAndReportsMediumTest {
       .setIssueListener(issueListener)
       .start();
 
-    assertThat(result.trackedIssues()).hasSize(20);
-    assertThat(issueListener.issueList).hasSize(20);
+    assertThat(result.trackedIssues()).hasSize(19);
+    assertThat(issueListener.issueList).hasSize(19);
   }
 
   private class IssueRecorder implements IssueListener {
index eb5850b08099a75fb77d770ce23f62b4d069e20a..26d1c3653cc8f6e94144a21e0c52aa2f1dc2819d 100644 (file)
  */
 package org.sonar.batch.mediumtest.issuesmode;
 
-import org.sonar.batch.issue.tracking.TrackedIssue;
-
-import org.assertj.core.api.Condition;
-import com.google.common.io.Resources;
-import org.sonar.batch.repository.FileData;
-import org.sonar.scanner.protocol.Constants.Severity;
-import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.io.Resources;
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import org.apache.commons.codec.digest.DigestUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.filefilter.FileFilterUtils;
+import org.assertj.core.api.Condition;
 import org.junit.After;
 import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
 import org.sonar.api.CoreProperties;
+import org.sonar.api.utils.log.LogTester;
+import org.sonar.batch.issue.tracking.TrackedIssue;
 import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.TaskResult;
+import org.sonar.batch.repository.FileData;
+import org.sonar.scanner.protocol.Constants.Severity;
+import org.sonar.scanner.protocol.input.ScannerInput.ServerIssue;
 import org.sonar.xoo.XooPlugin;
 import org.sonar.xoo.rule.XooRulesDefinition;
-import org.junit.rules.TemporaryFolder;
-import org.sonar.api.utils.log.LogTester;
-import org.junit.Test;
-import org.sonar.batch.mediumtest.TaskResult;
-
-import java.io.File;
-import java.io.IOException;
-import java.text.ParseException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
@@ -79,12 +77,9 @@ public class ScanOnlyChangedTest {
       .registerPlugin("xoo", new XooPlugin())
       .addDefaultQProfile("xoo", "Sonar Way")
       .addRules(new XooRulesDefinition())
-      .addRule("manual:MyManualIssue", "manual", "MyManualIssue", "My manual issue")
-      .addRule("manual:MyManualIssueDup", "manual", "MyManualIssue", "My manual issue")
       .addActiveRule("xoo", "OneIssuePerLine", null, "One issue per line", "MAJOR", null, "xoo")
       .addActiveRule("xoo", "OneIssueOnDirPerFile", null, "OneIssueOnDirPerFile", "MAJOR", null, "xoo")
       .addActiveRule("xoo", "OneIssuePerModule", null, "OneIssuePerModule", "MAJOR", null, "xoo")
-      .addActiveRule("manual", "MyManualIssue", null, "My manual issue", "MAJOR", null, null)
       // this will cause the file to have status==SAME
       .addFileData("sample", filePath, new FileData(md5sum, null))
       .setPreviousAnalysisDate(new Date())
@@ -110,18 +105,6 @@ public class ScanOnlyChangedTest {
         .setCreationDate(date("14/03/2004"))
         .setStatus("OPEN")
         .build())
-      // Manual issue
-      .mockServerIssue(ServerIssue.newBuilder().setKey("manual")
-        .setModuleKey("sample")
-        .setPath("xources/hello/HelloJava.xoo")
-        .setRuleRepository("manual")
-        .setRuleKey("MyManualIssue")
-        .setLine(1)
-        .setSeverity(Severity.MAJOR)
-        .setCreationDate(date("14/03/2004"))
-        .setChecksum(DigestUtils.md5Hex("packagehello;"))
-        .setStatus("OPEN")
-        .build())
       .build();
     tester.start();
   }
@@ -147,13 +130,12 @@ public class ScanOnlyChangedTest {
       .property("sonar.scanAllFiles", "true")
       .start();
 
-    assertNumberIssues(result, 16, 3, 0);
+    assertNumberIssues(result, 16, 2, 0);
 
     /*
      * 8 new per line
-     * 1 manual
      */
-    assertNumberIssuesOnFile(result, "HelloJava.xoo", 9);
+    assertNumberIssuesOnFile(result, "HelloJava.xoo", 8);
   }
 
   @Test
@@ -172,10 +154,10 @@ public class ScanOnlyChangedTest {
      * 1 manual issue (open, not new) in HelloJava.xoo
      * 1 existing issue on the project (open, not new)
      */
-    assertNumberIssues(result, 8, 3, 0);
+    assertNumberIssues(result, 8, 2, 0);
 
     // should only have server issues (HelloJava.xoo should not have been analyzed)
-    assertNumberIssuesOnFile(result, "HelloJava.xoo", 2);
+    assertNumberIssuesOnFile(result, "HelloJava.xoo", 1);
   }
 
   private static void assertNumberIssuesOnFile(TaskResult result, final String fileNameEndsWith, int issues) {