diff options
author | simonbrandhof <simon.brandhof@gmail.com> | 2011-11-04 10:16:50 +0100 |
---|---|---|
committer | simonbrandhof <simon.brandhof@gmail.com> | 2011-11-04 10:17:18 +0100 |
commit | 88554cc3c9747e266247f7d27ab3c22c93c6fa0d (patch) | |
tree | 7cd18655d9787b222825b022682201933ff6faed | |
parent | 8c4d787e20a63ece8620eac0a7686cb16dc536a7 (diff) | |
download | sonarqube-88554cc3c9747e266247f7d27ab3c22c93c6fa0d.tar.gz sonarqube-88554cc3c9747e266247f7d27ab3c22c93c6fa0d.zip |
SONAR-2967 extract the new component ProjectFilter from ProjectTree
6 files changed, 245 insertions, 71 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java index 06ec2bd23fd..34916a1e38a 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java +++ b/sonar-batch/src/main/java/org/sonar/batch/ProjectTree.java @@ -21,18 +21,18 @@ package org.sonar.batch; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import com.google.common.collect.Sets; import org.apache.commons.lang.ObjectUtils; -import org.apache.commons.lang.StringUtils; import org.slf4j.LoggerFactory; import org.sonar.api.batch.bootstrap.ProjectBuilder; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.bootstrap.ProjectReactor; -import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; +import org.sonar.batch.bootstrap.ProjectFilter; import java.io.IOException; -import java.util.*; +import java.util.Iterator; +import java.util.List; +import java.util.Map; public class ProjectTree { @@ -41,21 +41,21 @@ public class ProjectTree { private List<Project> projects; private Map<ProjectDefinition, Project> projectsByDef; - private Settings settings; + private ProjectFilter projectFilter; public ProjectTree(ProjectReactor projectReactor, //NOSONAR the unused parameter 'builders' is used for the startup order of components ProjectConfigurator projectConfigurator, - Settings settings, + ProjectFilter projectFilter, /* Must be executed after ProjectBuilders */ ProjectBuilder[] builders) { - this(projectReactor, projectConfigurator, settings); + this(projectReactor, projectConfigurator, projectFilter); } public ProjectTree(ProjectReactor projectReactor, //NOSONAR the unused parameter 'builders' is used for the startup order of components ProjectConfigurator projectConfigurator, - Settings settings) { + ProjectFilter projectFilter) { this.projectReactor = projectReactor; this.configurator = projectConfigurator; - this.settings = settings; + this.projectFilter = projectFilter; } ProjectTree(ProjectConfigurator configurator) { @@ -93,78 +93,21 @@ public class ProjectTree { } void applyExclusions() { - for (Project project : projects) { - String[] excludedArtifactIds = settings.getStringArray("sonar.skippedModules"); - String[] includedArtifactIds = settings.getStringArray("sonar.includedModules"); - - Set<String> includedModulesIdSet = Sets.newHashSet(); - Set<String> excludedModulesIdSet = Sets.newHashSet(); - - if (includedArtifactIds != null) { - includedModulesIdSet.addAll(Arrays.asList(includedArtifactIds)); - } - - if (excludedArtifactIds != null) { - excludedModulesIdSet.addAll(Arrays.asList(excludedArtifactIds)); - includedModulesIdSet.removeAll(excludedModulesIdSet); - } - - if (!includedModulesIdSet.isEmpty()) { - for (Project currentProject : projects) { - if (!includedModulesIdSet.contains(getArtifactId(currentProject))) { - exclude(currentProject); - } - } - } else { - for (String excludedArtifactId : excludedModulesIdSet) { - Project excludedProject = getProjectByArtifactId(excludedArtifactId); - exclude(excludedProject); - } - } - } - for (Iterator<Project> it = projects.iterator(); it.hasNext(); ) { Project project = it.next(); - if (project.isExcluded()) { - LoggerFactory.getLogger(getClass()).info("Module {} is excluded from analysis", project.getName()); + if (projectFilter.isExcluded(project)) { + project.setExcluded(true); + LoggerFactory.getLogger(getClass()).info("Project {} excluded", project.getName()); project.removeFromParent(); it.remove(); } } } - private void exclude(Project project) { - if (project != null) { - project.setExcluded(true); - for (Project module : project.getModules()) { - exclude(module); - } - } - } - public List<Project> getProjects() { return projects; } - private String getArtifactId(Project project) { - String key = project.getKey(); - if (StringUtils.isNotBlank(project.getBranch())) { - // remove branch part - key = StringUtils.removeEnd(project.getKey(), ":" + project.getBranch()); - } - return StringUtils.substringAfterLast(key, ":"); - } - - public Project getProjectByArtifactId(String artifactId) { - for (Project project : projects) { - // TODO see http://jira.codehaus.org/browse/SONAR-2324 - if (StringUtils.equals(getArtifactId(project), artifactId)) { - return project; - } - } - return null; - } - public Project getRootProject() { for (Project project : projects) { if (project.getParent() == null) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java index 822d6ca7a8d..0dbe5c95b97 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/BatchModule.java @@ -49,6 +49,7 @@ public class BatchModule extends Module { @Override protected void configure() { addCoreSingleton(ProjectTree.class); + addCoreSingleton(ProjectFilter.class); addCoreSingleton(ProjectConfigurator.class); addCoreSingleton(DefaultResourceCreationLock.class); addCoreSingleton(DefaultIndex.class); diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectFilter.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectFilter.java new file mode 100644 index 00000000000..5ecf6606dc0 --- /dev/null +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/ProjectFilter.java @@ -0,0 +1,73 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.bootstrap; + +import org.apache.commons.lang.ArrayUtils; +import org.apache.commons.lang.StringUtils; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Project; + +/** + * Filter projects to analyze by using the properties sonar.skippedModules and sonar.includedModules + * + * @since 2.12 + */ +public class ProjectFilter { + + private Settings settings; + + public ProjectFilter(Settings settings) { + this.settings = settings; + } + + public boolean isExcluded(Project project) { + Project p = project; + while (p != null) { + if (isExcluded(getArtifactId(p))) { + return true; + } + p = p.getParent(); + } + return false; + } + + private boolean isExcluded(String artifactId) { + String[] includedArtifactIds = settings.getStringArray("sonar.includedModules"); + + if (includedArtifactIds.length > 0) { + return !ArrayUtils.contains(includedArtifactIds, artifactId); + } + String[] excludedArtifactIds = settings.getStringArray("sonar.skippedModules"); + return ArrayUtils.contains(excludedArtifactIds, artifactId); + } + + // TODO see http://jira.codehaus.org/browse/SONAR-2324 + static String getArtifactId(Project project) { + String key = project.getKey(); + if (StringUtils.isNotBlank(project.getBranch())) { + // remove branch part + key = StringUtils.removeEnd(project.getKey(), ":" + project.getBranch()); + } + if (key.contains(":")) { + return StringUtils.substringAfter(key, ":"); + } + return key; + } +} diff --git a/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java b/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java index b8fc2a60b84..7a7fb5a1886 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java +++ b/sonar-batch/src/main/java/org/sonar/batch/config/ProjectSettings.java @@ -19,6 +19,7 @@ */ package org.sonar.batch.config; +import com.google.common.collect.Lists; import org.apache.commons.configuration.Configuration; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.PropertyDefinitions; @@ -49,11 +50,11 @@ public class ProjectSettings extends Settings { public ProjectSettings load() { clear(); - + // order is important -> bottom-up. The last one overrides all the others. loadDatabaseGlobalSettings(); loadDatabaseProjectSettings(projectDefinition); - addProperties(projectDefinition.getProperties()); + loadBuildProperties(); addEnvironmentVariables(); addSystemProperties(); @@ -62,6 +63,13 @@ public class ProjectSettings extends Settings { return this; } + private void loadBuildProperties() { + List<ProjectDefinition> orderedProjects = getOrderedProjects(projectDefinition); + for (ProjectDefinition p : orderedProjects) { + addProperties(p.getProperties()); + } + } + private void loadDatabaseProjectSettings(ProjectDefinition projectDef) { if (projectDef.getParent() != null) { loadDatabaseProjectSettings(projectDef.getParent()); @@ -83,4 +91,16 @@ public class ProjectSettings extends Settings { ConfigurationUtils.copyToCommonsConfiguration(properties, deprecatedCommonsConf); } + /** + * From root to module + */ + static List<ProjectDefinition> getOrderedProjects(ProjectDefinition project) { + List<ProjectDefinition> result = Lists.newArrayList(); + ProjectDefinition pd = project; + while (pd != null) { + result.add(0, pd); + pd = pd.getParent(); + } + return result; + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectFilterTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectFilterTest.java new file mode 100644 index 00000000000..d01f5150bf9 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/ProjectFilterTest.java @@ -0,0 +1,91 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.bootstrap; + +import org.junit.Test; +import org.sonar.api.config.Settings; +import org.sonar.api.resources.Project; +import org.sonar.batch.config.ProjectSettings; + +import static org.hamcrest.core.Is.is; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +public class ProjectFilterTest { + + @Test + public void testSkippedModule() { + Settings settings = new Settings(); + settings.setProperty("sonar.skippedModules", "foo,bar"); + + ProjectFilter filter = new ProjectFilter(settings); + assertTrue(filter.isExcluded(new Project("my:foo"))); + } + + @Test + public void testNotExcluded() { + Settings settings = new Settings(); + settings.setProperty("sonar.skippedModules", "foo,bar"); + + ProjectFilter filter = new ProjectFilter(settings); + assertFalse(filter.isExcluded(new Project("my:other"))); + } + + @Test + public void testNoSkippedModules() { + Settings settings = new Settings(); + + ProjectFilter filter = new ProjectFilter(settings); + assertFalse(filter.isExcluded(new Project("my:other"))); + } + + @Test + public void testIncludedModules() { + Settings settings = new Settings(); + settings.setProperty("sonar.includedModules", "foo"); + + ProjectFilter filter = new ProjectFilter(settings); + assertFalse(filter.isExcluded(new Project("my:foo"))); + + filter = new ProjectFilter(settings); + assertTrue(filter.isExcluded(new Project("my:bar"))); + } + + @Test + public void shouldBeExcludedIfParentIsExcluded() { + Settings settings = new Settings(); + settings.setProperty("sonar.skippedModules", "parent"); + + Project parent = new Project("my:parent"); + Project child = new Project("my:child"); + child.setParent(parent); + + ProjectFilter filter = new ProjectFilter(settings); + assertTrue(filter.isExcluded(child)); + } + + @Test + public void testGetArtifactId() { + assertThat(ProjectFilter.getArtifactId(new Project("org:foo")), is("foo")); + assertThat(ProjectFilter.getArtifactId(new Project("foo")), is("foo")); + assertThat(ProjectFilter.getArtifactId(new Project("org:foo:1.x").setBranch("1.x")), is("foo")); + } +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/config/ProjectSettingsTest.java b/sonar-batch/src/test/java/org/sonar/batch/config/ProjectSettingsTest.java new file mode 100644 index 00000000000..0cd4f31c023 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/config/ProjectSettingsTest.java @@ -0,0 +1,46 @@ +/* + * Sonar, open source software quality management tool. + * Copyright (C) 2008-2011 SonarSource + * mailto:contact AT sonarsource DOT com + * + * Sonar 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. + * + * Sonar 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 Sonar; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 + */ +package org.sonar.batch.config; + +import org.hamcrest.core.Is; +import org.junit.Test; +import org.sonar.api.batch.bootstrap.ProjectDefinition; + +import java.util.List; + +import static org.junit.Assert.assertThat; + +public class ProjectSettingsTest { + + @Test + public void testOrderedProjects() { + ProjectDefinition grandParent = ProjectDefinition.create(); + ProjectDefinition parent = ProjectDefinition.create(); + ProjectDefinition child = ProjectDefinition.create(); + grandParent.addSubProject(parent); + parent.addSubProject(child); + + List<ProjectDefinition> hierarchy = ProjectSettings.getOrderedProjects(child); + assertThat(hierarchy.get(0), Is.is(grandParent)); + assertThat(hierarchy.get(1), Is.is(parent)); + assertThat(hierarchy.get(2), Is.is(child)); + + } +} |