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 {
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) {
}
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) {
@Override
protected void configure() {
addCoreSingleton(ProjectTree.class);
+ addCoreSingleton(ProjectFilter.class);
addCoreSingleton(ProjectConfigurator.class);
addCoreSingleton(DefaultResourceCreationLock.class);
addCoreSingleton(DefaultIndex.class);
--- /dev/null
+/*
+ * 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;
+ }
+}
*/
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;
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();
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());
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;
+ }
}
--- /dev/null
+/*
+ * 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"));
+ }
+}
--- /dev/null
+/*
+ * 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));
+
+ }
+}