import org.sonar.db.component.SnapshotDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.ComponentFinder.ParamNames;
import org.sonar.server.user.UserSession;
import org.sonarqube.ws.WsComponents.ShowWsResponse;
import org.sonarqube.ws.client.component.ShowWsRequest;
+import static com.google.common.base.Preconditions.checkArgument;
import static java.lang.String.format;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
+import static org.sonar.server.component.ComponentFinder.ParamNames.COMPONENT_ID_AND_COMPONENT;
import static org.sonar.server.component.ws.ComponentDtoToWsComponent.componentDtoToWsComponent;
+import static org.sonar.server.ws.KeyExamples.KEY_BRANCH_EXAMPLE_001;
import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SHOW;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT_ID;
+import static org.sonarqube.ws.client.measure.MeasuresWsParameters.PARAM_BRANCH;
public class ShowAction implements ComponentsWsAction {
private final UserSession userSession;
.setDescription("Component key")
.setDeprecatedKey("key", "6.4")
.setExampleValue(KEY_PROJECT_EXAMPLE_001);
+
+ action.createParam(PARAM_BRANCH)
+ .setDescription("Branch key")
+ .setExampleValue(KEY_BRANCH_EXAMPLE_001)
+ .setInternal(true)
+ .setSince("6.6");
}
@Override
private ShowWsResponse doHandle(ShowWsRequest request) {
try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentDto component = getComponentByUuidOrKey(dbSession, request);
+ ComponentDto component = loadComponent(dbSession, request);
Optional<SnapshotDto> lastAnalysis = dbClient.snapshotDao().selectLastAnalysisByComponentUuid(dbSession, component.projectUuid());
List<ComponentDto> ancestors = dbClient.componentDao().selectAncestors(dbSession, component);
OrganizationDto organizationDto = componentFinder.getOrganization(dbSession, component);
}
}
- private ComponentDto getComponentByUuidOrKey(DbSession dbSession, ShowWsRequest request) {
- ComponentDto component = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.COMPONENT_ID_AND_COMPONENT);
+ private ComponentDto loadComponent(DbSession dbSession, ShowWsRequest request) {
+ String componentId = request.getId();
+ String componentKey = request.getKey();
+ String branch = request.getBranch();
+ checkArgument(componentId == null || branch == null, "'%s' and '%s' parameters cannot be used at the same time", PARAM_COMPONENT_ID, PARAM_BRANCH);
+ ComponentDto component = branch == null
+ ? componentFinder.getByUuidOrKey(dbSession, componentId, componentKey, COMPONENT_ID_AND_COMPONENT)
+ : componentFinder.getByKeyAndBranch(dbSession, componentKey, branch);
userSession.checkComponentPermission(UserRole.USER, component);
return component;
}
private static ShowWsRequest toShowWsRequest(Request request) {
return new ShowWsRequest()
.setId(request.param(PARAM_COMPONENT_ID))
- .setKey(request.param(PARAM_COMPONENT));
+ .setKey(request.param(PARAM_COMPONENT))
+ .setBranch(request.param(PARAM_BRANCH));
}
}
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
import org.sonar.db.DbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
-import org.sonarqube.ws.WsComponents;
+import org.sonarqube.ws.WsComponents.Component;
import org.sonarqube.ws.WsComponents.ShowWsResponse;
import static org.assertj.core.api.Assertions.assertThat;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.component.SnapshotTesting.newAnalysis;
import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_BRANCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_COMPONENT_ID;
tuple("6.4", "The field 'id' is deprecated in the response"),
tuple("6.4", "The 'visibility' field is added to the response"),
tuple("6.5", "Leak period date is added to the response"));
+ assertThat(action.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("component", "componentId", "branch");
WebService.Param componentId = action.param(PARAM_COMPONENT_ID);
assertThat(componentId.isRequired()).isFalse();
assertThat(component.exampleValue()).isNotNull();
assertThat(component.deprecatedKey()).isEqualTo("key");
assertThat(component.deprecatedKeySince()).isEqualTo("6.4");
+
+ WebService.Param branch = action.param(PARAM_BRANCH);
+ assertThat(branch.isInternal()).isTrue();
+ assertThat(branch.isRequired()).isFalse();
+ assertThat(branch.since()).isEqualTo("6.6");
}
@Test
ShowWsResponse response = newRequest(null, file.getDbKey());
assertThat(response.getComponent().getKey()).isEqualTo(file.getDbKey());
- assertThat(response.getAncestorsList()).extracting(WsComponents.Component::getKey).containsOnly(directory.getDbKey(), module.getDbKey(), project.getDbKey());
+ assertThat(response.getAncestorsList()).extracting(Component::getKey).containsOnly(directory.getDbKey(), module.getDbKey(), project.getDbKey());
}
@Test
ShowWsResponse response = newRequest(null, file.getDbKey());
String expectedDate = formatDateTime(new Date(3_000_000_000L));
- assertThat(response.getAncestorsList()).extracting(WsComponents.Component::getAnalysisDate)
+ assertThat(response.getAncestorsList()).extracting(Component::getAnalysisDate)
.containsOnly(expectedDate, expectedDate, expectedDate);
}
assertThat(result.getComponent().hasVisibility()).isFalse();
}
+ @Test
+ public void branch() {
+ ComponentDto project = db.components().insertPrivateProject();
+ userSession.addProjectPermission(UserRole.USER, project);
+ String branchKey = "my_branch";
+ ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey(branchKey));
+ ComponentDto module = db.components().insertComponent(newModuleDto(branch));
+ ComponentDto directory = db.components().insertComponent(newDirectory(module, "dir"));
+ ComponentDto file = db.components().insertComponent(newFileDto(directory));
+
+ ShowWsResponse response = ws.newRequest()
+ .setParam(PARAM_COMPONENT, file.getKey())
+ .setParam(PARAM_BRANCH, branchKey)
+ .executeProtobuf(ShowWsResponse.class);
+
+ assertThat(response.getComponent()).extracting(Component::getKey, Component::getBranch)
+ .containsExactlyInAnyOrder(file.getKey(), branchKey);
+ assertThat(response.getAncestorsList()).extracting(Component::getKey, Component::getBranch)
+ .containsExactlyInAnyOrder(
+ tuple(directory.getKey(), branchKey),
+ tuple(module.getKey(), branchKey),
+ tuple(branch.getKey(), branchKey));
+ }
+
@Test
public void throw_ForbiddenException_if_user_doesnt_have_browse_permission_on_project() {
userSession.logIn();
newRequest(null, "file-key");
}
+ @Test
+ public void fail_when_componentId_and_branch_params_are_used_together() {
+ ComponentDto project = db.components().insertPrivateProject();
+ userSession.addProjectPermission(UserRole.USER, project);
+ ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("'componentId' and 'branch' parameters cannot be used at the same time");
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT_ID, branch.uuid())
+ .setParam(PARAM_BRANCH, "my_branch")
+ .execute();
+ }
+
+ @Test
+ public void fail_if_branch_does_not_exist() {
+ ComponentDto project = db.components().insertPrivateProject();
+ ComponentDto file = db.components().insertComponent(newFileDto(project));
+ userSession.addProjectPermission(UserRole.USER, project);
+ db.components().insertProjectBranch(project, b -> b.setKey("my_branch"));
+
+ expectedException.expect(NotFoundException.class);
+ expectedException.expectMessage(String.format("Component '%s' on branch '%s' not found", file.getKey(), "another_branch"));
+
+ ws.newRequest()
+ .setParam(PARAM_COMPONENT, file.getKey())
+ .setParam(PARAM_BRANCH, "another_branch")
+ .execute();
+ }
+
private ShowWsResponse newRequest(@Nullable String uuid, @Nullable String key) {
TestRequest request = ws.newRequest();
if (uuid != null) {