]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15498 add IT and Purge should delete selected project if it only selects a...
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Thu, 4 Nov 2021 21:01:17 +0000 (16:01 -0500)
committersonartech <sonartech@sonarsource.com>
Tue, 9 Nov 2021 20:03:16 +0000 (20:03 +0000)
13 files changed:
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeCommands.java
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/purge/PurgeMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/purge/PurgeMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/purge/PurgeCommandsTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/views/AddProjectBranchRequest.java [new file with mode: 0644]
sonar-ws/src/main/java/org/sonarqube/ws/client/views/CreateRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/views/RemoveProjectBranchRequest.java [new file with mode: 0644]
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SearchRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRegexpModeRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetRemainingProjectsModeRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/views/SetTagsModeRequest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/views/ViewsService.java

index feba85ea9e39ec37542458532fc924d9ec6bf29a..402bf9ef5b8577deebff68e0296c395b6ead786d 100644 (file)
@@ -455,7 +455,11 @@ class PurgeCommands {
 
   public void deleteProjectInPortfolios(String rootUuid) {
     profiler.start("deleteProjectInPortfolios (portfolio_projects)");
+    // delete selected project if it's only selecting a single branch corresponding to rootUuid
+    purgeMapper.deletePortfolioProjectsByBranchUuid(rootUuid);
+    // delete selected branches if branch is rootUuid or if it's part of a project that is rootUuid
     purgeMapper.deletePortfolioProjectBranchesByBranchUuid(rootUuid);
+    // delete selected project if project is rootUuid
     purgeMapper.deletePortfolioProjectsByProjectUuid(rootUuid);
     session.commit();
     profiler.stop();
index 11a0ee7e67cc87a3c078c27c1760e6baf707687d..7e0d1efd9ac61f429fec907205053758e9589192 100644 (file)
@@ -165,7 +165,7 @@ public class PurgeDao implements Dao {
 
   private static final class NewCodePeriodAnalysisFilter implements Predicate<PurgeableAnalysisDto> {
     @Nullable
-    private String analysisUuid;
+    private final String analysisUuid;
 
     private NewCodePeriodAnalysisFilter(PurgeMapper mapper, String componentUuid) {
       this.analysisUuid = mapper.selectSpecificAnalysisNewCodePeriod(componentUuid);
index 5270cec0721dc124f535785f22d32906b51299e4..348d043c7d5e28b087fcfc2a32f99feaf9a7b30c 100644 (file)
@@ -147,6 +147,8 @@ public interface PurgeMapper {
 
   void deleteApplicationBranchProjectBranchesByProjectBranchUuid(@Param("projectBranchUuid") String projectBranchUuid);
 
+  void deletePortfolioProjectsByBranchUuid(@Param("branchUuid") String branchUuid);
+
   void deletePortfolioProjectsByProjectUuid(@Param("projectUuid") String projectUuid);
 
   void deletePortfolioProjectBranchesByBranchUuid(@Param("branchUuid") String branchUuid);
index 32267058e04b1c7cb387bbd77780eccac42d1c56..604300faae04417a36b392031f3fbfa01c17f357 100644 (file)
     WHERE project_branch_uuid=#{projectBranchUuid,jdbcType=VARCHAR}
   </delete>
 
+  <delete id="deletePortfolioProjectsByBranchUuid" parameterType="map">
+    <!-- deletes selected projects that were only selecting the branch being deleted -->
+    DELETE
+    FROM portfolio_projects
+    WHERE uuid in (
+      SELECT ppb.portfolio_project_uuid FROM portfolio_proj_branches ppb
+      <!-- branch was selected -->
+      WHERE ppb.branch_uuid = #{branchUuid,jdbcType=VARCHAR}
+      <!-- and was the only one selected in the project -->
+      AND (SELECT count(*) FROM portfolio_proj_branches ppb2 WHERE ppb2.portfolio_project_uuid = ppb.portfolio_project_uuid) = 1
+    )
+  </delete>
+
   <delete id="deletePortfolioProjectsByProjectUuid" parameterType="map">
     DELETE
     FROM portfolio_projects
index 33c0475e5e5820bfeaa3774b4770d758907cd2f9..f0851b0858c8d1a0eb4e2821fc86b7efb02dae2a 100644 (file)
@@ -56,7 +56,6 @@ import org.sonar.db.user.UserDto;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static java.util.Arrays.asList;
-import static java.util.Collections.emptyList;
 import static java.util.Collections.singleton;
 import static java.util.Collections.singletonList;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphabetic;
@@ -654,7 +653,7 @@ public class PurgeCommandsTest {
   }
 
   @Test
-  public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios() {
+  public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios_if_root_is_branch() {
     var portfolio1 = dbTester.components().insertPrivatePortfolioDto();
     var portfolio2 = dbTester.components().insertPrivatePortfolioDto();
     dbTester.components().insertPrivatePortfolio();
@@ -676,6 +675,24 @@ public class PurgeCommandsTest {
       .containsExactlyInAnyOrder(tuple(portfolio1.getUuid(), anotherProject.getUuid(), singleton("anotherProjectBranch")));
   }
 
+  @Test
+  public void deleteProjectInPortfolios_deletes_project_and_branch_from_portfolios_if_root_is_project_only_selecting_a_single_branch() {
+    var portfolio1 = dbTester.components().insertPrivatePortfolioDto();
+    dbTester.components().insertPrivatePortfolio();
+    ProjectDto project = dbTester.components().insertPrivateProjectDto();
+
+    dbTester.components().addPortfolioProject(portfolio1, project);
+    dbTester.components().addPortfolioProjectBranch(portfolio1, project, "projectBranch");
+
+    PurgeCommands purgeCommands = new PurgeCommands(dbTester.getSession(), profiler, system2);
+
+    purgeCommands.deleteProjectInPortfolios(project.getUuid());
+
+    assertThat(dbTester.getDbClient().portfolioDao().selectAllPortfolioProjects(dbTester.getSession())).isEmpty();
+    assertThat(dbTester.countRowsOfTable("portfolio_proj_branches")).isZero();
+    assertThat(dbTester.countRowsOfTable("portfolio_projects")).isZero();
+  }
+
   @Test
   public void deleteProjectInPortfolios_deletes_branch_from_portfolios_if_root_is_branch() {
     var portfolio1 = dbTester.components().insertPrivatePortfolioDto();
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/AddProjectBranchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/AddProjectBranchRequest.java
new file mode 100644 (file)
index 0000000..0f3f636
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.sonarqube.ws.client.views;
+
+import javax.annotation.Generated;
+
+/**
+ * This is part of the internal API.
+ * This is a POST request.
+ * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_project_branch">Further information about this action online (including a response example)</a>
+ * @since 9.2
+ */
+@Generated("sonar-ws-generator")
+public class AddProjectBranchRequest {
+
+  private String branch;
+  private String key;
+  private String project;
+
+  /**
+   * This is a mandatory parameter.
+   * Example value: "feature/my_branch"
+   */
+  public AddProjectBranchRequest setBranch(String branch) {
+    this.branch = branch;
+    return this;
+  }
+
+  public String getBranch() {
+    return branch;
+  }
+
+  /**
+   * This is a mandatory parameter.
+   */
+  public AddProjectBranchRequest setKey(String key) {
+    this.key = key;
+    return this;
+  }
+
+  public String getKey() {
+    return key;
+  }
+
+  /**
+   * This is a mandatory parameter.
+   * Example value: "my_project"
+   */
+  public AddProjectBranchRequest setProject(String project) {
+    this.project = project;
+    return this;
+  }
+
+  public String getProject() {
+    return project;
+  }
+}
index 05c6bb4849e20f5ad7ac80a1f797df8c0134a97f..97b58d3adf3b64b26e4f24b148acb1f94edf4913 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonarqube.ws.client.views;
 
+import java.util.List;
 import javax.annotation.Generated;
 
 /**
@@ -33,6 +34,7 @@ public class CreateRequest {
   private String description;
   private String key;
   private String name;
+  private String qualifier;
   private String visibility;
 
   /**
@@ -69,6 +71,24 @@ public class CreateRequest {
     return name;
   }
 
+  /**
+   * Possible values:
+   * <ul>
+   *   <li>"VW"</li>
+   *   <li>"APP"</li>
+   * </ul>
+   * @deprecated since 7.3
+   */
+  @Deprecated
+  public CreateRequest setQualifier(String qualifier) {
+    this.qualifier = qualifier;
+    return this;
+  }
+
+  public String getQualifier() {
+    return qualifier;
+  }
+
   /**
    * Possible values:
    * <ul>
diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/views/RemoveProjectBranchRequest.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/views/RemoveProjectBranchRequest.java
new file mode 100644 (file)
index 0000000..c807a8b
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.sonarqube.ws.client.views;
+
+import javax.annotation.Generated;
+
+/**
+ * This is part of the internal API.
+ * This is a POST request.
+ * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/remove_project_branch">Further information about this action online (including a response example)</a>
+ * @since 9.2
+ */
+@Generated("sonar-ws-generator")
+public class RemoveProjectBranchRequest {
+
+  private String branch;
+  private String key;
+  private String project;
+
+  /**
+   * This is a mandatory parameter.
+   * Example value: "feature/my_branch"
+   */
+  public RemoveProjectBranchRequest setBranch(String branch) {
+    this.branch = branch;
+    return this;
+  }
+
+  public String getBranch() {
+    return branch;
+  }
+
+  /**
+   * This is a mandatory parameter.
+   */
+  public RemoveProjectBranchRequest setKey(String key) {
+    this.key = key;
+    return this;
+  }
+
+  public String getKey() {
+    return key;
+  }
+
+  /**
+   * This is a mandatory parameter.
+   * Example value: "my_project"
+   */
+  public RemoveProjectBranchRequest setProject(String project) {
+    this.project = project;
+    return this;
+  }
+
+  public String getProject() {
+    return project;
+  }
+}
index cc4158edcaf72fd336ad59ad686e9032fa9aabca..ae9f2d4e4ee8cb1822e358b81028c0016ff72d92 100644 (file)
@@ -93,7 +93,6 @@ public class SearchRequest {
   /**
    * Possible values:
    * <ul>
-   *   <li>"APP"</li>
    *   <li>"VW"</li>
    *   <li>"SVW"</li>
    * </ul>
index a2c330d6b3b56d4560bf346c1ea1abaa6e2af917..5ff689812b4b586a33fb6dbc3c22306ff30c760b 100644 (file)
@@ -30,9 +30,21 @@ import javax.annotation.Generated;
 @Generated("sonar-ws-generator")
 public class SetRegexpModeRequest {
 
+  private String branch;
   private String portfolio;
   private String regexp;
 
+  /**
+   */
+  public SetRegexpModeRequest setBranch(String branch) {
+    this.branch = branch;
+    return this;
+  }
+
+  public String getBranch() {
+    return branch;
+  }
+
   /**
    * This is a mandatory parameter.
    */
index 866c9340d85cfae83cb5db34ebf7fca435a0f972..c4ff5c99b26e6d23c6e646f7f998c00c26ddbe32 100644 (file)
@@ -30,8 +30,20 @@ import javax.annotation.Generated;
 @Generated("sonar-ws-generator")
 public class SetRemainingProjectsModeRequest {
 
+  private String branch;
   private String portfolio;
 
+  /**
+   */
+  public SetRemainingProjectsModeRequest setBranch(String branch) {
+    this.branch = branch;
+    return this;
+  }
+
+  public String getBranch() {
+    return branch;
+  }
+
   /**
    * This is a mandatory parameter.
    */
@@ -43,5 +55,4 @@ public class SetRemainingProjectsModeRequest {
   public String getPortfolio() {
     return portfolio;
   }
-
 }
index 8fcfbff1b6f640133ddf9354fa1fcc64e6b7613e..33e239820b94db128e6164f2a618e0e0df9fa53a 100644 (file)
@@ -31,9 +31,21 @@ import javax.annotation.Generated;
 @Generated("sonar-ws-generator")
 public class SetTagsModeRequest {
 
+  private String branch;
   private String portfolio;
   private List<String> tags;
 
+  /**
+   */
+  public SetTagsModeRequest setBranch(String branch) {
+    this.branch = branch;
+    return this;
+  }
+
+  public String getBranch() {
+    return branch;
+  }
+
   /**
    * This is a mandatory parameter.
    */
index d81260983b8957cd062bfb76aeff84e6eec81f06..9ab8d60c5c244ca1e684dc56e70352d2e3a430f5 100644 (file)
@@ -73,16 +73,15 @@ public class ViewsService extends BaseService {
    *
    * This is part of the internal API.
    * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_sub_view">Further information about this action online (including a response example)</a>
-   * @since 1.0
+   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_project_branch">Further information about this action online (including a response example)</a>
+   * @since 9.2
    */
-  public void addSubView(AddSubViewRequest request) {
+  public void addProjectBranch(AddProjectBranchRequest request) {
     call(
-      new PostRequest(path("add_sub_view"))
-        .setParam("description", request.getDescription())
+      new PostRequest(path("add_project_branch"))
+        .setParam("branch", request.getBranch())
         .setParam("key", request.getKey())
-        .setParam("name", request.getName())
-        .setParam("subKey", request.getSubKey())
+        .setParam("project", request.getProject())
         .setMediaType(MediaTypes.JSON)
       ).content();
   }
@@ -90,13 +89,17 @@ public class ViewsService extends BaseService {
   /**
    *
    * This is part of the internal API.
-   * This is a GET request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/app">Further information about this action online (including a response example)</a>
+   * This is a POST request.
+   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/add_sub_view">Further information about this action online (including a response example)</a>
    * @since 1.0
    */
-  public String app() {
-    return call(
-      new GetRequest(path("app"))
+  public void addSubView(AddSubViewRequest request) {
+    call(
+      new PostRequest(path("add_sub_view"))
+        .setParam("description", request.getDescription())
+        .setParam("key", request.getKey())
+        .setParam("name", request.getName())
+        .setParam("subKey", request.getSubKey())
         .setMediaType(MediaTypes.JSON)
       ).content();
   }
@@ -114,6 +117,7 @@ public class ViewsService extends BaseService {
         .setParam("description", request.getDescription())
         .setParam("key", request.getKey())
         .setParam("name", request.getName())
+        .setParam("qualifier", request.getQualifier())
         .setParam("visibility", request.getVisibility())
         .setMediaType(MediaTypes.JSON)
       ).content();
@@ -125,7 +129,9 @@ public class ViewsService extends BaseService {
    * This is a POST request.
    * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/define">Further information about this action online (including a response example)</a>
    * @since 1.0
+   * @deprecated since 9.2
    */
+  @Deprecated
   public void define(DefineRequest request) {
     call(
       new PostRequest(path("define"))
@@ -140,7 +146,9 @@ public class ViewsService extends BaseService {
    * This is a GET request.
    * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/definition">Further information about this action online (including a response example)</a>
    * @since 2.0
+   * @deprecated since 9.2
    */
+  @Deprecated
   public String definition() {
     return call(
       new GetRequest(path("definition"))
@@ -277,14 +285,15 @@ public class ViewsService extends BaseService {
    *
    * This is part of the internal API.
    * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/run">Further information about this action online (including a response example)</a>
-   * @since 1.0
-   * @deprecated since 7.1
+   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/remove_project_branch">Further information about this action online (including a response example)</a>
+   * @since 9.2
    */
-  @Deprecated
-  public String run() {
-    return call(
-      new PostRequest(path("run"))
+  public void removeProjectBranch(RemoveProjectBranchRequest request) {
+    call(
+      new PostRequest(path("remove_project_branch"))
+        .setParam("branch", request.getBranch())
+        .setParam("key", request.getKey())
+        .setParam("project", request.getProject())
         .setMediaType(MediaTypes.JSON)
       ).content();
   }
@@ -320,7 +329,7 @@ public class ViewsService extends BaseService {
       new PostRequest(path("set_manual_mode"))
         .setParam("portfolio", request.getPortfolio())
         .setMediaType(MediaTypes.JSON)
-    ).content();
+      ).content();
   }
 
   /**
@@ -335,23 +344,24 @@ public class ViewsService extends BaseService {
       new PostRequest(path("set_none_mode"))
         .setParam("portfolio", request.getPortfolio())
         .setMediaType(MediaTypes.JSON)
-    ).content();
+      ).content();
   }
 
   /**
    *
    * This is part of the internal API.
    * This is a POST request.
-   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/set_remaining_projects_mode">Further information about this action online (including a response example)</a>
+   * @see <a href="https://next.sonarqube.com/sonarqube/web_api/api/views/set_regexp_mode">Further information about this action online (including a response example)</a>
    * @since 7.4
    */
   public void setRegexpMode(SetRegexpModeRequest request) {
     call(
       new PostRequest(path("set_regexp_mode"))
+        .setParam("branch", request.getBranch())
         .setParam("portfolio", request.getPortfolio())
         .setParam("regexp", request.getRegexp())
         .setMediaType(MediaTypes.JSON)
-    ).content();
+      ).content();
   }
 
   /**
@@ -364,9 +374,10 @@ public class ViewsService extends BaseService {
   public void setRemainingProjectsMode(SetRemainingProjectsModeRequest request) {
     call(
       new PostRequest(path("set_remaining_projects_mode"))
+        .setParam("branch", request.getBranch())
         .setParam("portfolio", request.getPortfolio())
         .setMediaType(MediaTypes.JSON)
-    ).content();
+      ).content();
   }
 
   /**
@@ -379,6 +390,7 @@ public class ViewsService extends BaseService {
   public void setTagsMode(SetTagsModeRequest request) {
     call(
       new PostRequest(path("set_tags_mode"))
+        .setParam("branch", request.getBranch())
         .setParam("portfolio", request.getPortfolio())
         .setParam("tags", request.getTags() == null ? null : request.getTags().stream().collect(Collectors.joining(",")))
         .setMediaType(MediaTypes.JSON)