Browse Source

Allow to manually define source files to analyze

tags/2.9
Simon Brandhof 13 years ago
parent
commit
1d73764b9a

+ 15
- 2
sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java View 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());
}
}

+ 2
- 2
sonar-batch/src/main/java/org/sonar/batch/bootstrapper/ProjectDefinition.java View 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() {

+ 91
- 20
sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java View 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));
}

/**

+ 38
- 12
sonar-plugin-api/src/main/java/org/sonar/api/resources/DefaultProjectFileSystem.java View 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();
}
}

+ 21
- 11
sonar-plugin-api/src/test/java/org/sonar/api/batch/bootstrap/ProjectDefinitionTest.java View 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]));
}
}
}

+ 15
- 0
sonar-plugin-api/src/test/java/org/sonar/api/resources/DefaultProjectFileSystemTest.java View 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();
}

Loading…
Cancel
Save