@@ -0,0 +1,131 @@ | |||
/* | |||
* Sonar Runner - Batch | |||
* Copyright (C) 2011 SonarSource | |||
* dev@sonar.codehaus.org | |||
* | |||
* This program 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. | |||
* | |||
* This program 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 this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.batch; | |||
import com.google.common.base.Joiner; | |||
import com.google.common.collect.Lists; | |||
import org.apache.commons.io.FileUtils; | |||
import org.apache.commons.io.FilenameUtils; | |||
import org.apache.commons.io.filefilter.AndFileFilter; | |||
import org.apache.commons.io.filefilter.FileFileFilter; | |||
import org.apache.commons.io.filefilter.IOFileFilter; | |||
import org.apache.commons.io.filefilter.TrueFileFilter; | |||
import org.apache.commons.lang.StringUtils; | |||
import org.sonar.api.utils.WildcardPattern; | |||
import java.io.File; | |||
import java.util.Collection; | |||
import java.util.Collections; | |||
import java.util.List; | |||
class FilePattern { | |||
Collection<File> listFiles(File basedir, String pattern) { | |||
File absoluteBasedir = absoluteBasedir(pattern); | |||
IOFileFilter filter; | |||
if (absoluteBasedir != null) { | |||
filter = new AbsolutePathFilter(WildcardPattern.create(pattern, "/")); | |||
basedir = absoluteBasedir.isFile() ? absoluteBasedir.getParentFile() : absoluteBasedir; | |||
} else { | |||
filter = new RelativePathFilter(basedir, WildcardPattern.create(pattern, "/")); | |||
} | |||
if (basedir.isDirectory() && basedir.exists()) { | |||
return FileUtils.listFiles(basedir, new AndFileFilter(FileFileFilter.FILE, filter), TrueFileFilter.TRUE); | |||
} | |||
return Collections.emptyList(); | |||
} | |||
private File absoluteBasedir(String pattern) { | |||
File absoluteBasedir = null; | |||
int wildcard = StringUtils.indexOfAny(pattern, new char[]{'*', '?'}); | |||
if (wildcard == 0) { | |||
// relative path | |||
} else if (wildcard == -1) { | |||
absoluteBasedir = new File(pattern); | |||
} else { | |||
int lastSlashBeforeWildcard = pattern.substring(0, wildcard).lastIndexOf("/"); | |||
if (lastSlashBeforeWildcard >= 0) { | |||
String path = pattern.substring(0, lastSlashBeforeWildcard); | |||
absoluteBasedir = new File(path); | |||
} | |||
} | |||
if (absoluteBasedir != null && !absoluteBasedir.isAbsolute()) { | |||
absoluteBasedir = null; | |||
} | |||
return absoluteBasedir; | |||
} | |||
private static class RelativePathFilter implements IOFileFilter { | |||
private final File basedir; | |||
private final WildcardPattern pattern; | |||
private RelativePathFilter(File basedir, WildcardPattern pattern) { | |||
this.basedir = basedir; | |||
this.pattern = pattern; | |||
} | |||
public boolean accept(File file) { | |||
return pattern.match(relativePath(file)); | |||
} | |||
public boolean accept(File file, String filename) { | |||
return true; | |||
} | |||
String relativePath(File file) { | |||
List<String> stack = Lists.newArrayList(); | |||
String path = FilenameUtils.normalize(file.getAbsolutePath()); | |||
File cursor = new File(path); | |||
while (cursor != null) { | |||
if (containsFile(cursor)) { | |||
return Joiner.on("/").join(stack); | |||
} | |||
stack.add(0, cursor.getName()); | |||
cursor = cursor.getParentFile(); | |||
} | |||
return null; | |||
} | |||
private boolean containsFile(File cursor) { | |||
return FilenameUtils.equalsNormalizedOnSystem(basedir.getAbsolutePath(), cursor.getAbsolutePath()); | |||
} | |||
} | |||
private static class AbsolutePathFilter implements IOFileFilter { | |||
private final WildcardPattern pattern; | |||
private AbsolutePathFilter(WildcardPattern pattern) { | |||
this.pattern = pattern; | |||
} | |||
public boolean accept(File file) { | |||
return pattern.match(file.getAbsolutePath()); | |||
} | |||
public boolean accept(File file, String filename) { | |||
return true; | |||
} | |||
} | |||
} |
@@ -35,11 +35,8 @@ import java.io.File; | |||
import java.io.FileFilter; | |||
import java.io.FileInputStream; | |||
import java.io.IOException; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.*; | |||
import java.util.Map.Entry; | |||
import java.util.Properties; | |||
/** | |||
* Class that creates a Sonar project definition based on a set of properties. | |||
@@ -325,8 +322,8 @@ class ProjectReactorBuilder { | |||
// We need to resolve patterns that may have been used in "sonar.libraries" | |||
for (String pattern : Utils.getListFromProperty(props, PROPERTY_LIBRARIES)) { | |||
File[] files = getLibraries(baseDir, pattern); | |||
if (files == null || files.length == 0) { | |||
Collection<File> files = getLibraries(baseDir, pattern); | |||
if (files.isEmpty()) { | |||
LOG.error("Invalid value of " + PROPERTY_LIBRARIES + " for " + projectId); | |||
throw new IllegalStateException("No file matching pattern \"" + pattern + "\" in directory \"" + baseDir + "\""); | |||
} | |||
@@ -478,23 +475,8 @@ class ProjectReactorBuilder { | |||
* Returns files matching specified pattern. | |||
*/ | |||
@VisibleForTesting | |||
protected static File[] getLibraries(File baseDir, String pattern) { | |||
final int i = Math.max(pattern.lastIndexOf('/'), pattern.lastIndexOf('\\')); | |||
final String dirPath, filePattern; | |||
if (i == -1) { | |||
dirPath = "."; | |||
filePattern = pattern; | |||
} else { | |||
dirPath = pattern.substring(0, i); | |||
filePattern = pattern.substring(i + 1); | |||
} | |||
FileFilter fileFilter = new AndFileFilter(FileFileFilter.FILE, new WildcardFileFilter(filePattern)); | |||
File dir = resolvePath(baseDir, dirPath); | |||
File[] files = dir.listFiles(fileFilter); | |||
if (files == null) { | |||
files = new File[0]; | |||
} | |||
return files; | |||
protected static Collection<File> getLibraries(File baseDir, String pattern) { | |||
return new FilePattern().listFiles(baseDir, pattern); | |||
} | |||
private static File resolvePath(File baseDir, String path) { |
@@ -0,0 +1,72 @@ | |||
/* | |||
* Sonar Runner - Batch | |||
* Copyright (C) 2011 SonarSource | |||
* dev@sonar.codehaus.org | |||
* | |||
* This program 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. | |||
* | |||
* This program 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 this program; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 | |||
*/ | |||
package org.sonar.runner.batch; | |||
import org.junit.Before; | |||
import org.junit.Test; | |||
import java.io.File; | |||
import java.util.Collection; | |||
import static org.fest.assertions.Assertions.assertThat; | |||
public class FilePatternTest { | |||
File basedir, rootFile, subFile; | |||
@Before | |||
public void init() throws Exception { | |||
rootFile = new File(getClass().getResource("/org/sonar/runner/batch/FilePatternTest/root.txt").toURI()); | |||
subFile = new File(getClass().getResource("/org/sonar/runner/batch/FilePatternTest/subdir/subfile.txt").toURI()); | |||
basedir = rootFile.getParentFile(); | |||
} | |||
@Test | |||
public void should_list_files_by_relative_path() throws Exception { | |||
assertThat(new FilePattern().listFiles(basedir, "subdir/*.txt")).containsOnly(subFile); | |||
assertThat(new FilePattern().listFiles(basedir, "*.txt")).containsOnly(rootFile); | |||
assertThat(new FilePattern().listFiles(basedir, "root.txt")).containsOnly(rootFile); | |||
assertThat(new FilePattern().listFiles(basedir, "ro*t.txt")).containsOnly(rootFile); | |||
assertThat(new FilePattern().listFiles(basedir, "ro?t.txt")).containsOnly(rootFile); | |||
assertThat(new FilePattern().listFiles(basedir, "r?t.txt")).isEmpty(); | |||
assertThat(new FilePattern().listFiles(basedir, "*")).containsOnly(rootFile); | |||
assertThat(new FilePattern().listFiles(basedir, "**/*")).containsOnly(rootFile, subFile); | |||
assertThat(new FilePattern().listFiles(basedir, "**/*.txt")).containsOnly(subFile, rootFile); | |||
assertThat(new FilePattern().listFiles(basedir, "**/*.jar")).isEmpty(); | |||
assertThat(new FilePattern().listFiles(basedir, "elsewhere/root.txt")).isEmpty(); | |||
assertThat(new FilePattern().listFiles(basedir, "elsewhere/subfile.txt")).isEmpty(); | |||
} | |||
@Test | |||
public void should_list_files_by_absolute_path() throws Exception { | |||
assertOnly(new FilePattern().listFiles(basedir, basedir.getCanonicalPath() + "/*.txt"), rootFile); | |||
assertOnly(new FilePattern().listFiles(basedir, basedir.getCanonicalPath() + "/**/subdir/*"), subFile); | |||
assertOnly(new FilePattern().listFiles(basedir, rootFile.getCanonicalPath()), rootFile); | |||
assertOnly(new FilePattern().listFiles(basedir, basedir.getCanonicalPath() + "/*/subfile.txt"), subFile); | |||
assertThat(new FilePattern().listFiles(basedir, basedir.getCanonicalPath() + "/**/*.txt")).containsOnly(subFile, rootFile); | |||
assertThat(new FilePattern().listFiles(basedir, basedir.getCanonicalPath() + "/ElseWhere/**/*.txt")).isEmpty(); | |||
assertThat(new FilePattern().listFiles(basedir, "/ElseWhere/**/*.txt")).isEmpty(); | |||
} | |||
private void assertOnly(Collection<File> files, File file) throws Exception { | |||
assertThat(files).hasSize(1); | |||
assertThat(files.iterator().next().getCanonicalPath()).isEqualTo(file.getCanonicalPath()); | |||
} | |||
} |
@@ -447,17 +447,17 @@ public class ProjectReactorBuilderTest { | |||
@Test | |||
public void shouldFilterFiles() throws Exception { | |||
File baseDir = TestUtils.getResource(this.getClass(), "shouldFilterFiles"); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir, "in*.txt").length).isEqualTo(1); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir, "*.txt").length).isEqualTo(2); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir.getParentFile(), "shouldFilterFiles/in*.txt").length).isEqualTo(1); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir.getParentFile(), "shouldFilterFiles/*.txt").length).isEqualTo(2); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir, "in*.txt")).hasSize(1); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir, "*.txt")).hasSize(2); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir.getParentFile(), "shouldFilterFiles/in*.txt")).hasSize(1); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir.getParentFile(), "shouldFilterFiles/*.txt")).hasSize(2); | |||
} | |||
@Test | |||
public void shouldWorkWithAbsolutePath() throws Exception { | |||
File baseDir = new File("not-exists"); | |||
String absolutePattern = TestUtils.getResource(this.getClass(), "shouldFilterFiles").getAbsolutePath() + "/in*.txt"; | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir.getParentFile(), absolutePattern).length).isEqualTo(1); | |||
assertThat(ProjectReactorBuilder.getLibraries(baseDir.getParentFile(), absolutePattern)).hasSize(1); | |||
} | |||
@Test |
@@ -113,8 +113,8 @@ | |||
<configuration> | |||
<rules> | |||
<requireFilesSize> | |||
<minsize>250000</minsize> | |||
<maxsize>300000</maxsize> | |||
<minsize>280000</minsize> | |||
<maxsize>310000</maxsize> | |||
<files> | |||
<file>${pom.build.directory}/sonar-runner-${pom.version}.zip</file> | |||
</files> |