*/
private String kee;
+ /**
+ * Key of the root component this component belongs to. Consistent with projectUUid.
+ */
+ private String projectKey;
+
/**
* Not empty . Max size is 50 (note that effective UUID values are 40 characters with
* the current algorithm in use). Obviously it is unique.
return this;
}
+ /**
+ * Return the root project key. On a root project, return itself
+ */
+ public String projectKey() {
+ return projectKey;
+ }
+
+ public ComponentDto setProjectKey(String projectKey) {
+ this.projectKey = projectKey;
+ return this;
+ }
+
public boolean isRoot() {
return UUID_PATH_OF_ROOT.equals(uuidPath);
}
<select id="selectByQuery" resultType="Component">
select
- <include refid="componentColumns"/>
+ <include refid="componentColumns"/>,
+ root.kee as projectKey
+ from projects p
+ inner join projects root on p.project_uuid=root.uuid and p.organization_uuid=root.organization_uuid
<include refid="sqlSelectByQuery"/>
ORDER BY LOWER(p.name), p.name, p.id
</select>
<select id="countByQuery" resultType="int">
select count(p.id)
+ from projects p
<include refid="sqlSelectByQuery"/>
</select>
<sql id="sqlSelectByQuery">
- from projects p
where
p.enabled=${_true}
AND p.copy_component_uuid is null
import static java.util.Collections.emptySet;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.assertj.guava.api.Assertions.assertThat;
import static org.sonar.db.component.ComponentTesting.newDirectory;
import static org.sonar.db.component.ComponentTesting.newFileDto;
@Test
public void select_provisioned() {
OrganizationDto organization = db.organizations().insert();
- ComponentDto provisionedProject = db.components().insertComponent(ComponentTesting.newPrivateProjectDto(organization).setKey("provisioned.project").setName("Provisioned Project"));
+ ComponentDto provisionedProject = db.components()
+ .insertComponent(ComponentTesting.newPrivateProjectDto(organization).setKey("provisioned.project").setName("Provisioned Project"));
ComponentDto provisionedView = db.components().insertView(organization);
String projectUuid = db.components().insertProjectAndSnapshot(ComponentTesting.newPrivateProjectDto(organization)).getComponentUuid();
String disabledProjectUuid = db.components().insertProjectAndSnapshot(ComponentTesting.newPrivateProjectDto(organization).setEnabled(false)).getComponentUuid();
assertThat(underTest.selectByQuery(dbSession, allProjectsQuery, 0, 10)).extracting(ComponentDto::getKey).containsOnly("public-key", "private-key");
}
+ @Test
+ public void selectByQuery_returns_projectKey() {
+ ComponentDto project = ComponentTesting.newPublicProjectDto(db.getDefaultOrganization()).setKey("project-key");
+ db.components().insertComponent(project);
+ ComponentDto module = ComponentTesting.newModuleDto(project).setKey("module-key");
+ db.components().insertComponent(module);
+ ComponentDto file = ComponentTesting.newFileDto(module).setKey("file-key");
+ db.components().insertComponent(file);
+
+ ComponentQuery allQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT, Qualifiers.MODULE, Qualifiers.FILE).build();
+
+ assertThat(underTest.selectByQuery(dbSession, allQuery, 0, 10)).extracting(ComponentDto::getKey, ComponentDto::projectKey)
+ .containsOnly(tuple("project-key", "project-key"),
+ tuple("module-key", "project-key"),
+ tuple("file-key", "project-key"));
+ }
+
@Test
public void selectByQuery_on_empty_list_of_component_id() {
ComponentQuery dbQuery = ComponentQuery.builder().setQualifiers(Qualifiers.PROJECT).setComponentIds(emptySet()).build();
import static org.sonar.core.util.Protobuf.setNullable;
import static org.sonar.server.util.LanguageParamUtils.getExampleValue;
import static org.sonar.server.util.LanguageParamUtils.getLanguageKeys;
-import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsParameterBuilder.createQualifiersParameter;
+import static org.sonar.server.ws.WsParameterBuilder.QualifierParameterContext.newQualifierParameterContext;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.ACTION_SEARCH;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE;
.setOrganization(organization.getKey())
.setId(dto.uuid())
.setKey(dto.key())
+ .setProjectKey(dto.projectKey())
.setName(dto.name())
.setQualifier(dto.qualifier());
setNullable(dto.language(), builder::setLanguage);
"id": "directory-uuid",
"key": "directory-key",
"qualifier": "DIR",
- "name": "Directory Name"
+ "name": "Directory Name",
+ "projectKey": "project-key"
},
{
"organization": "my-org-1",
"key": "file-key",
"qualifier": "FIL",
"name": "File Name",
- "language": "java"
+ "language": "java",
+ "projectKey": "project-key"
},
{
"organization": "my-org-1",
"id": "module-uuid",
"key": "module-key",
"qualifier": "BRC",
- "name": "Module Name"
+ "name": "Module Name",
+ "projectKey": "project-key"
},
{
"organization": "my-org-1",
"id": "project-uuid",
"key": "project-key",
"qualifier": "TRK",
- "name": "Project Name"
+ "name": "Project Name",
+ "projectKey": "project-key"
}
]
}
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.WsComponents.Component;
import org.sonarqube.ws.WsComponents.SearchWsResponse;
import org.sonarqube.ws.client.component.SearchWsRequest;
+import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.sonar.api.resources.Qualifiers.DIRECTORY;
import static org.sonar.db.component.ComponentTesting.newPrivateProjectDto;
import static org.sonar.db.component.ComponentTesting.newView;
import static org.sonar.test.JsonAssert.assertJson;
-import static org.sonarqube.ws.WsComponents.Component;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_LANGUAGE;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_ORGANIZATION;
import static org.sonarqube.ws.client.component.ComponentsWsParameters.PARAM_QUALIFIERS;
assertThat(response.getComponentsList()).extracting(Component::getKey).containsOnly(file1.getKey(), file2.getKey());
}
+ @Test
+ public void return_project_key() throws IOException {
+ ComponentDto project = ComponentTesting.newPublicProjectDto(db.getDefaultOrganization());
+ ComponentDto module = ComponentTesting.newModuleDto(project);
+ ComponentDto file1 = newFileDto(module).setKey("file1");
+ ComponentDto file2 = newFileDto(module).setKey("file2");
+ ComponentDto file3 = newFileDto(project).setKey("file3");
+ db.components().insertComponents(project, module, file1, file2, file3);
+
+ SearchWsResponse response = call(new SearchWsRequest().setQualifiers(asList(PROJECT, MODULE, FILE)));
+
+ assertThat(response.getComponentsList()).extracting(Component::getKey, Component::getProjectKey)
+ .containsOnly(tuple(project.getKey(), project.getKey()),
+ tuple(module.getKey(), project.getKey()),
+ tuple(file1.getKey(), project.getKey()),
+ tuple(file2.getKey(), project.getKey()),
+ tuple(file3.getKey(), project.getKey()));
+ }
+
@Test
public void do_not_verify_permissions_if_user_is_root() throws IOException {
OrganizationDto org = db.organizations().insert();
optional Tags tags = 14;
optional string visibility = 15;
optional string leakPeriodDate = 16;
+ // Root project key
+ optional string projectKey = 17;
message Tags {
repeated string tags = 1;