From: David Gageot Date: Fri, 5 Oct 2012 12:10:46 +0000 (+0200) Subject: SONAR-1078 General exclusion patterns X-Git-Tag: 3.3~101 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=43e916612a3ce005ccbb4406368f883e0deb9184;p=sonarqube.git SONAR-1078 General exclusion patterns --- diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java index 4ac7f001232..b65f646aa3a 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java @@ -174,6 +174,18 @@ import java.util.List; project = false, global = true, category = CoreProperties.CATEGORY_GENERAL), + @Property( + key = CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY, + name = "Global source exclusions", + description = "Exclude sources from code analysis. Applies to every project. Cannot be overriden. Changes will be applied during next code analysis.", + multiValues = true, + category = CoreProperties.CATEGORY_EXCLUSIONS), + @Property( + key = CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY, + name = "Global test exclusions", + description = "Exclude tests from code analysis. Applies to every project. Cannot be overriden. Changes will be applied during next code analysis.", + multiValues = true, + category = CoreProperties.CATEGORY_EXCLUSIONS), @Property( key = CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, name = "Exclusions", @@ -182,6 +194,14 @@ import java.util.List; global = true, multiValues = true, category = CoreProperties.CATEGORY_EXCLUSIONS), + @Property( + key = CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, + name = "Test Exclusions", + description = "Exclude tests from code analysis. Changes will be applied during next code analysis.", + project = true, + global = true, + multiValues = true, + category = CoreProperties.CATEGORY_EXCLUSIONS), @Property( key = CoreProperties.CORE_COVERAGE_PLUGIN_PROPERTY, defaultValue = "jacoco", diff --git a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java index 7c3aefba96b..46516ff4d8a 100644 --- a/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java +++ b/plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java @@ -28,27 +28,24 @@ import org.sonar.api.resources.ResourceUtils; * @since 1.12 */ public class ExcludedResourceFilter implements ResourceFilter { - - private Project project; + private final Project project; public ExcludedResourceFilter(Project project) { this.project = project; } public boolean isIgnored(Resource resource) { - if (ResourceUtils.isUnitTestClass(resource)) { - // See SONAR-1115 Exclusion patterns do not apply to unit tests. + String[] patterns = ResourceUtils.isUnitTestClass(resource) ? project.getTestExclusionPatterns() : project.getExclusionPatterns(); + if (patterns == null) { return false; } - String[] patterns = project.getExclusionPatterns(); - if (patterns != null) { - for (String pattern : patterns) { - if (resource.matchFilePattern(pattern)) { - return true; - } + for (String pattern : patterns) { + if (resource.matchFilePattern(pattern)) { + return true; } } + return false; } -} \ No newline at end of file +} diff --git a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties index c9aa68491f4..914e0a2a8e5 100644 --- a/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties +++ b/plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties @@ -582,7 +582,13 @@ property.category.server_id=Server ID property.category.exclusions=Exclusions property.sonar.exclusions.name=Exclude sources from code analysis property.sonar.exclusions.description=Changes will be applied during next code analysis. -property.sonar.exclusions.help=

Wildcards

\ +property.sonar.test.exclusions.name=Exclude tests from code analysis +property.sonar.test.exclusions.description=Changes will be applied during next code analysis. +property.sonar.global.exclusions.name=Global source exclusions +property.sonar.global.exclusions.description=Exclude sources from code analysis. Applies to every project. Cannot be overriden at project level. Changes will be applied during next code analysis. +property.sonar.global.test.exclusions.name=Global test exclusions +property.sonar.global.test.exclusions.description=Exclude tests from code analysis. Applies to every project. Cannot be overriden at project level. Changes will be applied during next code analysis. +property.sonar.global.test.exclusions.help=

Wildcards

\

Following rules are applied:

\ \ \ diff --git a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java index 86269208bbf..1b9612ae750 100644 --- a/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java +++ b/plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java @@ -50,9 +50,6 @@ public class ExcludedResourceFilterTest { assertThat(filter.isIgnored(mock(Resource.class)), is(false)); } - /** - * See SONAR-1115 Exclusion patterns do not apply to unit tests. - */ @Test public void ignoreResourceIfMatchesPattern() { PropertiesConfiguration conf = new PropertiesConfiguration(); @@ -66,6 +63,23 @@ public class ExcludedResourceFilterTest { assertThat(filter.isIgnored(resource), is(true)); } + @Test + public void ignoreTestIfMatchesPattern() { + PropertiesConfiguration conf = new PropertiesConfiguration(); + conf.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, new String[]{"**/foo/*.java", "**/bar/*"}); + Project project = new Project("foo").setConfiguration(conf); + ExcludedResourceFilter filter = new ExcludedResourceFilter(project); + + Resource resource = mock(Resource.class); + when(resource.getQualifier()).thenReturn(Qualifiers.UNIT_TEST_FILE); + when(resource.matchFilePattern("**/bar/*")).thenReturn(true); + + assertThat(filter.isIgnored(resource), is(true)); + } + + /** + * See SONAR-1115 Source exclusion patterns do not apply to unit tests. + */ @Test public void doNotExcludeUnitTestFiles() { PropertiesConfiguration conf = new PropertiesConfiguration(); diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java index c72cd3781ab..8bceb171ba2 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java @@ -110,6 +110,13 @@ public interface CoreProperties { /* Exclusions */ String PROJECT_EXCLUSIONS_PROPERTY = "sonar.exclusions"; + /** + * @since 3.3 + */ + String PROJECT_TEST_EXCLUSIONS_PROPERTY = "sonar.test.exclusions"; + String GLOBAL_EXCLUSIONS_PROPERTY = "sonar.global.exclusions"; + String GLOBAL_TEST_EXCLUSIONS_PROPERTY = "sonar.global.test.exclusions"; + /** * @deprecated since 2.5. See discussion from http://jira.codehaus.org/browse/SONAR-1873 */ diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java index c7be30c73da..0f1bc0c064e 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java @@ -211,14 +211,14 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { return !testFiles(lang.getKey()).isEmpty(); } - List getFiles(List directories, List initialFiles, boolean applyExclusionPatterns, String... langs) { + List getFiles(List directories, List initialFiles, String[] patterns, String... langs) { List result = Lists.newArrayList(); if (directories == null) { return result; } IOFileFilter suffixFilter = getFileSuffixFilter(langs); - WildcardPattern[] exclusionPatterns = getExclusionPatterns(applyExclusionPatterns); + WildcardPattern[] exclusionPatterns = WildcardPattern.create(patterns); IOFileFilter initialFilesFilter = TrueFileFilter.INSTANCE; if (initialFiles != null && !initialFiles.isEmpty()) { @@ -401,14 +401,14 @@ public class DefaultProjectFileSystem implements ProjectFileSystem { * @since 2.6 */ public List mainFiles(String... langs) { - return getFiles(getSourceDirs(), getInitialSourceFiles(), true, langs); + return getFiles(getSourceDirs(), getInitialSourceFiles(), project.getExclusionPatterns(), langs); } /** * @since 2.6 */ public List testFiles(String... langs) { - return getFiles(getTestDirs(), getInitialTestFiles(), false /* FIXME should be true? */, langs); + return getFiles(getTestDirs(), getInitialTestFiles(), project.getTestExclusionPatterns(), langs); } protected List getInitialSourceFiles() { diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java index fc39d34827d..46871a2aca2 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java @@ -19,6 +19,8 @@ */ package org.sonar.api.resources; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; import org.apache.commons.configuration.Configuration; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.builder.ToStringBuilder; @@ -86,7 +88,7 @@ public class Project extends Resource { */ public boolean isDynamic(boolean includeReuseReportMode) { return equals(Project.AnalysisType.DYNAMIC) || - (equals(Project.AnalysisType.REUSE_REPORTS) && includeReuseReportMode); + (equals(Project.AnalysisType.REUSE_REPORTS) && includeReuseReportMode); } } @@ -304,8 +306,6 @@ public class Project extends Resource { return parent; } - - /** * For internal use only. */ @@ -358,14 +358,34 @@ public class Project extends Resource { /** * Patterns of resource exclusion as defined in project settings page. + * + * @since 3.3 also applies exclusions in general settings page and global exclusions. */ public String[] getExclusionPatterns() { - String[] exclusions = configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY); - for (int index=0 ; index builder() + .add(configuration.getStringArray(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY)) + .add(configuration.getStringArray(CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY)).build()); + } + + /** + * Patterns of test exclusion as defined in project settings page. + * Also applies exclusions in general settings page and global exclusions. + * + * @since 3.3 + */ + public String[] getTestExclusionPatterns() { + return trimExclusions(ImmutableList. builder() + .add(configuration.getStringArray(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY)) + .add(configuration.getStringArray(CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY)).build()); + } + + // http://jira.codehaus.org/browse/SONAR-2261 - exclusion must be trimmed + private static String[] trimExclusions(List exclusions) { + List trimmed = Lists.newArrayList(); + for (String exclusion : exclusions) { + trimmed.add(StringUtils.trim(exclusion)); } - return exclusions; + return trimmed.toArray(new String[trimmed.size()]); } /** diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java index 4d083fd21da..da456d5b0b4 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java @@ -236,7 +236,7 @@ public class DefaultProjectFileSystemTest { public void shouldExcludeDirectoriesStartingWithDot() { List dirs = Arrays.asList(new File("test-resources/org/sonar/api/resources/DefaultProjectFileSystemTest/shouldExcludeDirectoriesStartingWithDot/src")); - List files = new DefaultProjectFileSystem(new Project("foo"), null).getFiles(dirs, Collections.emptyList(), false); + List files = new DefaultProjectFileSystem(new Project("foo"), null).getFiles(dirs, Collections.emptyList(), new String[0]); assertThat(files.size(), is(1)); assertThat(files.get(0).getRelativePath(), is("org/sonar/Included.java")); } diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java index 6bc15f8f79c..ae2d5151be7 100644 --- a/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java +++ b/sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java @@ -19,36 +19,36 @@ */ package org.sonar.api.resources; -import org.apache.commons.configuration.Configuration; import org.apache.commons.configuration.PropertiesConfiguration; -import org.hamcrest.MatcherAssert; -import org.hamcrest.core.Is; import org.junit.Test; import org.sonar.api.CoreProperties; import org.sonar.api.test.MavenTestUtils; -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.fest.assertions.Assertions.assertThat; public class ProjectTest { + PropertiesConfiguration conf = new PropertiesConfiguration(); + @Test public void equalsProject() { Project project1 = MavenTestUtils.loadProjectFromPom(getClass(), "equalsProject/pom.xml"); Project project2 = MavenTestUtils.loadProjectFromPom(getClass(), "equalsProject/pom.xml"); - assertEquals(project1, project2); - assertFalse("foo:bar".equals(project1)); - assertEquals(project1.hashCode(), project2.hashCode()); + + assertThat(project1).isEqualTo(project2); + assertThat(project1).isNotEqualTo("foo:bar"); + assertThat(project1.hashCode()).isEqualTo(project2.hashCode()); } @Test public void effectiveKeyShouldEqualKey() { - assertThat(new Project("my:project").getEffectiveKey(), is("my:project")); + assertThat(new Project("my:project").getEffectiveKey()).isEqualTo("my:project"); } @Test public void createFromMavenIds() { Project project = Project.createFromMavenIds("my", "artifact"); - assertThat(project.getKey(), is("my:artifact")); + + assertThat(project.getKey()).isEqualTo("my:artifact"); } /** @@ -58,45 +58,48 @@ public class ProjectTest { */ @Test public void shouldTrimExclusionPatterns() { - Configuration conf = new PropertiesConfiguration(); conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, " **/*Foo.java , **/Bar.java "); - Project project = new Project("foo").setConfiguration(conf); + conf.setProperty(CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY, " **/*Test.java "); + Project project = new Project("foo").setConfiguration(conf); String[] exclusions = project.getExclusionPatterns(); - assertThat(exclusions.length, Is.is(2)); - assertThat(exclusions[0], Is.is("**/*Foo.java")); - assertThat(exclusions[1], Is.is("**/Bar.java")); + assertThat(exclusions).containsOnly("**/*Foo.java", "**/Bar.java", "**/*Test.java"); } @Test public void testNoExclusionPatterns() { - Project project = new Project("key").setConfiguration(new PropertiesConfiguration()); + Project project = new Project("key").setConfiguration(conf); - MatcherAssert.assertThat(project.getExclusionPatterns().length, Is.is(0)); + assertThat(project.getExclusionPatterns()).isEmpty(); } @Test - public void testManyExclusionPatterns() { - PropertiesConfiguration conf = new PropertiesConfiguration(); + public void should_exclude_many_patterns() { conf.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*,foo,*/bar"); + conf.setProperty(CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY, "*/exclude"); Project project = new Project("key").setConfiguration(conf); - MatcherAssert.assertThat(project.getExclusionPatterns().length, Is.is(3)); - MatcherAssert.assertThat(project.getExclusionPatterns()[0], Is.is("**/*")); - MatcherAssert.assertThat(project.getExclusionPatterns()[1], Is.is("foo")); - MatcherAssert.assertThat(project.getExclusionPatterns()[2], Is.is("*/bar")); + assertThat(project.getExclusionPatterns()).containsOnly("**/*", "foo", "*/bar", "*/exclude"); + } + + @Test + public void should_exclude_test_patterns() { + conf.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, "**/*Test.java, **/*IntegrationTest.java"); + conf.setProperty(CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY, "**/*FunctionalTest.java"); + + Project project = new Project("key").setConfiguration(conf); + + assertThat(project.getTestExclusionPatterns()).containsOnly("**/*Test.java", "**/*IntegrationTest.java", "**/*FunctionalTest.java"); } @Test public void testSetExclusionPatterns() { - PropertiesConfiguration conf = new PropertiesConfiguration(); Project project = new Project("key").setConfiguration(conf); - project.setExclusionPatterns(new String[]{"**/*Foo.java", "**/*Bar.java"}); - MatcherAssert.assertThat(project.getExclusionPatterns().length, Is.is(2)); - MatcherAssert.assertThat(project.getExclusionPatterns()[0], Is.is("**/*Foo.java")); - MatcherAssert.assertThat(project.getExclusionPatterns()[1], Is.is("**/*Bar.java")); + project.setExclusionPatterns(new String[] {"**/*Foo.java", "**/*Bar.java"}); + + assertThat(project.getExclusionPatterns()).containsOnly("**/*Foo.java", "**/*Bar.java"); } }