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
@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;
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
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
*/
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);
}
}
void insert(MeasureDto measureDto);
- List<ProjectMeasureDto> selectMeasureFromLargestBranchForAllProjects(@Param("metricKey") String metricKey);
+ List<ProjectMeasureDto> selectLastMeasureForAllProjects(@Param("metricKey") String metricKey);
}
</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,
@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);
@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));
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 {
.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)",
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);
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);
}
}
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));
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);
}
}
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));
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;
}
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);
}
}
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()));
}
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;
+ }
+ }
}
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);
request,
data,
Paging.forPageIndex(
- request.getPage())
+ request.getPage())
.withPageSize(request.getPageSize())
.andTotal(data.getComponentCount()));
}
.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()));
}
}
.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();
}
}
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) {
.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
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();
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;
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;
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"));
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();
.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();
.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();