]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-1078 General exclusion patterns
authorDavid Gageot <david@gageot.net>
Fri, 5 Oct 2012 12:10:46 +0000 (14:10 +0200)
committerDavid Gageot <david@gageot.net>
Fri, 5 Oct 2012 13:52:44 +0000 (15:52 +0200)
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/CorePlugin.java
plugins/sonar-core-plugin/src/main/java/org/sonar/plugins/core/batch/ExcludedResourceFilter.java
plugins/sonar-core-plugin/src/main/resources/org/sonar/l10n/core.properties
plugins/sonar-core-plugin/src/test/java/org/sonar/plugins/core/batch/ExcludedResourceFilterTest.java
sonar-plugin-api/src/main/java/org/sonar/api/CoreProperties.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/Project.java
sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java
sonar-plugin-api/src/test/java/org/sonar/api/resources/ProjectTest.java

index 4ac7f0012329774001b1848f431181690fed0613..b65f646aa3a6a28ab5265becc5f01190f101a7f3 100644 (file)
@@ -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",
index 7c3aefba96be2a31ab5bc817fadadc1429e072fc..46516ff4d8a58ac4d4dc2cd2b383644826520d26 100644 (file)
@@ -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
+}
index c9aa68491f4ecf837d920ff25dcf90dd8eff55c0..914e0a2a8e5af7cb996223669bc9534964d9f558 100644 (file)
@@ -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=<h2>Wildcards</h2>\
+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=<h2>Wildcards</h2>\
  <p>Following rules are applied:</p>\
  <table class="data">\
    <thead><tr><th colspan="2"></th></tr></thead>\
index 86269208bbf15e1e6a6848268e642165d3407595..1b9612ae750c18fa15c4724307f51f7a1a93a075 100644 (file)
@@ -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();
index c72cd3781ab3eff010bcf907f6dfaa7a6de4042f..8bceb171ba2c032621299b1825d326bcd75ffeee 100644 (file)
@@ -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
    */
index c7be30c73da70b68dd0fee53906e86bfd1daf088..0f1bc0c064ef60d8152caaf0673111ef2e6764af 100644 (file)
@@ -211,14 +211,14 @@ public class DefaultProjectFileSystem implements ProjectFileSystem {
     return !testFiles(lang.getKey()).isEmpty();
   }
 
-  List<InputFile> getFiles(List<File> directories, List<File> initialFiles, boolean applyExclusionPatterns, String... langs) {
+  List<InputFile> getFiles(List<File> directories, List<File> initialFiles, String[] patterns, String... langs) {
     List<InputFile> 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<InputFile> mainFiles(String... langs) {
-    return getFiles(getSourceDirs(), getInitialSourceFiles(), true, langs);
+    return getFiles(getSourceDirs(), getInitialSourceFiles(), project.getExclusionPatterns(), langs);
   }
 
   /**
    * @since 2.6
    */
   public List<InputFile> testFiles(String... langs) {
-    return getFiles(getTestDirs(), getInitialTestFiles(), false /* FIXME should be true? */, langs);
+    return getFiles(getTestDirs(), getInitialTestFiles(), project.getTestExclusionPatterns(), langs);
   }
 
   protected List<File> getInitialSourceFiles() {
index fc39d34827d364399025f252ac8752c9675bf08c..46871a2aca2311a74e652476816ebf76e86396be 100644 (file)
@@ -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<exclusions.length ; index++) {
-      // http://jira.codehaus.org/browse/SONAR-2261 - exclusion must be trimmed
-      exclusions[index]=StringUtils.trim(exclusions[index]);
+    return trimExclusions(ImmutableList.<String> 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.<String> 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<String> exclusions) {
+    List<String> trimmed = Lists.newArrayList();
+    for (String exclusion : exclusions) {
+      trimmed.add(StringUtils.trim(exclusion));
     }
-    return exclusions;
+    return trimmed.toArray(new String[trimmed.size()]);
   }
 
   /**
index 4d083fd21da0e8e3df31e6bd2163a8d681a8a194..da456d5b0b4abd41d52e8e148ffc9c1aa416ce7e 100644 (file)
@@ -236,7 +236,7 @@ public class DefaultProjectFileSystemTest {
   public void shouldExcludeDirectoriesStartingWithDot() {
     List<File> dirs = Arrays.asList(new File("test-resources/org/sonar/api/resources/DefaultProjectFileSystemTest/shouldExcludeDirectoriesStartingWithDot/src"));
 
-    List<InputFile> files = new DefaultProjectFileSystem(new Project("foo"), null).getFiles(dirs, Collections.<File>emptyList(), false);
+    List<InputFile> files = new DefaultProjectFileSystem(new Project("foo"), null).getFiles(dirs, Collections.<File>emptyList(), new String[0]);
     assertThat(files.size(), is(1));
     assertThat(files.get(0).getRelativePath(), is("org/sonar/Included.java"));
   }
index 6bc15f8f79c6fcb54c32a4dbfff42a0289521566..ae2d5151be76a3430e22d740c69db0f68243138b 100644 (file)
  */
 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");
   }
 }