]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-17352 Refactor component keys to not include branch suffix
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Sun, 9 Oct 2022 20:48:07 +0000 (15:48 -0500)
committersonartech <sonartech@sonarsource.com>
Wed, 12 Oct 2022 20:03:44 +0000 (20:03 +0000)
20 files changed:
server/sonar-ce-task-projectanalysis/src/main/java/org/sonar/ce/task/projectanalysis/component/ConfigurationRepositoryImpl.java
server/sonar-ce-task/src/main/java/org/sonar/ce/task/step/ComputationStepExecutor.java
server/sonar-db-dao/src/main/java/org/sonar/db/component/ComponentDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureDao.java
server/sonar-db-dao/src/main/java/org/sonar/db/measure/MeasureMapper.java
server/sonar-db-dao/src/main/resources/org/sonar/db/measure/MeasureMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/component/ComponentDaoTest.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/component/ComponentTesting.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ComponentDtoToWsComponent.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/ShowAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/component/ws/TreeAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/hotspot/ws/SearchAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentAction.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentDtoToWsComponent.java
server/sonar-webserver-webapi/src/main/java/org/sonar/server/measure/ws/ComponentTreeAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ComponentUpdaterTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/ShowActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/component/ws/TreeActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/ComponentActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/measure/ws/ComponentTreeActionTest.java

index 02aba3d59feb973929075def3cbbda3dc3500d1a..9b4e02919901e4faf07dc85283cf639ce81ce2af 100644 (file)
@@ -33,9 +33,11 @@ public class ConfigurationRepositoryImpl implements ConfigurationRepository {
   private final Supplier<Configuration> configuration;
 
   public ConfigurationRepositoryImpl(TreeRootHolder treeRootHolder, AnalysisMetadataHolder analysisMetadataHolder, ProjectConfigurationFactory f) {
-    String branchUuid = treeRootHolder.getRoot().getUuid();
-    String projectUuid = analysisMetadataHolder.getProject().getUuid();
-    this.configuration = Suppliers.memoize(() -> f.newProjectConfiguration(projectUuid, branchUuid));
+    this.configuration = Suppliers.memoize(() -> {
+      String branchUuid = treeRootHolder.getRoot().getUuid();
+      String projectUuid = analysisMetadataHolder.getProject().getUuid();
+      return f.newProjectConfiguration(projectUuid, branchUuid);
+    });
   }
 
   @Override
index b00f8b1432d9c043f33fa117398220bb3d74ab3d..9245232f26ced53b0126227763293b469e9f9831 100644 (file)
@@ -39,12 +39,11 @@ public final class ComputationStepExecutor {
   @CheckForNull
   private final Listener listener;
 
-  @Autowired(required = false)
   public ComputationStepExecutor(ComputationSteps steps, CeTaskInterrupter taskInterrupter) {
     this(steps, taskInterrupter, null);
   }
 
-  @Autowired(required = false)
+  @Autowired
   public ComputationStepExecutor(ComputationSteps steps, CeTaskInterrupter taskInterrupter, @Nullable Listener listener) {
     this.steps = steps;
     this.taskInterrupter = taskInterrupter;
index 687d4e574aa2d7832b0a2b384d687f5b055ed83a..c561e71775ead49059b007517838de48bcb2cbd6 100644 (file)
@@ -194,6 +194,25 @@ public class ComponentDao implements Dao {
     return executeLargeInputs(keys, subKeys -> mapper(session).selectByKeysAndBranchOrPr(subKeys, branch, pullRequest));
   }
 
+  /**
+   * Returns components in the main branch
+   */
+  public Optional<ComponentDto> selectByKey(DbSession session, String key) {
+    return Optional.ofNullable(mapper(session).selectByKeyAndBranchOrPr(key, null, null));
+  }
+
+  public Optional<ComponentDto> selectByKeyAndBranch(DbSession session, String key, String branch) {
+    return Optional.ofNullable(mapper(session).selectByKeyAndBranchOrPr(key, branch, null));
+  }
+
+  public Optional<ComponentDto> selectByKeyAndPullRequest(DbSession session, String key, String pullRequestId) {
+    return Optional.ofNullable(mapper(session).selectByKeyAndBranchOrPr(key, null, pullRequestId));
+  }
+
+  public Optional<ComponentDto> selectByKeyCaseInsensitive(DbSession session, String key) {
+    return Optional.ofNullable(mapper(session).selectByKeyCaseInsensitive(key));
+  }
+
   /**
    * List of ancestors, ordered from root to parent. The list is empty
    * if the component is a tree root. Disabled components are excluded by design
@@ -228,26 +247,6 @@ public class ComponentDao implements Dao {
     return mapper(dbSession).selectChildren(branchUuid, uuidPaths);
   }
 
-  public ComponentDto selectOrFailByKey(DbSession session, String key) {
-    return selectByKey(session, key).orElseThrow(() -> new RowNotFoundException(String.format("Component key '%s' not found", key)));
-  }
-
-  public Optional<ComponentDto> selectByKey(DbSession session, String key) {
-    return Optional.ofNullable(mapper(session).selectByKey(key));
-  }
-
-  public Optional<ComponentDto> selectByKeyCaseInsensitive(DbSession session, String key) {
-    return Optional.ofNullable(mapper(session).selectByKeyCaseInsensitive(key));
-  }
-
-  public Optional<ComponentDto> selectByKeyAndBranch(DbSession session, String key, String branch) {
-    return Optional.ofNullable(mapper(session).selectByKeyAndBranchKey(key, branch));
-  }
-
-  public Optional<ComponentDto> selectByKeyAndPullRequest(DbSession session, String key, String pullRequestId) {
-    return Optional.ofNullable(mapper(session).selectByKeyAndPrKey(key, pullRequestId));
-  }
-
   /*
     SELECT ALL
    */
index 824b61656dc03820c485bb6e4f1c5066edf7c10d..d6b8adb6a0281dac7f1455bb923d6af1f4739b8b 100644 (file)
@@ -76,8 +76,8 @@ public class MeasureDao implements Dao {
     return session.getMapper(MeasureMapper.class);
   }
 
-  public List<ProjectMeasureDto> selectMeasureFromLargestBranchForAllProjects(DbSession session, String metricKey) {
-    return mapper(session).selectMeasureFromLargestBranchForAllProjects(metricKey);
+  public List<ProjectMeasureDto> selectLastMeasureForAllProjects(DbSession session, String metricKey) {
+    return mapper(session).selectLastMeasureForAllProjects(metricKey);
 
   }
 }
index 5b8759b2fae274a68e7c5bfac6f5389c92ec610d..9f80836c15b54630ab0327d09568354c15218102 100644 (file)
@@ -42,5 +42,5 @@ public interface MeasureMapper {
 
   void insert(MeasureDto measureDto);
 
-  List<ProjectMeasureDto> selectMeasureFromLargestBranchForAllProjects(@Param("metricKey") String metricKey);
+  List<ProjectMeasureDto> selectLastMeasureForAllProjects(@Param("metricKey") String metricKey);
 }
index 20cce60af4d14ce5b3438519b8d54af300248ec1..8fa3ab066b1da5d12885d742a0fcbbf851a5e2d0 100644 (file)
@@ -28,7 +28,7 @@
   </select>
 
 
-  <select id="selectMeasureFromLargestBranchForAllProjects" parameterType="map" resultType="ProjectMeasure">
+  <select id="selectLastMeasureForAllProjects" parameterType="map" resultType="ProjectMeasure">
     select tie_breaker.projectUuid as projectUuid,
     s.build_date as lastAnalysis,
     ncloc as loc,
index 12d3bcd450a9bd1cc0261f4a867061650605c102..3533a00faea2f1d1c79469f75d9b3c8f32c44003 100644 (file)
@@ -2055,7 +2055,7 @@ public class ComponentDaoTest {
   @Test
   public void selectByKeyCaseInsensitive_shouldFindProject_whenCaseIsDifferent() {
     String projectKey = randomAlphabetic(5).toLowerCase();
-    db.components().insertPrivateProject(c -> c.setDbKey(projectKey));
+    db.components().insertPrivateProject(c -> c.setKey(projectKey));
 
     ComponentDto result = underTest.selectByKeyCaseInsensitive(db.getSession(), projectKey.toUpperCase()).orElse(null);
 
@@ -2066,7 +2066,7 @@ public class ComponentDaoTest {
   @Test
   public void selectByKeyCaseInsensitive_shouldNotFindProject_whenKeyIsDifferent() {
     String projectKey = randomAlphabetic(5).toLowerCase();
-    db.components().insertPrivateProject(c -> c.setDbKey(projectKey));
+    db.components().insertPrivateProject(c -> c.setKey(projectKey));
 
     Optional<ComponentDto> result = underTest.selectByKeyCaseInsensitive(db.getSession(), projectKey + randomAlphabetic(1));
 
index 1cbf60e75fcb82d156cebec18976cde6d006d032..b9d6e5c8b82dfd898f71a6acb23f746c4d611514 100644 (file)
@@ -32,6 +32,7 @@ import static org.sonar.db.component.BranchDto.DEFAULT_MAIN_BRANCH_NAME;
 import static org.sonar.db.component.ComponentDto.UUID_PATH_OF_ROOT;
 import static org.sonar.db.component.ComponentDto.UUID_PATH_SEPARATOR;
 import static org.sonar.db.component.ComponentDto.formatUuidPathFromParent;
+import static org.sonar.db.component.ComponentDto.generateBranchKey;
 
 public class ComponentTesting {
 
@@ -170,6 +171,18 @@ public class ComponentTesting {
       .setLanguage(null);
   }
 
+  public static ComponentDto newProjectBranchCopy(String uuid, ComponentDto project, ComponentDto view, String branch) {
+    return newChildComponent(uuid, view, view)
+      .setKey(generateBranchKey(view.getKey() + project.getKey(), branch))
+      .setName(project.name())
+      .setLongName(project.longName())
+      .setCopyComponentUuid(project.uuid())
+      .setScope(Scopes.FILE)
+      .setQualifier(Qualifiers.PROJECT)
+      .setPath(null)
+      .setLanguage(null);
+  }
+
   public static ComponentDto newChildComponent(String uuid, ComponentDto moduleOrProject, ComponentDto parent) {
     checkArgument(moduleOrProject.isPrivate() == parent.isPrivate(),
       "private flag inconsistent between moduleOrProject (%s) and parent (%s)",
index 868249ea30d4346321afc322d9469592d7082f95..e92505dc163d9d45760ee7d4de8cd3a6979cc0c5 100644 (file)
@@ -68,7 +68,7 @@ class ComponentDtoToWsComponent {
   public static Components.Component.Builder componentDtoToWsComponent(ComponentDto dto, @Nullable ProjectDto parentProjectDto,
     @Nullable SnapshotDto lastAnalysis, @Nullable String branch, @Nullable String pullRequest) {
     Components.Component.Builder wsComponent = Components.Component.newBuilder()
-      .setKey(dto.getKey())
+      .setKey(ComponentDto.removeBranchAndPullRequestFromKey(dto.getKey()))
       .setName(dto.name())
       .setQualifier(dto.qualifier());
     ofNullable(emptyToNull(branch)).ifPresent(wsComponent::setBranch);
index f7525e9e56d45728afb2a0bbafefbc8c3288e66e..d0d197f730ed6e9a497bd269071bd5fe099b8cf5 100644 (file)
@@ -155,13 +155,18 @@ public class ShowAction implements ComponentsWsAction {
       boolean needIssueSync = needIssueSync(dbSession, component, parentProject.orElse(null));
       if (component.getCopyComponentUuid() != null) {
         String branch = dbClient.branchDao().selectByUuid(dbSession, component.getCopyComponentUuid())
+          .filter(b -> !b.isMain())
           .map(BranchDto::getKey)
           .orElse(null);
         return componentDtoToWsComponent(component, parentProject.orElse(null), lastAnalysis, branch, null)
           .setNeedIssueSync(needIssueSync);
+      } else if (component.getMainBranchProjectUuid() != null) {
+        return componentDtoToWsComponent(component, parentProject.orElse(null), lastAnalysis, request.branch, request.pullRequest)
+          .setNeedIssueSync(needIssueSync);
+      } else {
+        return componentDtoToWsComponent(component, parentProject.orElse(null), lastAnalysis, null, null)
+          .setNeedIssueSync(needIssueSync);
       }
-      return componentDtoToWsComponent(component, parentProject.orElse(null), lastAnalysis, request.branch, request.pullRequest)
-        .setNeedIssueSync(needIssueSync);
     }
   }
 
index 16635cf1c3c32931ea1ae97fe57e60cc888df118..fa0219377aac34296fd5e6cd067df1862dde4c95 100644 (file)
@@ -230,6 +230,7 @@ public class TreeAction implements ComponentsWsAction {
 
     Map<String, String> branchKeyByReferenceUuid = dbClient.branchDao().selectByUuids(dbSession, referenceComponentsByUuid.keySet())
       .stream()
+      .filter(b -> !b.isMain())
       .collect(Collectors.toMap(BranchDto::getUuid, BranchDto::getBranchKey));
 
     response.setBaseComponent(toWsComponent(dbSession, baseComponent, referenceComponentsByUuid, branchKeyByReferenceUuid, request));
@@ -255,8 +256,10 @@ public class TreeAction implements ComponentsWsAction {
 
       if (referenceComponent != null) {
         wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), null, branchKeyByReferenceUuid.get(referenceComponent.uuid()), null);
-      } else {
+      } else if (component.getMainBranchProjectUuid() != null) {
         wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), null, request.branch, request.pullRequest);
+      } else {
+        wsComponent = componentDtoToWsComponent(component, parentProject.orElse(null), null, null, null);
       }
     }
 
index ac108f7654df7d7d39e0aa591600f0672d80a72b..94380c40e497379d6e4a57f3298696415cefa728 100644 (file)
@@ -638,7 +638,7 @@ public class SearchAction implements HotspotsWsAction {
     for (ComponentDto component : components) {
       String branchUuid = component.getCopyComponentUuid() != null ? component.getCopyComponentUuid() : component.branchUuid();
       BranchDto branchDto = searchResponseData.getBranch(branchUuid);
-      if (branchDto == null) {
+      if (branchDto == null && component.getCopyComponentUuid() == null) {
         throw new IllegalStateException("Could not find a branch for a component " + component.getKey() + " with uuid " + component.uuid());
       }
       responseBuilder.addComponents(responseFormatter.formatComponent(builder, component, branchDto));
index bdbbeaeb817dd35cabcdafb9dbbe24745d46ced4..8e6f553c2468f1d5b899975d884f88ed234a414c 100644 (file)
@@ -40,6 +40,7 @@ import org.sonar.api.web.UserRole;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
+import org.sonar.db.component.BranchDto;
 import org.sonar.db.component.ComponentDto;
 import org.sonar.db.component.SnapshotDto;
 import org.sonar.db.measure.LiveMeasureDto;
@@ -159,8 +160,8 @@ public class ComponentAction implements MeasuresWsAction {
       }
 
       Optional<Measures.Period> period = snapshotToWsPeriods(analysis);
-      Optional<ComponentDto> refComponent = getReferenceComponent(dbSession, component);
-      return buildResponse(request, component, refComponent, measuresByMetric, metrics, period);
+      Optional<RefComponent> reference = getReference(dbSession, component);
+      return buildResponse(request, component, reference, measuresByMetric, metrics, period);
     }
   }
 
@@ -223,31 +224,33 @@ public class ComponentAction implements MeasuresWsAction {
 
   private ComponentDto loadComponent(DbSession dbSession, ComponentRequest request, @Nullable String branch, @Nullable String pullRequest) {
     String componentKey = request.getComponent();
-
-    if (branch == null && pullRequest == null) {
-      return componentFinder.getByKey(dbSession, componentKey);
-    }
-
     checkRequest(componentKey != null, "The '%s' parameter is missing", PARAM_COMPONENT);
     return componentFinder.getByKeyAndOptionalBranchOrPullRequest(dbSession, componentKey, branch, pullRequest);
   }
 
-  private Optional<ComponentDto> getReferenceComponent(DbSession dbSession, ComponentDto component) {
+  private Optional<RefComponent> getReference(DbSession dbSession, ComponentDto component) {
     if (component.getCopyComponentUuid() == null) {
       return Optional.empty();
     }
 
-    return dbClient.componentDao().selectByUuid(dbSession, component.getCopyComponentUuid());
+    Optional<ComponentDto> refComponent = dbClient.componentDao().selectByUuid(dbSession, component.getCopyComponentUuid());
+    if (refComponent.isEmpty()) {
+      return Optional.empty();
+    }
+    Optional<BranchDto> refBranch = dbClient.branchDao().selectByUuid(dbSession, refComponent.get().branchUuid());
+    return refBranch.map(rb -> new RefComponent(rb, refComponent.get()));
   }
 
-  private static ComponentWsResponse buildResponse(ComponentRequest request, ComponentDto component, Optional<ComponentDto> refComponent,
+  private static ComponentWsResponse buildResponse(ComponentRequest request, ComponentDto component, Optional<RefComponent> reference,
     Map<MetricDto, LiveMeasureDto> measuresByMetric, Collection<MetricDto> metrics, Optional<Measures.Period> period) {
     ComponentWsResponse.Builder response = ComponentWsResponse.newBuilder();
     boolean isMainBranch = component.getMainBranchProjectUuid() == null;
 
-    if (refComponent.isPresent()) {
-      response.setComponent(componentDtoToWsComponent(component, measuresByMetric, singletonMap(refComponent.get().uuid(),
-        refComponent.get()), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
+    if (reference.isPresent()) {
+      BranchDto refBranch = reference.get().getRefBranch();
+      ComponentDto refComponent = reference.get().getComponent();
+      response.setComponent(componentDtoToWsComponent(component, measuresByMetric, singletonMap(refComponent.uuid(), refComponent),
+        refBranch.isMain() ? null : refBranch.getBranchKey(), null));
     } else {
       response.setComponent(componentDtoToWsComponent(component, measuresByMetric, emptyMap(), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
     }
@@ -343,4 +346,22 @@ public class ComponentAction implements MeasuresWsAction {
       return this;
     }
   }
+
+  private static class RefComponent {
+    public RefComponent(BranchDto refBranch, ComponentDto refComponent) {
+      this.refBranch = refBranch;
+      this.refComponent = refComponent;
+    }
+
+    private BranchDto refBranch;
+    private ComponentDto refComponent;
+
+    public BranchDto getRefBranch() {
+      return refBranch;
+    }
+
+    public ComponentDto getComponent() {
+      return refComponent;
+    }
+  }
 }
index 51f079449404de9365367555400c89905929422a..6b1220565895935462ebda442bad9edb577688bf 100644 (file)
@@ -56,7 +56,7 @@ class ComponentDtoToWsComponent {
 
   static Component.Builder componentDtoToWsComponent(ComponentDto component, @Nullable String branch, @Nullable String pullRequest) {
     Component.Builder wsComponent = Component.newBuilder()
-      .setKey(component.getKey())
+      .setKey(ComponentDto.removeBranchAndPullRequestFromKey(component.getKey()))
       .setName(component.name())
       .setQualifier(component.qualifier());
     ofNullable(branch).ifPresent(wsComponent::setBranch);
index 6d822a5add5312c274fb49eec6d9e77ca7fbc943..6471ad3b1c3b4dc11c11c46b70239516e05c15a1 100644 (file)
@@ -276,7 +276,7 @@ public class ComponentTreeAction implements MeasuresWsAction {
       request,
       data,
       Paging.forPageIndex(
-          request.getPage())
+        request.getPage())
         .withPageSize(request.getPageSize())
         .andTotal(data.getComponentCount()));
   }
@@ -289,24 +289,25 @@ public class ComponentTreeAction implements MeasuresWsAction {
       .setTotal(paging.total())
       .build();
 
+    boolean isMainBranch = data.getBaseComponent().getMainBranchProjectUuid() == null;
     response.setBaseComponent(
       toWsComponent(
         data.getBaseComponent(),
         data.getMeasuresByComponentUuidAndMetric().row(data.getBaseComponent().uuid()),
-        data.getReferenceComponentsByUuid(), request.getBranch(), request.getPullRequest()));
+        data.getReferenceComponentsByUuid(), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
 
     for (ComponentDto componentDto : data.getComponents()) {
       if (componentDto.getCopyComponentUuid() != null) {
-        String branch = data.getBranchByReferenceUuid().get(componentDto.getCopyComponentUuid());
+        String refBranch = data.getBranchByReferenceUuid().get(componentDto.getCopyComponentUuid());
         response.addComponents(toWsComponent(
           componentDto,
           data.getMeasuresByComponentUuidAndMetric().row(componentDto.uuid()),
-          data.getReferenceComponentsByUuid(), branch, null));
+          data.getReferenceComponentsByUuid(), refBranch, null));
       } else {
         response.addComponents(toWsComponent(
           componentDto,
           data.getMeasuresByComponentUuidAndMetric().row(componentDto.uuid()),
-          data.getReferenceComponentsByUuid(), request.getBranch(), request.getPullRequest()));
+          data.getReferenceComponentsByUuid(), isMainBranch ? null : request.getBranch(), request.getPullRequest()));
       }
     }
 
@@ -342,7 +343,8 @@ public class ComponentTreeAction implements MeasuresWsAction {
       .setPageSize(request.getPageSize())
       .setTotal(0);
     if (baseComponent != null) {
-      response.setBaseComponent(componentDtoToWsComponent(baseComponent, request.getBranch(), request.getPullRequest()));
+      boolean isMainBranch = baseComponent.getMainBranchProjectUuid() == null;
+      response.setBaseComponent(componentDtoToWsComponent(baseComponent, isMainBranch ? null : request.getBranch(), request.getPullRequest()));
     }
     return response.build();
   }
@@ -467,7 +469,9 @@ public class ComponentTreeAction implements MeasuresWsAction {
   }
 
   private Map<String, String> searchReferenceBranchKeys(DbSession dbSession, Set<String> referenceUuids) {
-    return dbClient.branchDao().selectByUuids(dbSession, referenceUuids).stream().collect(Collectors.toMap(BranchDto::getUuid, BranchDto::getBranchKey));
+    return dbClient.branchDao().selectByUuids(dbSession, referenceUuids).stream()
+      .filter(b -> !b.isMain())
+      .collect(Collectors.toMap(BranchDto::getUuid, BranchDto::getBranchKey));
   }
 
   private static boolean isPR(@Nullable String pullRequest) {
index b761e96a01f190a902ec70c942895faadadbf323..f6b472cbc8eb4da2ae40812557488c0919a93064 100644 (file)
@@ -253,7 +253,7 @@ public class ComponentUpdaterTest {
       .build();
     assertThatThrownBy(() -> underTest.create(session, newComponent, null, null))
       .isInstanceOf(BadRequestException.class)
-      .hasMessage("Could not create Project, key already exists: " + existing.getKey());
+      .hasMessage("Could not create Project with key: \"%s\". A similar key already exists: \"%s\"", existing.getKey(), existing.getKey());
   }
 
   @Test
index 6084ef4f5a7ee84c8780a95d24181f8e3cc3d48f..1793a77a430519aebcb4376c91ce2c881a890031 100644 (file)
@@ -284,6 +284,22 @@ public class ShowActionTest {
         tuple(branch.getKey(), branchKey, "1.1"));
   }
 
+  @Test
+  public void dont_show_branch_if_main_branch() {
+    ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(UserRole.USER, project);
+    String branchKey = "master";
+
+    ShowWsResponse response = ws.newRequest()
+      .setParam(PARAM_COMPONENT, project.getKey())
+      .setParam(PARAM_BRANCH, branchKey)
+      .executeProtobuf(ShowWsResponse.class);
+
+    assertThat(response.getComponent())
+      .extracting(Component::getKey, Component::getBranch)
+      .containsExactlyInAnyOrder(project.getKey(), "");
+  }
+
   @Test
   public void pull_request() {
     ComponentDto project = db.components().insertPrivateProject();
index 88859bd69bb31fc2806496e666c7beaff6472d63..c0564c6ed34237ddea94dc6603ae647638a547fe 100644 (file)
@@ -48,7 +48,6 @@ import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.TestRequest;
 import org.sonar.server.ws.WsActionTester;
 import org.sonar.test.JsonAssert;
-import org.sonarqube.ws.Components;
 import org.sonarqube.ws.Components.Component;
 import org.sonarqube.ws.Components.TreeWsResponse;
 
@@ -67,6 +66,7 @@ import static org.sonar.db.component.ComponentTesting.newChildComponent;
 import static org.sonar.db.component.ComponentTesting.newDirectory;
 import static org.sonar.db.component.ComponentTesting.newModuleDto;
 import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
+import static org.sonar.db.component.ComponentTesting.newProjectBranchCopy;
 import static org.sonar.db.component.ComponentTesting.newProjectCopy;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BRANCH;
 import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT;
@@ -271,6 +271,28 @@ public class TreeActionTest {
     assertThat(response.getComponentsList()).extracting("refKey").containsExactly("project-key-1", "");
   }
 
+  @Test
+  public void project_branch_reference_from_portfolio() {
+    ComponentDto view = ComponentTesting.newPortfolio("view-uuid");
+    db.components().insertPortfolioAndSnapshot(view);
+    ComponentDto project = newPrivateProjectDto("project-uuid-1").setName("project-name").setKey("project-key-1");
+    db.components().insertProjectAndSnapshot(project);
+    db.components().insertComponent(newProjectBranchCopy("project-uuid-1-copy", project, view, "branch1"));
+    db.components().insertComponent(ComponentTesting.newSubPortfolio(view, "sub-view-uuid", "sub-view-key").setName("sub-view-name"));
+    db.commit();
+    userSession.logIn()
+      .registerComponents(view, project);
+
+    TreeWsResponse response = ws.newRequest()
+      .setParam(PARAM_STRATEGY, "children")
+      .setParam(PARAM_COMPONENT, view.getKey())
+      .setParam(Param.TEXT_QUERY, "name").executeProtobuf(TreeWsResponse.class);
+
+    assertThat(response.getComponentsList()).extracting("key").containsExactly("KEY_view-uuidproject-key-1", "sub-view-key");
+    assertThat(response.getComponentsList()).extracting("refId").containsExactly("project-uuid-1", "");
+    assertThat(response.getComponentsList()).extracting("refKey").containsExactly("project-key-1", "");
+  }
+
   @Test
   public void project_branch_reference_from_application_branch() {
     ComponentDto application = db.components().insertPrivateProject(c -> c.setQualifier(APP).setKey("app-key"));
@@ -354,6 +376,21 @@ public class TreeActionTest {
         tuple(file.getKey(), branchKey));
   }
 
+  @Test
+  public void dont_show_branch_if_main_branch() {
+    ComponentDto project = db.components().insertPrivateProject();
+    ComponentDto file = db.components().insertComponent(ComponentTesting.newFileDto(project));
+    userSession.addProjectPermission(UserRole.USER, project);
+
+    TreeWsResponse response = ws.newRequest()
+      .setParam(PARAM_COMPONENT, file.getKey())
+      .setParam(PARAM_BRANCH, "master")
+      .executeProtobuf(TreeWsResponse.class);
+
+    assertThat(response.getBaseComponent()).extracting(Component::getKey, Component::getBranch)
+      .containsExactlyInAnyOrder(file.getKey(), "");
+  }
+
   @Test
   public void pull_request() {
     ComponentDto project = db.components().insertPrivateProject();
index 0d4f7684181efba0fe86196b4aa4c623c6cc7993..e3e8ecba3e7925622d92e26d639589d1da83ef38 100644 (file)
@@ -138,6 +138,23 @@ public class ComponentActionTest {
       .containsExactlyInAnyOrder(tuple(complexity.getKey(), measure.getValue()));
   }
 
+  @Test
+  public void branch_not_set_if_main_branch() {
+    ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(USER, project);
+    ComponentDto file = db.components().insertComponent(newFileDto(project));
+    MetricDto complexity = db.measures().insertMetric(m1 -> m1.setKey("complexity").setValueType("INT"));
+
+    ComponentWsResponse response = ws.newRequest()
+      .setParam(PARAM_COMPONENT, file.getKey())
+      .setParam(PARAM_BRANCH, "master")
+      .setParam(PARAM_METRIC_KEYS, "complexity")
+      .executeProtobuf(ComponentWsResponse.class);
+
+    assertThat(response.getComponent()).extracting(Component::getKey, Component::getBranch)
+      .containsExactlyInAnyOrder(file.getKey(), "");
+  }
+
   @Test
   public void pull_request() {
     ComponentDto project = db.components().insertPrivateProject();
index b2e489198fced019faff100332a98ea3958979a4..353d901140606c40f8bba3243c148bfdb38720b4 100644 (file)
@@ -555,6 +555,23 @@ public class ComponentTreeActionTest {
       .containsExactlyInAnyOrder(tuple(complexity.getKey(), measure.getValue()));
   }
 
+  @Test
+  public void dont_show_branch_if_main_branch() {
+    ComponentDto project = db.components().insertPrivateProject();
+    userSession.addProjectPermission(USER, project);
+    ComponentDto file = db.components().insertComponent(newFileDto(project));
+    MetricDto complexity = db.measures().insertMetric(m -> m.setValueType(INT.name()));
+
+    ComponentTreeWsResponse response = ws.newRequest()
+      .setParam(PARAM_COMPONENT, file.getKey())
+      .setParam(PARAM_BRANCH, "master")
+      .setParam(PARAM_METRIC_KEYS, complexity.getKey())
+      .executeProtobuf(ComponentTreeWsResponse.class);
+
+    assertThat(response.getBaseComponent()).extracting(Component::getKey, Component::getBranch)
+      .containsExactlyInAnyOrder(file.getKey(), "");
+  }
+
   @Test
   public void pull_request() {
     ComponentDto project = db.components().insertPrivateProject();