]> source.dussan.org Git - sonarqube.git/commitdiff
Allow to manually define source files to analyze
authorSimon Brandhof <simon.brandhof@gmail.com>
Fri, 3 Jun 2011 12:51:14 +0000 (14:51 +0200)
committerSimon Brandhof <simon.brandhof@gmail.com>
Fri, 3 Jun 2011 12:51:14 +0000 (14:51 +0200)
sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java
sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java
sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectDefinitionTest.java
sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java

index baa4e2394ec912e43e69e0be953a0c1fce5e602c..632ee139c8ca52836797458e6ea4ec41ad3b7512 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.batch;
 
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
 import org.apache.commons.io.FileUtils;
 import org.apache.maven.project.MavenProject;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
@@ -31,6 +32,7 @@ import org.sonar.api.utils.SonarException;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -84,6 +86,7 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
     }
   }
 
+  @Override
   public List<File> getSourceDirs() {
     List<File> unfiltered;
     if (pom != null) {
@@ -106,7 +109,7 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
     if (pom != null) {
       pom.getCompileSourceRoots().add(0, dir.getAbsolutePath());
     } else {
-      def.addSourceDir(dir.getAbsolutePath());
+      def.addSourceDirs(dir.getAbsolutePath());
     }
     return this;
   }
@@ -114,6 +117,7 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
   /**
    * Maven can modify test directories during Sonar execution - see MavenPhaseExecutor.
    */
+  @Override
   public List<File> getTestDirs() {
     List<File> unfiltered;
     if (pom != null) {
@@ -136,7 +140,7 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
     if (pom != null) {
       pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath());
     } else {
-      def.addTestDir(dir.getAbsolutePath());
+      def.addTestDirs(dir.getAbsolutePath());
     }
     return this;
   }
@@ -168,4 +172,13 @@ public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem {
     return dir;
   }
 
+  @Override
+  protected List<File> getInitialSourceFiles() {
+    return resolvePaths(def.getSourceFiles());
+  }
+
+  @Override
+  protected List<File> getInitialTestFiles() {
+    return resolvePaths(def.getTestFiles());
+  }
 }
index e24d078f1721585bd5c9e56d574b374ac507ed36..f3fbe726c9fd00f68e12ab21df12131d57f7118e 100644 (file)
@@ -62,7 +62,7 @@ public class ProjectDefinition {
   }
 
   public void addSourceDir(String path) {
-    target.addSourceDir(path);
+    target.addSourceDirs(path);
   }
 
   public List<String> getTestDirs() {
@@ -74,7 +74,7 @@ public class ProjectDefinition {
    *          It can be absolute or relative to project directory.
    */
   public void addTestDir(String path) {
-    target.addTestDir(path);
+    target.addTestDirs(path);
   }
 
   public List<String> getBinaries() {
index 37764621c10a741e09de1fd6be1a771a8f8a5be8..2282be26078530cb3d6e31b4be1d0ce141e1577f 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.api.batch.bootstrap;
 
 import com.google.common.collect.Lists;
+import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.CoreProperties;
@@ -32,13 +33,15 @@ import java.util.Properties;
 /**
  * Defines project metadata (key, name, source directories, ...). It's generally used by the
  * {@link org.sonar.api.batch.bootstrap.ProjectBuilder extension point}
- * 
+ *
  * @since 2.9
  */
 public final class ProjectDefinition implements BatchComponent {
 
-  public static final String SOURCES_PROPERTY = "sonar.sources";
-  public static final String TESTS_PROPERTY = "sonar.tests";
+  public static final String SOURCE_DIRS_PROPERTY = "sonar.sources";
+  public static final String SOURCE_FILES_PROPERTY = "sonar.sourceFiles";
+  public static final String TEST_DIRS_PROPERTY = "sonar.tests";
+  public static final String TEST_FILES_PROPERTY = "sonar.testFiles";
   public static final String BINARIES_PROPERTY = "sonar.binaries";
   public static final String LIBRARIES_PROPERTY = "sonar.libraries";
 
@@ -132,26 +135,30 @@ public final class ProjectDefinition implements BatchComponent {
   }
 
   public List<String> getSourceDirs() {
-    String sources = properties.getProperty(SOURCES_PROPERTY, "");
+    String sources = properties.getProperty(SOURCE_DIRS_PROPERTY, "");
     return Arrays.asList(StringUtils.split(sources, SEPARATOR));
   }
 
   /**
-   * @param path path to directory with main sources.
-   *          It can be absolute or relative to project directory.
+   * @param paths paths to directory with main sources.
+   *              They can be absolute or relative to project base directory.
    */
-  public ProjectDefinition addSourceDir(String path) {
-    appendProperty(SOURCES_PROPERTY, path);
+  public ProjectDefinition addSourceDirs(String... paths) {
+    for (String path : paths) {
+      appendProperty(SOURCE_DIRS_PROPERTY, FilenameUtils.normalize(path));
+    }
     return this;
   }
 
-  public ProjectDefinition addSourceDir(File path) {
-    addSourceDir(path.getAbsolutePath());
+  public ProjectDefinition addSourceDirs(File... dirs) {
+    for (File dir : dirs) {
+      addSourceDirs(dir);
+    }
     return this;
   }
 
   public ProjectDefinition setSourceDir(String path) {
-    properties.setProperty(SOURCES_PROPERTY, path);
+    properties.setProperty(SOURCE_DIRS_PROPERTY, FilenameUtils.normalize(path));
     return this;
   }
 
@@ -160,20 +167,84 @@ public final class ProjectDefinition implements BatchComponent {
     return this;
   }
 
+  /**
+   * Adding source files is possible only if no source directories have been set.
+   * Absolute path or relative path from project base dir. 
+   */
+  public ProjectDefinition addSourceFiles(String... paths) {
+    for (String path : paths) {
+      appendProperty(SOURCE_FILES_PROPERTY, FilenameUtils.normalize(path));
+    }
+    return this;
+  }
+
+  /**
+   * Adding source files is possible only if no source directories have been set.
+   */
+  public ProjectDefinition addSourceFiles(File... files) {
+    for (File file : files) {
+      addSourceFiles(file.getAbsolutePath());
+    }
+    return this;
+  }
+
+  public List<String> getSourceFiles() {
+    String sources = properties.getProperty(SOURCE_FILES_PROPERTY, "");
+    return Arrays.asList(StringUtils.split(sources, SEPARATOR));
+  }
+
+
   public List<String> getTestDirs() {
-    String sources = properties.getProperty(TESTS_PROPERTY, "");
+    String sources = properties.getProperty(TEST_DIRS_PROPERTY, "");
     return Arrays.asList(StringUtils.split(sources, SEPARATOR));
   }
 
   /**
-   * @param path path to directory with test sources.
-   *          It can be absolute or relative to project directory.
+   * @param paths path to directory with test sources.
+   *              It can be absolute or relative to project directory.
    */
-  public ProjectDefinition addTestDir(String path) {
-    appendProperty(TESTS_PROPERTY, path);
+  public ProjectDefinition addTestDirs(String... paths) {
+    for (String path : paths) {
+      appendProperty(TEST_DIRS_PROPERTY, FilenameUtils.normalize(path));
+    }
     return this;
   }
 
+  public ProjectDefinition addTestDirs(File... dirs) {
+    for (File dir : dirs) {
+      addTestDirs(dir.getAbsolutePath());
+    }
+    return this;
+  }
+
+
+  /**
+   * Adding source files is possible only if no source directories have been set.
+   * Absolute path or relative path from project base dir.
+   */
+  public ProjectDefinition addTestFiles(String... paths) {
+    for (String path : paths) {
+      appendProperty(TEST_FILES_PROPERTY, FilenameUtils.normalize(path));
+    }
+    return this;
+  }
+
+  /**
+   * Adding source files is possible only if no source directories have been set.
+   */
+  public ProjectDefinition addTestFiles(File... files) {
+    for (File file : files) {
+      addTestFiles(file.getAbsolutePath());
+    }
+    return this;
+  }
+
+  public List<String> getTestFiles() {
+    String sources = properties.getProperty(TEST_FILES_PROPERTY, "");
+    return Arrays.asList(StringUtils.split(sources, SEPARATOR));
+  }
+
+
   public List<String> getBinaries() {
     String sources = properties.getProperty(BINARIES_PROPERTY, "");
     return Arrays.asList(StringUtils.split(sources, SEPARATOR));
@@ -181,11 +252,11 @@ public final class ProjectDefinition implements BatchComponent {
 
   /**
    * @param path path to directory with compiled source. In case of Java this is directory with class files.
-   *          It can be absolute or relative to project directory.
+   *             It can be absolute or relative to project directory.
    * @TODO currently Sonar supports only one such directory due to dependency on MavenProject
    */
   public ProjectDefinition addBinaryDir(String path) {
-    appendProperty(BINARIES_PROPERTY, path);
+    appendProperty(BINARIES_PROPERTY, FilenameUtils.normalize(path));
     return this;
   }
 
@@ -196,10 +267,10 @@ public final class ProjectDefinition implements BatchComponent {
 
   /**
    * @param path path to file with third-party library. In case of Java this is path to jar file.
-   *          It can be absolute or relative to project directory.
+   *             It can be absolute or relative to project directory.
    */
   public void addLibrary(String path) {
-    appendProperty(LIBRARIES_PROPERTY, path);
+    appendProperty(LIBRARIES_PROPERTY, FilenameUtils.normalize(path));
   }
 
   /**
index dd046681513cc9455422543abd6234f0bace9330..aa5e7a68ee5fe250aeb678f306f44301c7b61174 100644 (file)
@@ -20,9 +20,7 @@
 package org.sonar.api.resources;
 
 import com.google.common.base.Predicate;
-import com.google.common.collect.ImmutableList;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Lists;
+import com.google.common.collect.*;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.FilenameUtils;
 import org.apache.commons.io.filefilter.*;
@@ -37,9 +35,7 @@ import org.sonar.api.utils.WildcardPattern;
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.util.*;
 
 /**
  * An implementation of {@link ProjectFileSystem}.
@@ -196,7 +192,7 @@ public class DefaultProjectFileSystem implements ProjectFileSystem {
     return !testFiles(lang.getKey()).isEmpty();
   }
 
-  private List<InputFile> getFiles(List<File> directories, boolean applyExclusionPatterns, String... langs) {
+  private List<InputFile> getFiles(List<File> directories, List<File> initialFiles, boolean applyExclusionPatterns, String... langs) {
     List<InputFile> result = Lists.newArrayList();
     if (directories == null) {
       return result;
@@ -205,13 +201,19 @@ public class DefaultProjectFileSystem implements ProjectFileSystem {
     IOFileFilter suffixFilter = getFileSuffixFilter(langs);
     WildcardPattern[] exclusionPatterns = getExclusionPatterns(applyExclusionPatterns);
 
+    IOFileFilter initialFilesFilter = TrueFileFilter.INSTANCE;
+    if (initialFiles!=null && !initialFiles.isEmpty()) {
+      initialFilesFilter = new FileSelectionFilter(initialFiles);
+    }
+
     for (File dir : directories) {
       if (dir.exists()) {
         IOFileFilter exclusionFilter = new ExclusionFilter(dir, exclusionPatterns);
         IOFileFilter visibleFileFilter = HiddenFileFilter.VISIBLE;
-        List<IOFileFilter> dirFilters = Lists.newArrayList(visibleFileFilter, suffixFilter, exclusionFilter);
-        dirFilters.addAll(this.filters);
-        List<File> files = (List<File>) FileUtils.listFiles(dir, new AndFileFilter(dirFilters), HiddenFileFilter.VISIBLE);
+        List<IOFileFilter> fileFilters = Lists.newArrayList(visibleFileFilter, suffixFilter, exclusionFilter, initialFilesFilter);
+        fileFilters.addAll(this.filters);
+        
+        List<File> files = (List<File>) FileUtils.listFiles(dir, new AndFileFilter(fileFilters), HiddenFileFilter.VISIBLE);
         for (File file : files) {
           String relativePath = DefaultProjectFileSystem.getRelativePath(file, dir);
           result.add(InputFileUtils.create(dir, relativePath));
@@ -269,6 +271,22 @@ public class DefaultProjectFileSystem implements ProjectFileSystem {
     }
   }
 
+  static class FileSelectionFilter implements IOFileFilter {
+    private Set<File> files;
+
+    public FileSelectionFilter(List<File> f) {
+      files = Sets.newHashSet(f);
+    }
+
+    public boolean accept(File file) {
+      return files.contains(file);
+    }
+
+    public boolean accept(File file, String name) {
+      return accept(file);
+    }
+  }
+
   public File writeToWorkingDirectory(String content, String fileName) throws IOException {
     return writeToFile(content, getSonarWorkingDirectory(), fileName);
   }
@@ -363,13 +381,21 @@ public class DefaultProjectFileSystem implements ProjectFileSystem {
    * @since 2.6
    */
   public List<InputFile> mainFiles(String... langs) {
-    return getFiles(getSourceDirs(), true, langs);
+    return getFiles(getSourceDirs(), getInitialSourceFiles(), true, langs);
   }
 
   /**
    * @since 2.6
    */
   public List<InputFile> testFiles(String... langs) {
-    return getFiles(getTestDirs(), false /* FIXME should be true? */, langs);
+    return getFiles(getTestDirs(), getInitialTestFiles(), false /* FIXME should be true? */, langs);
+  }
+
+  protected List<File> getInitialSourceFiles() {
+    return Collections.emptyList();
+  }
+
+  protected List<File> getInitialTestFiles() {
+    return Collections.emptyList();
   }
 }
index 49f1e1c916aabfe55293e5c50097303ab21fee5a..9b92b37e8806a756e864762c25f0e5938a45c503 100644 (file)
@@ -74,19 +74,29 @@ public class ProjectDefinitionTest {
   @Test
   public void shouldAddDirectories() {
     ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties());
-    def.addSourceDir("src/main/java");
-    def.addSourceDir("src/main/java2");
-    def.addTestDir("src/test/java");
-    def.addTestDir("src/test/java2");
+    def.addSourceDirs("src/main/java", "src/main/java2");
+    def.addTestDirs("src/test/java");
+    def.addTestDirs("src/test/java2");
     def.addBinaryDir("target/classes");
     def.addBinaryDir("target/classes2");
     def.addLibrary("junit.jar");
     def.addLibrary("mockito.jar");
 
-    assertDirs(def.getSourceDirs(), "src/main/java", "src/main/java2");
-    assertDirs(def.getTestDirs(), "src/test/java", "src/test/java2");
-    assertDirs(def.getBinaries(), "target/classes", "target/classes2");
-    assertDirs(def.getLibraries(), "junit.jar", "mockito.jar");
+    assertFiles(def.getSourceDirs(), "src/main/java", "src/main/java2");
+    assertFiles(def.getTestDirs(), "src/test/java", "src/test/java2");
+    assertFiles(def.getBinaries(), "target/classes", "target/classes2");
+    assertFiles(def.getLibraries(), "junit.jar", "mockito.jar");
+  }
+
+  @Test
+  public void shouldAddFiles() {
+    ProjectDefinition def = new ProjectDefinition(new File("."), new File("."), new Properties());
+    def.addSourceFiles("src/main/java/foo/Bar.java", "src/main/java/hello/World.java");
+    def.addTestFiles("src/test/java/foo/BarTest.java", "src/test/java/hello/WorldTest.java");
+
+    assertFiles(def.getSourceFiles(), "src/main/java/foo/Bar.java", "src/main/java/hello/World.java");
+    assertFiles(def.getTestFiles(), "src/test/java/foo/BarTest.java", "src/test/java/hello/WorldTest.java");
+
   }
 
   @Test
@@ -102,10 +112,10 @@ public class ProjectDefinitionTest {
     assertThat(child.getParent(), is(root));
   }
 
-  private static void assertDirs(List<String> dirs, String... values) {
-    assertThat(dirs.size(), is(values.length));
+  private static void assertFiles(List<String> paths, String... values) {
+    assertThat(paths.size(), is(values.length));
     for (int i = 0; i < values.length; i++) {
-      assertThat(dirs.get(i), is(values[i]));
+      assertThat(paths.get(i), is(values[i]));
     }
   }
 }
index a867392245b7d83f3c49c8bc7ec479cb5328ca91..22731536df309aaa48452ea521087f372173b938 100644 (file)
@@ -32,6 +32,7 @@ import org.apache.commons.lang.SystemUtils;
 import org.apache.maven.project.MavenProject;
 import org.hamcrest.Description;
 import org.hamcrest.Matcher;
+import org.hamcrest.Matchers;
 import org.hamcrest.TypeSafeMatcher;
 import org.junit.Before;
 import org.junit.Test;
@@ -39,6 +40,7 @@ import org.sonar.api.batch.FileFilter;
 import org.sonar.api.test.MavenTestUtils;
 
 import java.io.File;
+import java.util.Arrays;
 import java.util.List;
 
 public class DefaultProjectFileSystemTest {
@@ -205,6 +207,19 @@ public class DefaultProjectFileSystemTest {
     assertThat(fsWithFilter.getSourceFiles(), not(hasItem(named("Bar.java"))));
   }
 
+  @Test
+  public void testSelectiveFileFilter() {
+    DefaultProjectFileSystem.FileSelectionFilter filter = new DefaultProjectFileSystem.FileSelectionFilter(
+        Arrays.asList(new File("foo/Bar.java"), new File("hello/Bar.java"), new File("hello/World.java")));
+    assertThat(filter.accept(new File("foo/Bar.java")), Matchers.is(true));
+    assertThat(filter.accept(new File("hello/Bar.java")), Matchers.is(true));
+    assertThat(filter.accept(new File("hello/World.java")), Matchers.is(true));
+
+    assertThat(filter.accept(new File("foo/Unknown.java")), Matchers.is(false));
+    assertThat(filter.accept(new File("foo/bar/Bar.java")), Matchers.is(false));
+    assertThat(filter.accept(new File("foo/World.java")), Matchers.is(false));
+  }
+
   private DefaultProjectFileSystem newDefaultProjectFileSystem(Project project) {
     return (DefaultProjectFileSystem) project.getFileSystem();
   }