}
// must SELECT first everything
- ResourceDto project = mapper.selectProject(projectOrModuleUuid);
+ ResourceDto project = mapper.selectProjectByUuid(projectOrModuleUuid);
String projectOldKey = project.getKey();
List<ResourceDto> resources = mapper.selectProjectResources(projectOrModuleUuid);
resources.add(project);
.filter(branch -> !projectOrModuleUuid.equals(branch.getUuid()))
.forEach(branch -> {
resources.addAll(mapper.selectProjectResources(branch.getUuid()));
- resources.add(mapper.selectProject(branch.getUuid()));
+ resources.add(mapper.selectProjectByUuid(branch.getUuid()));
});
// and then proceed with the batch UPDATE at once
}
private static Set<ResourceDto> collectAllModules(String projectUuid, String stringToReplace, ComponentKeyUpdaterMapper mapper, boolean includeDisabled) {
- ResourceDto project = mapper.selectProject(projectUuid);
+ ResourceDto project = mapper.selectProjectByUuid(projectUuid);
Set<ResourceDto> modules = new HashSet<>();
if (project.getKey().contains(stringToReplace) && (project.isEnabled() || includeDisabled)) {
modules.add(project);
import java.util.List;
import org.apache.ibatis.annotations.Param;
-/**
- * @since 3.2
- */
public interface ComponentKeyUpdaterMapper {
int countResourceByKey(String key);
- ResourceDto selectProject(@Param("uuid") String uuid);
+ ResourceDto selectProjectByUuid(@Param("uuid") String uuid);
List<ResourceDto> selectProjectResources(@Param("rootUuid") String rootUuid);
WHERE kee = #{key,jdbcType=VARCHAR}
</select>
- <select id="selectProject" parameterType="String" resultMap="resourceResultMap">
+ <select id="selectProjectByUuid" parameterType="String" resultMap="resourceResultMap">
select * from projects
where uuid = #{uuid,jdbcType=VARCHAR}
</select>
if (!Qualifiers.PROJECT.equals(component.qualifier()) || !Scopes.PROJECT.equals(component.scope())) {
errors.add(format("Component '%s' is not a project", rawProjectKey));
}
- if (!project.get().projectUuid().equals(project.get().uuid())) {
+ if (!component.projectUuid().equals(component.uuid())) {
// Project key is already used as a module of another project
- ComponentDto anotherBaseProject = dbClient.componentDao().selectOrFailByUuid(dbSession, project.get().projectUuid());
+ ComponentDto anotherBaseProject = dbClient.componentDao().selectOrFailByUuid(dbSession, component.projectUuid());
errors.add(format("The project '%s' is already defined in SonarQube but as a module of project '%s'. "
+ "If you really want to stop directly analysing project '%s', please first delete it from SonarQube and then relaunch the analysis of project '%s'.",
rawProjectKey, anotherBaseProject.getKey(), anotherBaseProject.getKey(), rawProjectKey));
*/
package org.sonar.server.project.ws;
+import com.google.common.base.Optional;
import org.sonar.api.server.ws.Change;
import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
-import org.sonar.server.component.ComponentFinder;
-import org.sonar.server.component.ComponentFinder.ParamNames;
import org.sonar.server.component.ComponentService;
-
-import javax.annotation.CheckForNull;
-import javax.annotation.Nullable;
+import org.sonar.server.exceptions.NotFoundException;
import static com.google.common.base.Preconditions.checkArgument;
import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01;
public class UpdateKeyAction implements ProjectsWsAction {
private final DbClient dbClient;
- private final ComponentFinder componentFinder;
private final ComponentService componentService;
- public UpdateKeyAction(DbClient dbClient, ComponentFinder componentFinder, ComponentService componentService) {
+ public UpdateKeyAction(DbClient dbClient, ComponentService componentService) {
this.dbClient = dbClient;
- this.componentFinder = componentFinder;
this.componentService = componentService;
}
public WebService.NewAction doDefine(WebService.NewController context) {
WebService.NewAction action = context.createAction(ACTION_UPDATE_KEY)
.setDescription("Update a project or module key and all its sub-components keys.<br>" +
- "Either '%s' or '%s' must be provided.<br> " +
- "Requires one of the following permissions: " +
- "<ul>" +
- "<li>'Administer System'</li>" +
- "<li>'Administer' rights on the specified project</li>" +
- "</ul>",
+ "Either '%s' or '%s' must be provided.<br> " +
+ "Requires one of the following permissions: " +
+ "<ul>" +
+ "<li>'Administer System'</li>" +
+ "<li>'Administer' rights on the specified project</li>" +
+ "</ul>",
PARAM_FROM, PARAM_PROJECT_ID)
.setSince("6.1")
.setPost(true)
.setHandler(this);
action.setChangelog(
- new Change("6.4", "Move from api/components/update_key to api/projects/update_key"));
+ new Change("6.4", "Move from api/components/update_key to api/projects/update_key"),
+ new Change("7.1", "Ability to update key of a disabled module"));
action.createParam(PARAM_PROJECT_ID)
.setDescription("Project or module id")
@Override
public void handle(Request request, Response response) throws Exception {
- doHandle(toWsRequest(request));
- response.noContent();
- }
+ String uuid = request.param(PARAM_PROJECT_ID);
+ String key = request.param(PARAM_FROM);
+ String newKey = request.mandatoryParam(PARAM_TO);
+ checkArgument(uuid != null ^ key != null, "Either '%s' or '%s' must be provided", PARAM_PROJECT_ID, PARAM_FROM);
- private void doHandle(UpdateKeyRequest request) {
try (DbSession dbSession = dbClient.openSession(false)) {
- ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.PROJECT_ID_AND_FROM);
- componentService.updateKey(dbSession, projectOrModule, request.getNewKey());
- }
- }
-
- private static UpdateKeyRequest toWsRequest(Request request) {
- return UpdateKeyRequest.builder()
- .setId(request.param(PARAM_PROJECT_ID))
- .setKey(request.param(PARAM_FROM))
- .setNewKey(request.mandatoryParam(PARAM_TO))
- .build();
- }
-
- private static class UpdateKeyRequest {
- private final String id;
- private final String key;
- private final String newKey;
-
- public UpdateKeyRequest(Builder builder) {
- this.id = builder.id;
- this.key = builder.key;
- this.newKey = builder.newKey;
- }
-
- @CheckForNull
- public String getId() {
- return id;
- }
-
- @CheckForNull
- public String getKey() {
- return key;
- }
-
- public String getNewKey() {
- return newKey;
- }
-
- public static Builder builder() {
- return new Builder();
- }
- }
-
- private static class Builder {
- private String id;
- private String key;
- private String newKey;
-
- private Builder() {
- // enforce method constructor
- }
-
- public Builder setId(@Nullable String id) {
- this.id = id;
- return this;
- }
-
- public Builder setKey(@Nullable String key) {
- this.key = key;
- return this;
- }
-
- public Builder setNewKey(String newKey) {
- this.newKey = newKey;
- return this;
- }
-
- public UpdateKeyRequest build() {
- checkArgument(newKey != null && !newKey.isEmpty(), "The new key must not be empty");
- return new UpdateKeyRequest(this);
+ Optional<ComponentDto> component;
+ if (uuid != null) {
+ component = dbClient.componentDao().selectByUuid(dbSession, uuid);
+ } else {
+ component = dbClient.componentDao().selectByKey(dbSession, key);
+ }
+ if (!component.isPresent() || component.get().getMainBranchProjectUuid() != null) {
+ throw new NotFoundException("Component not found");
+ }
+
+ componentService.updateKey(dbSession, component.get(), newKey);
}
+ response.noContent();
}
}
*/
package org.sonar.server.project.ws;
+import com.google.common.base.Optional;
import javax.annotation.Nullable;
import org.junit.Rule;
import org.junit.Test;
import org.sonar.api.server.ws.WebService;
import org.sonar.api.server.ws.WebService.Param;
import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.ComponentTesting;
import org.sonar.server.component.ComponentService;
-import org.sonar.server.component.TestComponentFinder;
+import org.sonar.server.es.ProjectIndexers;
+import org.sonar.server.es.ProjectIndexersImpl;
+import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.ws.TestRequest;
import org.sonar.server.ws.WsActionTester;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_TO;
public ExpectedException expectedException = ExpectedException.none();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
+ @Rule
+ public UserSessionRule userSessionRule = UserSessionRule.standalone();
+ private DbClient dbClient = db.getDbClient();
+ private ProjectIndexers projectIndexers = new ProjectIndexersImpl();
+ private ComponentService componentService = new ComponentService(dbClient, userSessionRule, projectIndexers);
+ private WsActionTester ws = new WsActionTester(new UpdateKeyAction(dbClient, componentService));
- ComponentDbTester componentDb = new ComponentDbTester(db);
- DbClient dbClient = db.getDbClient();
+ @Test
+ public void update_key_of_project_referenced_by_its_key() {
+ ComponentDto project = insertProject();
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
- ComponentService componentService = mock(ComponentService.class);
+ callByKey(project.getKey(), ANOTHER_KEY);
- WsActionTester ws = new WsActionTester(new org.sonar.server.project.ws.UpdateKeyAction(dbClient, TestComponentFinder.from(db), componentService));
+ assertThat(selectByKey(project.getKey()).isPresent()).isFalse();
+ assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(project.uuid());
+ }
@Test
- public void call_by_key() {
+ public void update_key_of_project_referenced_by_its_uuid() {
ComponentDto project = insertProject();
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
- callByKey(project.getDbKey(), ANOTHER_KEY);
+ callByUuid(project.uuid(), ANOTHER_KEY);
- assertCallComponentService(ANOTHER_KEY);
+ assertThat(selectByKey(project.getKey()).isPresent()).isFalse();
+ assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(project.uuid());
}
@Test
- public void call_by_uuid() {
+ public void update_key_of_module_referenced_by_its_uuid() {
ComponentDto project = insertProject();
+ ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project));
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
- callByUuid(project.uuid(), ANOTHER_KEY);
+ callByUuid(module.uuid(), ANOTHER_KEY);
- assertCallComponentService(ANOTHER_KEY);
+ assertThat(selectByKey(project.getKey()).isPresent()).isTrue();
+ assertThat(selectByKey(module.getKey()).isPresent()).isFalse();
+ assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(module.uuid());
}
@Test
- public void fail_if_new_key_is_not_provided() {
- expectedException.expect(IllegalArgumentException.class);
+ public void update_key_of_disabled_module() {
+ ComponentDto project = insertProject();
+ ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project).setEnabled(false));
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
+
+ callByKey(module.getKey(), ANOTHER_KEY);
+
+ assertThat(selectByKey(project.getKey()).isPresent()).isTrue();
+ assertThat(selectByKey(module.getKey()).isPresent()).isFalse();
+ ComponentDto loadedModule = selectByKey(ANOTHER_KEY).get();
+ assertThat(loadedModule.uuid()).isEqualTo(module.uuid());
+ assertThat(loadedModule.isEnabled()).isFalse();
+ }
+
+
+ @Test
+ public void fail_if_not_authorized() {
+ ComponentDto project = insertProject();
+ userSessionRule.addProjectPermission(UserRole.USER, project);
+
+ expectedException.expect(ForbiddenException.class);
+ expectedException.expectMessage("Insufficient privileges");
+
+ callByKey(project.getKey(), ANOTHER_KEY);
+ }
+ @Test
+ public void fail_if_new_key_is_not_provided() {
ComponentDto project = insertProject();
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
+
+ expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("The 'to' parameter is missing");
- callByKey(project.getDbKey(), null);
+ callByKey(project.getKey(), null);
}
@Test
public void fail_if_uuid_nor_key_provided() {
expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Either 'projectId' or 'from' must be provided");
call(null, null, ANOTHER_KEY);
}
@Test
- public void fail_if_uuid_and_key_provided() {
+ public void fail_if_both_uuid_and_key_provided() {
+ ComponentDto project = insertProject();
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
+
expectedException.expect(IllegalArgumentException.class);
+ expectedException.expectMessage("Either 'projectId' or 'from' must be provided");
- ComponentDto project = insertProject();
- call(project.uuid(), project.getDbKey(), ANOTHER_KEY);
+ call(project.uuid(), project.getKey(), ANOTHER_KEY);
}
@Test
public void fail_when_using_branch_db_key() throws Exception {
ComponentDto project = db.components().insertMainBranch();
ComponentDto branch = db.components().insertProjectBranch(project);
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
expectedException.expect(NotFoundException.class);
- expectedException.expectMessage(String.format("Component key '%s' not found", branch.getDbKey()));
+ expectedException.expectMessage("Component not found");
callByKey(branch.getDbKey(), ANOTHER_KEY);
}
public void fail_when_using_branch_uuid() {
ComponentDto project = db.components().insertMainBranch();
ComponentDto branch = db.components().insertProjectBranch(project);
+ userSessionRule.addProjectPermission(UserRole.ADMIN, project);
expectedException.expect(NotFoundException.class);
- expectedException.expectMessage(String.format("Component id '%s' not found", branch.uuid()));
+ expectedException.expectMessage("Component not found");
callByUuid(branch.uuid(), ANOTHER_KEY);
}
assertThat(definition.since()).isEqualTo("6.1");
assertThat(definition.isPost()).isTrue();
assertThat(definition.key()).isEqualTo("update_key");
+ assertThat(definition.changelog()).hasSize(2);
assertThat(definition.params())
.hasSize(3)
.extracting(Param::key)
.containsOnlyOnce("projectId", "from", "to");
}
- private void assertCallComponentService(@Nullable String newKey) {
- verify(componentService).updateKey(any(DbSession.class), any(ComponentDto.class), eq(newKey));
- }
-
private ComponentDto insertProject() {
- return componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()));
+ return db.components().insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert()));
}
- private String callByUuid(@Nullable String uuid, @Nullable String newKey) {
- return call(uuid, null, newKey);
+ private void callByUuid(@Nullable String uuid, @Nullable String newKey) {
+ call(uuid, null, newKey);
}
- private String callByKey(@Nullable String key, @Nullable String newKey) {
- return call(null, key, newKey);
+ private void callByKey(@Nullable String key, @Nullable String newKey) {
+ call(null, key, newKey);
}
private String call(@Nullable String uuid, @Nullable String key, @Nullable String newKey) {
return request.execute().getInput();
}
+
+ private Optional<ComponentDto> selectByKey(String key) {
+ return db.getDbClient().componentDao().selectByKey(db.getSession(), key);
+ }
}
@Suite.SuiteClasses({
BranchTest.class,
CodePageTest.class,
- ComponentsWsTest.class
+ ComponentsWsTest.class,
+ ModuleTest.class
})
public class ComponentSuite {
@ClassRule
public static final Orchestrator ORCHESTRATOR = ItUtils.newOrchestratorBuilder()
-
.addPlugin(xooPlugin())
-
.build();
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.tests.component;
+
+import com.sonar.orchestrator.Orchestrator;
+import com.sonar.orchestrator.build.BuildFailureException;
+import com.sonar.orchestrator.build.SonarScanner;
+import java.io.File;
+import org.junit.ClassRule;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonarqube.qa.util.Tester;
+import org.sonarqube.ws.Organizations;
+import org.sonarqube.ws.client.components.ShowRequest;
+import org.sonarqube.ws.client.components.TreeRequest;
+import org.sonarqube.ws.client.projects.UpdateKeyRequest;
+import util.XooProjectBuilder;
+
+import static java.util.Arrays.asList;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.fail;
+
+public class ModuleTest {
+
+ private static final String PROJECT_KEY = "sample";
+
+ @ClassRule
+ public static Orchestrator orchestrator = ComponentSuite.ORCHESTRATOR;
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+ @Rule
+ public Tester tester = new Tester(orchestrator);
+
+ /**
+ * SONAR-10536
+ */
+ @Test
+ public void analyze_disabled_module_as_a_new_project() throws Exception {
+ Organizations.Organization organization = tester.organizations().generate();
+ String projectKey = PROJECT_KEY;
+ String moduleKey = projectKey + ":module_a";
+
+ // analyze project "sample" with module "sample:module_a"
+ File projectWithModule = new XooProjectBuilder(projectKey)
+ .addModules("module_a")
+ .build(temp.newFolder());
+ analyze(organization, projectWithModule);
+ assertThat(tester.projects().exists(moduleKey)).isTrue();
+ assertThat(countFilesInProject(projectKey)).isEqualTo(2 /* 1 file in project and 1 file in module */);
+
+ // analyze project "sample" without module "sample:module_a". The latter
+ // is considered as disabled
+ File projectWithoutModule = new XooProjectBuilder(projectKey)
+ .build(temp.newFolder());
+ analyze(organization, projectWithoutModule);
+ assertThat(tester.projects().exists(moduleKey)).isFalse();
+ assertThat(countFilesInProject(projectKey)).isEqualTo(1 /* 1 file in project */);
+
+ // analyze module_a as a project
+ File moduleAsProject = new XooProjectBuilder(moduleKey)
+ .build(temp.newFolder());
+ try {
+ analyze(organization, moduleAsProject);
+ fail();
+ } catch (BuildFailureException e) {
+ assertThat(e.getResult().getLogs()).contains("The project '" + moduleKey + "' is already defined in SonarQube but as a module of project '" + projectKey + "'");
+ assertThat(tester.projects().exists(moduleKey)).isFalse();
+ }
+
+ // the only workaround is to rename the key of the disabled module
+ updateModuleKey(moduleKey, moduleKey + "_old");
+
+ // module_a can now be analyzed as a project
+ analyze(organization, moduleAsProject);
+ assertThat(tester.projects().exists(moduleKey)).isTrue();
+ assertThat(countFilesInProject(moduleKey)).isEqualTo(1);
+ assertThat(tester.wsClient().components().show(new ShowRequest().setComponent(moduleKey)).getComponent().getQualifier()).isEqualTo("TRK");
+ }
+
+ private void analyze(Organizations.Organization organization, File projectDir) {
+ orchestrator.executeBuild(SonarScanner.create(projectDir,
+ "sonar.organization", organization.getKey(),
+ "sonar.login", "admin", "sonar.password", "admin"));
+ }
+
+ private int countFilesInProject(String projectKey) {
+ TreeRequest request = new TreeRequest().setComponent(projectKey).setQualifiers(asList("FIL"));
+ return tester.wsClient().components().tree(request).getComponentsCount();
+ }
+
+ private void updateModuleKey(String fromKey, String toKey) {
+ tester.wsClient().projects().updateKey(new UpdateKeyRequest()
+ .setFrom(fromKey)
+ .setTo(toKey));
+ }
+}
import com.sonar.orchestrator.build.SonarScanner;
import java.io.File;
import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
-import java.util.Properties;
import java.util.stream.Collectors;
import javax.annotation.CheckForNull;
-import org.apache.commons.io.FileUtils;
-import org.apache.commons.lang.StringUtils;
import org.junit.After;
import org.junit.ClassRule;
import org.junit.Rule;
import org.sonarqube.ws.client.projects.BulkUpdateKeyRequest;
import org.sonarqube.ws.client.projects.UpdateKeyRequest;
import util.ItUtils;
+import util.XooProjectBuilder;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
.collect(Collectors.toList());
}
- private static class XooProjectBuilder {
- private final String key;
- private final List<String> moduleKeys = new ArrayList<>();
- private int filesPerModule = 1;
-
- XooProjectBuilder(String projectKey) {
- this.key = projectKey;
- }
-
- XooProjectBuilder addModules(String key, String... otherKeys) {
- this.moduleKeys.add(key);
- this.moduleKeys.addAll(asList(otherKeys));
- return this;
- }
-
- XooProjectBuilder setFilesPerModule(int i) {
- this.filesPerModule = i;
- return this;
- }
-
- File build(File dir) {
- for (String moduleKey : moduleKeys) {
- generateModule(moduleKey, new File(dir, moduleKey), new Properties());
- }
- Properties additionalProps = new Properties();
- additionalProps.setProperty("sonar.modules", StringUtils.join(moduleKeys, ","));
- generateModule(key, dir, additionalProps);
- return dir;
- }
-
- private void generateModule(String key, File dir, Properties additionalProps) {
- try {
- File sourceDir = new File(dir, "src");
- FileUtils.forceMkdir(sourceDir);
- for (int i = 0; i < filesPerModule; i++) {
- File sourceFile = new File(sourceDir, "File" + i + ".xoo");
- FileUtils.write(sourceFile, "content of " + sourceFile.getName());
- }
- Properties props = new Properties();
- props.setProperty("sonar.projectKey", key);
- props.setProperty("sonar.projectName", key);
- props.setProperty("sonar.projectVersion", "1.0");
- props.setProperty("sonar.sources", sourceDir.getName());
- props.putAll(additionalProps);
- File propsFile = new File(dir, "sonar-project.properties");
- try (OutputStream output = FileUtils.openOutputStream(propsFile)) {
- props.store(output, "generated");
- }
- } catch (IOException e) {
- throw new IllegalStateException(e);
- }
- }
- }
-
}
--- /dev/null
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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 util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+
+import static java.util.Arrays.asList;
+
+public class XooProjectBuilder {
+ private final String key;
+ private final List<String> moduleKeys = new ArrayList<>();
+ private int filesPerModule = 1;
+
+ public XooProjectBuilder(String projectKey) {
+ this.key = projectKey;
+ }
+
+ public XooProjectBuilder addModules(String key, String... otherKeys) {
+ this.moduleKeys.add(key);
+ this.moduleKeys.addAll(asList(otherKeys));
+ return this;
+ }
+
+ public XooProjectBuilder setFilesPerModule(int i) {
+ this.filesPerModule = i;
+ return this;
+ }
+
+ public File build(File dir) {
+ for (String moduleKey : moduleKeys) {
+ generateModule(moduleKey, new File(dir, moduleKey), new Properties());
+ }
+ Properties additionalProps = new Properties();
+ additionalProps.setProperty("sonar.modules", StringUtils.join(moduleKeys, ","));
+ generateModule(key, dir, additionalProps);
+ return dir;
+ }
+
+ private void generateModule(String key, File dir, Properties additionalProps) {
+ try {
+ File sourceDir = new File(dir, "src");
+ FileUtils.forceMkdir(sourceDir);
+ for (int i = 0; i < filesPerModule; i++) {
+ File sourceFile = new File(sourceDir, "File" + i + ".xoo");
+ FileUtils.write(sourceFile, "content of " + sourceFile.getName());
+ }
+ Properties props = new Properties();
+ props.setProperty("sonar.projectKey", key);
+ props.setProperty("sonar.projectName", key);
+ props.setProperty("sonar.projectVersion", "1.0");
+ props.setProperty("sonar.sources", sourceDir.getName());
+ props.putAll(additionalProps);
+ File propsFile = new File(dir, "sonar-project.properties");
+ try (OutputStream output = FileUtils.openOutputStream(propsFile)) {
+ props.store(output, "generated");
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ }
+}