diff options
author | Simon Brandhof <simon.brandhof@gmail.com> | 2013-02-12 17:56:00 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@gmail.com> | 2013-02-12 17:56:23 +0100 |
commit | b218afa5a514c2a3a7fcb856cde88d884fc129c8 (patch) | |
tree | 0ce15e51e62abf163b4aef938e11eb7e13273530 /sonar-batch | |
parent | 102fe9aa9858c9371140ce66b30d48be21a24696 (diff) | |
download | sonarqube-b218afa5a514c2a3a7fcb856cde88d884fc129c8.tar.gz sonarqube-b218afa5a514c2a3a7fcb856cde88d884fc129c8.zip |
SONAR-1896 SONAR-3739 improve the API of scan file system
Diffstat (limited to 'sonar-batch')
31 files changed, 387 insertions, 658 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/AbstractMavenPluginExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/AbstractMavenPluginExecutor.java index c29939a5738..a9752543943 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/AbstractMavenPluginExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/AbstractMavenPluginExecutor.java @@ -26,23 +26,24 @@ import org.sonar.api.batch.maven.MavenPluginHandler; import org.sonar.api.resources.Project; import org.sonar.api.utils.SonarException; import org.sonar.api.utils.TimeProfiler; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; /** * Abstract implementation of {@link MavenPluginExecutor} to reduce duplications in concrete implementations for different Maven versions. */ public abstract class AbstractMavenPluginExecutor implements MavenPluginExecutor { - public final MavenPluginHandler execute(Project project, ProjectDefinition projectDefinition, MavenPluginHandler handler) { + public final MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) { for (String goal : handler.getGoals()) { MavenPlugin plugin = MavenPlugin.getPlugin(project.getPom(), handler.getGroupId(), handler.getArtifactId()); execute(project, - projectDefinition, + fs, getGoal(handler.getGroupId(), handler.getArtifactId(), (plugin != null && plugin.getPlugin() != null ? plugin.getPlugin().getVersion() : null), goal)); } return handler; } - public final void execute(Project project, ProjectDefinition projectDefinition, String goal) { + public final void execute(Project project, DefaultModuleFileSystem fs, String goal) { TimeProfiler profiler = new TimeProfiler().start("Execute " + goal); ClassLoader currentClassLoader = Thread.currentThread().getContextClassLoader(); try { @@ -56,7 +57,7 @@ public abstract class AbstractMavenPluginExecutor implements MavenPluginExecutor } if (project.getPom() != null) { - MavenProjectConverter.synchronizeFileSystem(project.getPom(), projectDefinition); + MavenProjectConverter.synchronizeFileSystem(project.getPom(), fs); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java b/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java deleted file mode 100644 index 2dfe6dbe3fc..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/DefaultProjectFileSystem2.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import org.apache.commons.io.FileUtils; -import org.apache.maven.project.MavenProject; -import org.sonar.api.batch.FileFilter; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.resources.DefaultProjectFileSystem; -import org.sonar.api.resources.Languages; -import org.sonar.api.resources.Project; -import org.sonar.api.utils.SonarException; - -import java.io.File; -import java.io.IOException; -import java.util.List; - -/** - * Implementation of {@link org.sonar.api.resources.ProjectFileSystem} based on {@link ProjectDefinition} and {@link MavenProject}. - */ -public class DefaultProjectFileSystem2 extends DefaultProjectFileSystem { - - private ProjectDefinition def; - private MavenProject pom; - - public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, FileFilter[] fileFilters) { - super(project, languages, fileFilters); - this.def = def; - } - - /** - * For Maven. - */ - public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom, FileFilter[] fileFilters) { - this(project, languages, def, fileFilters); - this.pom = pom; - } - - public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def) { - this(project, languages, def, new FileFilter[0]); - } - - /** - * For Maven. - */ - public DefaultProjectFileSystem2(Project project, Languages languages, ProjectDefinition def, MavenProject pom) { - this(project, languages, def, pom, new FileFilter[0]); - } - - @Override - public File getBasedir() { - return def.getBaseDir(); - } - - @Override - public File getBuildDir() { - if (pom != null) { - return resolvePath(pom.getBuild().getDirectory()); - } else { - // TODO workaround - return new File(getSonarWorkingDirectory(), "target"); - } - } - - @Override - public File getBuildOutputDir() { - if (pom != null) { - return resolvePath(pom.getBuild().getOutputDirectory()); - } else { - if (def.getBinaries().isEmpty()) { - // workaround for IndexOutOfBoundsException - return new File(getBuildDir(), "classes"); - } - // TODO we assume that there is only one directory which contains compiled code - return resolvePath(def.getBinaries().get(0)); - } - } - - @Override - public List<File> getSourceDirs() { - List<File> unfiltered = resolvePaths(def.getSourceDirs()); - return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS)); - } - - /** - * @deprecated since 2.6, because should be immutable - */ - @Override - @Deprecated - public DefaultProjectFileSystem addSourceDir(File dir) { - if (dir == null) { - throw new IllegalArgumentException("Can not add null to project source dirs"); - } - if (pom != null) { - pom.getCompileSourceRoots().add(0, dir.getAbsolutePath()); - } - def.addSourceDirs(dir.getAbsolutePath()); - return this; - } - - /** - * Maven can modify test directories during Sonar execution - see MavenPhaseExecutor. - */ - @Override - public List<File> getTestDirs() { - List<File> unfiltered = resolvePaths(def.getTestDirs()); - return ImmutableList.copyOf(Iterables.filter(unfiltered, DIRECTORY_EXISTS)); - } - - /** - * @deprecated since 2.6, because should be immutable - */ - @Override - @Deprecated - public DefaultProjectFileSystem addTestDir(File dir) { - if (dir == null) { - throw new IllegalArgumentException("Can not add null to project test dirs"); - } - if (pom != null) { - pom.getTestCompileSourceRoots().add(0, dir.getAbsolutePath()); - } - def.addTestDirs(dir.getAbsolutePath()); - return this; - } - - /** - * TODO Godin: seems that used only by Cobertura and Clover - */ - @Override - public File getReportOutputDir() { - if (pom != null) { - return resolvePath(pom.getReporting().getOutputDirectory()); - } else { - return new File(getBuildDir(), "site"); - } - } - - @Override - public File getSonarWorkingDirectory() { - try { - FileUtils.forceMkdir(def.getWorkDir()); - return def.getWorkDir(); - } catch (IOException e) { - throw new SonarException("Unable to retrieve Sonar working directory.", e); - } - } - - @Override - protected List<File> getInitialSourceFiles() { - return resolvePaths(def.getSourceFiles()); - } - - @Override - protected List<File> getInitialTestFiles() { - return resolvePaths(def.getTestFiles()); - } - - // Hack to instantiate DefaultProjectFileSystem2 before executing Phases. - // TODO all the project bootstrapping must be refactored. It's overcomplicated. - public void start() { - - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/FakeMavenPluginExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/FakeMavenPluginExecutor.java index cd31e21bbda..0129cf50fdf 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/FakeMavenPluginExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/FakeMavenPluginExecutor.java @@ -19,16 +19,16 @@ */ package org.sonar.batch; -import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.maven.MavenPluginHandler; import org.sonar.api.resources.Project; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; public final class FakeMavenPluginExecutor implements MavenPluginExecutor { - public void execute(Project project, ProjectDefinition projectDef, String goal) { + public void execute(Project project, DefaultModuleFileSystem fs, String goal) { // do nothing } - public MavenPluginHandler execute(Project project, ProjectDefinition projectDefinition, MavenPluginHandler handler) { + public MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) { // do nothing return handler; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java index 55d18caa39b..89bc49f577e 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenPluginExecutor.java @@ -23,11 +23,12 @@ import org.sonar.api.BatchComponent; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.maven.MavenPluginHandler; import org.sonar.api.resources.Project; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; public interface MavenPluginExecutor extends BatchComponent { - void execute(Project project, ProjectDefinition def, String goal); + void execute(Project project, DefaultModuleFileSystem def, String goal); - MavenPluginHandler execute(Project project, ProjectDefinition def, MavenPluginHandler handler); + MavenPluginHandler execute(Project project, DefaultModuleFileSystem def, MavenPluginHandler handler); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java index 9e214b56117..7aecc6d72d3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/MavenProjectConverter.java @@ -20,6 +20,7 @@ package org.sonar.batch; import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; import org.apache.commons.lang.StringUtils; import org.apache.maven.model.CiManagement; @@ -29,16 +30,18 @@ import org.apache.maven.project.MavenProject; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.utils.SonarException; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.List; import java.util.Map; public final class MavenProjectConverter { private static final String UNABLE_TO_DETERMINE_PROJECT_STRUCTURE_EXCEPTION_MESSAGE = "Unable to determine structure of project." + - " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used."; + " Probably you use Maven Advanced Reactor Options, which is not supported by Sonar and should not be used."; private MavenProjectConverter() { // only static methods @@ -104,12 +107,12 @@ public final class MavenProjectConverter { ProjectDefinition definition = ProjectDefinition.create(); // IMPORTANT NOTE : reference on properties from POM model must not be saved, instead they should be copied explicitly - see SONAR-2896 definition - .setProperties(pom.getModel().getProperties()) - .setKey(key) - .setVersion(pom.getVersion()) - .setName(pom.getName()) - .setDescription(pom.getDescription()) - .addContainerExtension(pom); + .setProperties(pom.getModel().getProperties()) + .setKey(key) + .setVersion(pom.getVersion()) + .setName(pom.getName()) + .setDescription(pom.getDescription()) + .addContainerExtension(pom); convertMavenLinksToProperties(definition, pom); @@ -152,20 +155,53 @@ public final class MavenProjectConverter { public static void synchronizeFileSystem(MavenProject pom, ProjectDefinition into) { into.setBaseDir(pom.getBasedir()); - into.setWorkDir(new File(resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), "sonar")); + File buildDir = resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()); + if (buildDir != null) { + into.setBuildDir(buildDir); + into.setWorkDir(new File(buildDir, "sonar")); + } into.setSourceDirs((String[]) pom.getCompileSourceRoots().toArray(new String[pom.getCompileSourceRoots().size()])); into.setTestDirs((String[]) pom.getTestCompileSourceRoots().toArray(new String[pom.getTestCompileSourceRoots().size()])); + File binaryDir = resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir()); + if (binaryDir != null) { + into.addBinaryDir(binaryDir); + } + } + + public static void synchronizeFileSystem(MavenProject pom, DefaultModuleFileSystem into) { + into.resetDirs( + pom.getBasedir(), + new File(resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), "sonar"), + resolvePath(pom.getBuild().getDirectory(), pom.getBasedir()), + resolvePaths((List<String>) pom.getCompileSourceRoots(), pom.getBasedir()), + resolvePaths((List<String>) pom.getTestCompileSourceRoots(), pom.getBasedir()), + Arrays.asList(resolvePath(pom.getBuild().getOutputDirectory(), pom.getBasedir())) + ); } static File resolvePath(String path, File basedir) { - File file = new File(path); - if (!file.isAbsolute()) { - try { - file = new File(basedir, path).getCanonicalFile(); - } catch (IOException e) { - throw new SonarException("Unable to resolve path '" + path + "'", e); + if (path != null) { + File file = new File(path); + if (!file.isAbsolute()) { + try { + file = new File(basedir, path).getCanonicalFile(); + } catch (IOException e) { + throw new SonarException("Unable to resolve path '" + path + "'", e); + } + } + return file; + } + return null; + } + + static List<File> resolvePaths(List<String> paths, File basedir) { + List<File> result = Lists.newArrayList(); + for (String path : paths) { + File dir = resolvePath(path, basedir); + if (dir != null) { + result.add(dir); } } - return file; + return result; } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/InspectionContainer.java b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/InspectionContainer.java index 83d16a37fe6..2885cfd3ffb 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/bootstrap/InspectionContainer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/bootstrap/InspectionContainer.java @@ -26,9 +26,10 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.profiles.RulesProfile; import org.sonar.api.resources.Languages; import org.sonar.api.resources.Project; +import org.sonar.api.scan.filesystem.ModuleExclusions; +import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.DefaultProfileLoader; import org.sonar.batch.DefaultProjectClasspath; -import org.sonar.batch.DefaultProjectFileSystem2; import org.sonar.batch.DefaultSensorContext; import org.sonar.batch.DefaultTimeMachine; import org.sonar.batch.ProfileProvider; @@ -42,6 +43,10 @@ import org.sonar.batch.index.ResourcePersister; import org.sonar.batch.local.DryRunExporter; import org.sonar.batch.phases.Phases; import org.sonar.batch.phases.PhasesTimeProfiler; +import org.sonar.batch.scan.filesystem.DeprecatedFileSystemAdapter; +import org.sonar.batch.scan.filesystem.ExclusionFileFilter; +import org.sonar.batch.scan.filesystem.LanguageFileFilters; +import org.sonar.batch.scan.filesystem.ModuleFileSystemProvider; import org.sonar.core.qualitymodel.DefaultModelFinder; import org.sonar.jpa.dao.ProfilesDao; import org.sonar.jpa.dao.RulesDao; @@ -83,10 +88,18 @@ public class InspectionContainer extends Container { container.addSingleton(component); } container.addSingleton(Languages.class); - container.addSingleton(DefaultProjectClasspath.class); - container.addSingleton(DefaultProjectFileSystem2.class); container.addSingleton(RulesDao.class); + // file system + container.addSingleton(PathResolver.class); + container.addSingleton(ModuleExclusions.class); + container.addSingleton(LanguageFileFilters.class); + container.addSingleton(ExclusionFileFilter.class); + container.addSingleton(DefaultProjectClasspath.class); + container.addPicoAdapter(new ModuleFileSystemProvider()); + container.addSingleton(DeprecatedFileSystemAdapter.class); + + // the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor) container.addSingleton(container.getComponentByType(ResourcePersister.class).getSnapshot(project)); @@ -120,9 +133,9 @@ public class InspectionContainer extends Container { protected void doStart() { DefaultIndex index = container.getComponentByType(DefaultIndex.class); index.setCurrentProject(project, - container.getComponentByType(ResourceFilters.class), - container.getComponentByType(ViolationFilters.class), - container.getComponentByType(RulesProfile.class)); + container.getComponentByType(ResourceFilters.class), + container.getComponentByType(ViolationFilters.class), + container.getComponentByType(RulesProfile.class)); container.getComponentByType(Phases.class).execute(project); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java b/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java index 6f478c2fda7..e2a82ed5342 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java @@ -29,10 +29,10 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.SensorContext; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; -import org.sonar.api.resources.ProjectFileSystem; import org.sonar.api.resources.Resource; import org.sonar.api.rules.Rule; import org.sonar.api.rules.Violation; +import org.sonar.api.scan.filesystem.ModuleFileSystem; import org.sonar.api.utils.SonarException; import org.sonar.batch.index.DefaultIndex; import org.sonar.core.i18n.RuleI18nManager; @@ -54,14 +54,14 @@ public class DryRunExporter implements BatchComponent { private final Settings settings; private final DefaultIndex sonarIndex; - private final ProjectFileSystem projectFileSystem; + private final ModuleFileSystem fileSystem; private final Server server; private final RuleI18nManager ruleI18nManager; - public DryRunExporter(Settings settings, DefaultIndex sonarIndex, ProjectFileSystem projectFileSystem, Server server, RuleI18nManager ruleI18nManager) { + public DryRunExporter(Settings settings, DefaultIndex sonarIndex, ModuleFileSystem fileSystem, Server server, RuleI18nManager ruleI18nManager) { this.settings = settings; this.sonarIndex = sonarIndex; - this.projectFileSystem = projectFileSystem; + this.fileSystem = fileSystem; this.server = server; this.ruleI18nManager = ruleI18nManager; } @@ -73,7 +73,7 @@ public class DryRunExporter implements BatchComponent { } private void exportResults(Collection<Resource> resources) { - File exportFile = new File(projectFileSystem.getSonarWorkingDirectory(), settings.getString("sonar.dryRun.export.path")); + File exportFile = new File(fileSystem.workingDir(), settings.getString("sonar.dryRun.export.path")); LOG.info("Exporting DryRun results to " + exportFile.getAbsolutePath()); Writer output = null; diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/InitializersExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/InitializersExecutor.java index 7f37d4cb18c..f4d58be33e8 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/InitializersExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/InitializersExecutor.java @@ -24,12 +24,12 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.BatchExtensionDictionnary; import org.sonar.api.batch.Initializer; -import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.maven.DependsUponMavenPlugin; import org.sonar.api.batch.maven.MavenPluginHandler; import org.sonar.api.resources.Project; import org.sonar.api.utils.TimeProfiler; import org.sonar.batch.MavenPluginExecutor; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import java.util.Collection; @@ -39,15 +39,15 @@ public class InitializersExecutor { private MavenPluginExecutor mavenExecutor; - private ProjectDefinition projectDef; + private DefaultModuleFileSystem fs; private Project project; private BatchExtensionDictionnary selector; - public InitializersExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDef, MavenPluginExecutor mavenExecutor) { + public InitializersExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor) { this.selector = selector; this.mavenExecutor = mavenExecutor; this.project = project; - this.projectDef = projectDef; + this.fs = fs; } public void execute() { @@ -70,7 +70,7 @@ public class InitializersExecutor { MavenPluginHandler handler = ((DependsUponMavenPlugin) sensor).getMavenPluginHandler(project); if (handler != null) { TimeProfiler profiler = new TimeProfiler(LOG).start("Execute maven plugin " + handler.getArtifactId()); - mavenExecutor.execute(project, projectDef, handler); + mavenExecutor.execute(project, fs, handler); profiler.stop(); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPhaseExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPhaseExecutor.java index a6d88708d86..87d397d5a30 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPhaseExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/MavenPhaseExecutor.java @@ -24,23 +24,24 @@ import org.sonar.api.BatchComponent; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.resources.Project; import org.sonar.batch.MavenPluginExecutor; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; public class MavenPhaseExecutor implements BatchComponent { public static final String PROP_PHASE = "sonar.phase"; private MavenPluginExecutor executor; - private ProjectDefinition projectDef; + private DefaultModuleFileSystem fs; - public MavenPhaseExecutor(ProjectDefinition projectDef, MavenPluginExecutor executor) { - this.projectDef = projectDef; + public MavenPhaseExecutor(DefaultModuleFileSystem fs, MavenPluginExecutor executor) { + this.fs = fs; this.executor = executor; } public void execute(Project project) { String mavenPhase = (String) project.getProperty(PROP_PHASE); if (!StringUtils.isBlank(mavenPhase)) { - executor.execute(project, projectDef, mavenPhase); + executor.execute(project, fs, mavenPhase); } } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/PostJobsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/PostJobsExecutor.java index f5530102336..e2871b9b632 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/PostJobsExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/PostJobsExecutor.java @@ -26,12 +26,12 @@ import org.sonar.api.BatchComponent; import org.sonar.api.batch.BatchExtensionDictionnary; import org.sonar.api.batch.PostJob; import org.sonar.api.batch.SensorContext; -import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.maven.DependsUponMavenPlugin; import org.sonar.api.batch.maven.MavenPluginHandler; import org.sonar.api.resources.Project; import org.sonar.batch.MavenPluginExecutor; import org.sonar.batch.local.DryRunExporter; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import java.util.Collection; @@ -40,15 +40,15 @@ public class PostJobsExecutor implements BatchComponent { private final BatchExtensionDictionnary selector; private final Project project; - private final ProjectDefinition projectDefinition; + private final DefaultModuleFileSystem fs; private final MavenPluginExecutor mavenExecutor; private final DryRunExporter localModeExporter; - public PostJobsExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDefinition, MavenPluginExecutor mavenExecutor, - DryRunExporter localModeExporter) { + public PostJobsExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor, + DryRunExporter localModeExporter) { this.selector = selector; this.project = project; - this.projectDefinition = projectDefinition; + this.fs = fs; this.mavenExecutor = mavenExecutor; this.localModeExporter = localModeExporter; } @@ -79,7 +79,7 @@ public class PostJobsExecutor implements BatchComponent { if (job instanceof DependsUponMavenPlugin) { MavenPluginHandler handler = ((DependsUponMavenPlugin) job).getMavenPluginHandler(project); if (handler != null) { - mavenExecutor.execute(project, projectDefinition, handler); + mavenExecutor.execute(project, fs, handler); } } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/phases/SensorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/phases/SensorsExecutor.java index ac8f7ca756c..d08ae6cba8b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/phases/SensorsExecutor.java +++ b/sonar-batch/src/main/java/org/sonar/batch/phases/SensorsExecutor.java @@ -33,6 +33,7 @@ import org.sonar.api.resources.Project; import org.sonar.api.utils.TimeProfiler; import org.sonar.batch.MavenPluginExecutor; import org.sonar.batch.events.EventBus; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import java.util.Collection; @@ -42,15 +43,15 @@ public class SensorsExecutor implements BatchComponent { private MavenPluginExecutor mavenExecutor; private EventBus eventBus; private Project project; - private ProjectDefinition projectDefinition; + private DefaultModuleFileSystem fs; private BatchExtensionDictionnary selector; - public SensorsExecutor(BatchExtensionDictionnary selector, Project project, ProjectDefinition projectDefinition, MavenPluginExecutor mavenExecutor, EventBus eventBus) { + public SensorsExecutor(BatchExtensionDictionnary selector, Project project, DefaultModuleFileSystem fs, MavenPluginExecutor mavenExecutor, EventBus eventBus) { this.selector = selector; this.mavenExecutor = mavenExecutor; this.eventBus = eventBus; this.project = project; - this.projectDefinition = projectDefinition; + this.fs = fs; } public void execute(SensorContext context) { @@ -73,7 +74,7 @@ public class SensorsExecutor implements BatchComponent { MavenPluginHandler handler = ((DependsUponMavenPlugin) sensor).getMavenPluginHandler(project); if (handler != null) { TimeProfiler profiler = new TimeProfiler(LOG).start("Execute maven plugin " + handler.getArtifactId()); - mavenExecutor.execute(project, projectDefinition, handler); + mavenExecutor.execute(project, fs, handler); profiler.stop(); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java index 10733249b6a..9b864e150de 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystem.java @@ -29,6 +29,7 @@ import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.filefilter.TrueFileFilter; import org.sonar.api.scan.filesystem.FileFilter; import org.sonar.api.scan.filesystem.ModuleFileSystem; +import org.sonar.api.scan.filesystem.PathResolver; import java.io.File; import java.nio.charset.Charset; @@ -46,7 +47,7 @@ public class DefaultModuleFileSystem implements ModuleFileSystem { private static final IOFileFilter DIR_FILTER = FileFilterUtils.and(HiddenFileFilter.VISIBLE, FileFilterUtils.notFileFilter(FileFilterUtils.prefixFileFilter("."))); private final Charset sourceCharset; - private File baseDir, workingDir; + private File baseDir, workingDir, buildDir; private List<File> sourceDirs, testDirs, binaryDirs; private final PathResolver pathResolver; private final List<FileFilter> fileFilters; @@ -55,6 +56,7 @@ public class DefaultModuleFileSystem implements ModuleFileSystem { private DefaultModuleFileSystem(Builder builder) { sourceCharset = builder.sourceCharset; baseDir = builder.baseDir; + buildDir = builder.buildDir; workingDir = builder.workingDir; sourceDirs = ImmutableList.copyOf(builder.sourceDirs); testDirs = ImmutableList.copyOf(builder.testDirs); @@ -68,6 +70,10 @@ public class DefaultModuleFileSystem implements ModuleFileSystem { return baseDir; } + public File buildDir() { + return buildDir; + } + public List<File> sourceDirs() { return sourceDirs; } @@ -119,12 +125,24 @@ public class DefaultModuleFileSystem implements ModuleFileSystem { /** * Breaks immutability but it's required to allow Maven Plugins to be executed and to change project structure. */ - public void resetDirs(File basedir, File workDir, List<File> sourceDirs, List<File> testDirs, List<File> binaryDirs) { + public void resetDirs(File basedir, File workDir, File buildDir, List<File> sourceDirs, List<File> testDirs, List<File> binaryDirs) { + Preconditions.checkNotNull(basedir, "Basedir can't be null"); this.baseDir = basedir; this.workingDir = workDir; - this.sourceDirs = ImmutableList.copyOf(sourceDirs); - this.testDirs = ImmutableList.copyOf(testDirs); - this.binaryDirs = ImmutableList.copyOf(binaryDirs); + this.buildDir = buildDir; + this.sourceDirs = existingDirs(sourceDirs); + this.testDirs = existingDirs(testDirs); + this.binaryDirs = existingDirs(binaryDirs); + } + + private List<File> existingDirs(List<File> dirs) { + ImmutableList.Builder<File> builder = ImmutableList.builder(); + for (File dir : dirs) { + if (dir.exists() && dir.isDirectory()) { + builder.add(dir); + } + } + return builder.build(); } private List<File> files(List<File> dirs, FileFilter.FileType fileType, IOFileFilter languageFilter) { @@ -167,7 +185,7 @@ public class DefaultModuleFileSystem implements ModuleFileSystem { static final class Builder { private Charset sourceCharset; - private File baseDir, workingDir; + private File baseDir, workingDir, buildDir; private List<File> sourceDirs = Lists.newArrayList(), testDirs = Lists.newArrayList(), binaryDirs = Lists.newArrayList(); private List<FileFilter> fileFilters = Lists.newArrayList(); private PathResolver pathResolver; @@ -178,13 +196,18 @@ public class DefaultModuleFileSystem implements ModuleFileSystem { return this; } - Builder baseDir(File f) { - this.baseDir = f; + Builder baseDir(File d) { + this.baseDir = d; + return this; + } + + Builder buildDir(File d) { + this.buildDir = d; return this; } - Builder workingDir(File f) { - this.workingDir = f; + Builder workingDir(File d) { + this.workingDir = d; return this; } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileSystemAdapter.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileSystemAdapter.java index a0a8120951b..92a98988f5b 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileSystemAdapter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/DeprecatedFileSystemAdapter.java @@ -23,26 +23,46 @@ import com.google.common.collect.Iterables; import com.google.common.collect.Lists; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.CharEncoding; +import org.apache.maven.project.MavenProject; import org.sonar.api.resources.InputFile; +import org.sonar.api.resources.InputFileUtils; import org.sonar.api.resources.Java; import org.sonar.api.resources.Language; +import org.sonar.api.resources.Project; import org.sonar.api.resources.ProjectFileSystem; import org.sonar.api.resources.Resource; -import org.sonar.api.scan.filesystem.ModuleFileSystem; +import org.sonar.api.scan.filesystem.PathResolver; +import org.sonar.api.utils.SonarException; + +import javax.annotation.Nullable; import java.io.File; import java.io.IOException; import java.nio.charset.Charset; import java.util.List; +/** + * Adapter for keeping the backward-compatibility of the deprecated component {@link org.sonar.api.resources.ProjectFileSystem} + * @since 3.5 + */ public class DeprecatedFileSystemAdapter implements ProjectFileSystem { - private final ModuleFileSystem target; - private final PathResolver pathResolver; + private final DefaultModuleFileSystem target; + private final PathResolver pathResolver = new PathResolver(); + private final MavenProject pom; + - public DeprecatedFileSystemAdapter(ModuleFileSystem target, PathResolver pathResolver) { + public DeprecatedFileSystemAdapter(DefaultModuleFileSystem target, Project project, @Nullable MavenProject pom) { this.target = target; - this.pathResolver = pathResolver; + this.pom = pom; + + // TODO See http://jira.codehaus.org/browse/SONAR-2126 + // previously MavenProjectBuilder was responsible for creation of ProjectFileSystem + project.setFileSystem(this); + } + + public DeprecatedFileSystemAdapter(DefaultModuleFileSystem target, Project project) { + this(target, project, null); } public Charset getSourceCharset() { @@ -54,12 +74,22 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem { } public File getBuildDir() { - // TODO - return null; + File dir = target.buildDir(); + if (dir == null) { + // emulate build dir to keep backward-compatibility + dir = new File(getSonarWorkingDirectory(), "build"); + } + return dir; } public File getBuildOutputDir() { - return Iterables.getFirst(target.binaryDirs(), null); + File dir = Iterables.getFirst(target.binaryDirs(), null); + if (dir == null) { + // emulate binary dir + dir = new File(getBuildDir(), "classes"); + } + + return dir; } public List<File> getSourceDirs() { @@ -79,8 +109,11 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem { } public File getReportOutputDir() { - // TODO - return null; + if (pom != null) { + return resolvePath(pom.getReporting().getOutputDirectory()); + } + // emulate Maven report output dir + return new File(getBuildDir(), "site"); } public File getSonarWorkingDirectory() { @@ -88,8 +121,15 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem { } public File resolvePath(String path) { - // TODO - return null; + File file = new File(path); + if (!file.isAbsolute()) { + try { + file = new File(getBasedir(), path).getCanonicalFile(); + } catch (IOException e) { + throw new SonarException("Unable to resolve path '" + path + "'", e); + } + } + return file; } public List<File> getSourceFiles(Language... langs) { @@ -132,17 +172,41 @@ public class DeprecatedFileSystemAdapter implements ProjectFileSystem { } public Resource toResource(File file) { - // TODO - return null; + if (file == null || !file.exists()) { + return null; + } + PathResolver.RelativePath relativePath = pathResolver.relativePath(getSourceDirs(), file); + if (relativePath == null) { + return null; + } + return (file.isFile() ? new org.sonar.api.resources.File(relativePath.path()) : new org.sonar.api.resources.Directory(relativePath.path())); } public List<InputFile> mainFiles(String... langs) { - // TODO - return null; + List<InputFile> result = Lists.newArrayList(); + for (String lang : langs) { + List<File> files = target.sourceFilesOfLang(lang); + for (File file : files) { + PathResolver.RelativePath relativePath = pathResolver.relativePath(getSourceDirs(), file); + if (relativePath != null) { + result.add(InputFileUtils.create(relativePath.dir(), relativePath.path())); + } + } + } + return result; } public List<InputFile> testFiles(String... langs) { - // TODO - return null; + List<InputFile> result = Lists.newArrayList(); + for (String lang : langs) { + List<File> files = target.testFilesOfLang(lang); + for (File file : files) { + PathResolver.RelativePath relativePath = pathResolver.relativePath(getTestDirs(), file); + if (relativePath != null) { + result.add(InputFileUtils.create(relativePath.dir(), relativePath.path())); + } + } + } + return result; } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionFileFilter.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionFileFilter.java index edc8dfa3518..1935205bad0 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionFileFilter.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionFileFilter.java @@ -23,10 +23,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.BatchComponent; import org.sonar.api.batch.ResourceFilter; -import org.sonar.api.config.Settings; import org.sonar.api.resources.Resource; import org.sonar.api.resources.ResourceUtils; import org.sonar.api.scan.filesystem.FileFilter; +import org.sonar.api.scan.filesystem.ModuleExclusions; import org.sonar.api.utils.WildcardPattern; import java.io.File; @@ -37,18 +37,18 @@ public class ExclusionFileFilter implements FileFilter, ResourceFilter, BatchCom private final WildcardPattern[] sourceExclusions; private final WildcardPattern[] testExclusions; - public ExclusionFileFilter(Settings settings) { - sourceInclusions = ExclusionPatterns.sourceInclusions(settings); + public ExclusionFileFilter(ModuleExclusions exclusions) { + sourceInclusions = WildcardPattern.create(exclusions.sourceInclusions()); log("Included sources: ", sourceInclusions); - testInclusions = ExclusionPatterns.testInclusions(settings); - log("Included tests: ", sourceInclusions); - - sourceExclusions = ExclusionPatterns.sourceExclusions(settings); + sourceExclusions = WildcardPattern.create(exclusions.sourceExclusions()); log("Excluded sources: ", sourceExclusions); - testExclusions = ExclusionPatterns.testExclusions(settings); - log("Excluded tests: ", sourceExclusions); + testInclusions = WildcardPattern.create(exclusions.testInclusions()); + log("Included tests: ", testInclusions); + + testExclusions = WildcardPattern.create(exclusions.testExclusions()); + log("Excluded tests: ", testExclusions); } private void log(String title, WildcardPattern[] patterns) { @@ -63,8 +63,12 @@ public class ExclusionFileFilter implements FileFilter, ResourceFilter, BatchCom public boolean accept(File file, Context context) { WildcardPattern[] inclusionPatterns = (context.fileType() == FileType.TEST ? testInclusions : sourceInclusions); - for (WildcardPattern pattern : inclusionPatterns) { - if (!pattern.match(context.fileRelativePath())) { + if (inclusionPatterns.length > 0) { + boolean matchInclusion = false; + for (WildcardPattern pattern : inclusionPatterns) { + matchInclusion |= pattern.match(context.fileRelativePath()); + } + if (!matchInclusion) { return false; } } @@ -78,9 +82,16 @@ public class ExclusionFileFilter implements FileFilter, ResourceFilter, BatchCom } public boolean isIgnored(Resource resource) { + if (!ResourceUtils.isFile(resource)) { + return false; + } WildcardPattern[] inclusionPatterns = (ResourceUtils.isUnitTestClass(resource) ? testInclusions : sourceInclusions); - for (WildcardPattern pattern : inclusionPatterns) { - if (!resource.matchFilePattern(pattern.toString())) { + if (inclusionPatterns.length > 0) { + boolean matchInclusion = false; + for (WildcardPattern pattern : inclusionPatterns) { + matchInclusion |= resource.matchFilePattern(pattern.toString()); + } + if (!matchInclusion) { return true; } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionPatterns.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionPatterns.java deleted file mode 100644 index 3b4e3ba247a..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ExclusionPatterns.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch.scan.filesystem; - -import com.google.common.collect.Lists; -import com.google.common.collect.ObjectArrays; -import org.apache.commons.lang.StringUtils; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.Settings; -import org.sonar.api.utils.WildcardPattern; - -import java.util.List; - -/** - * Get configuration of file inclusions and exclusions - * - * @since 3.5 - */ -class ExclusionPatterns { - static WildcardPattern[] sourceInclusions(Settings settings) { - return inclusions(settings, CoreProperties.PROJECT_INCLUSIONS_PROPERTY); - } - - static WildcardPattern[] testInclusions(Settings settings) { - return inclusions(settings, CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY); - } - - private static WildcardPattern[] inclusions(Settings settings, String propertyKey) { - String[] patterns = sanitize(settings.getStringArray(propertyKey)); - List<WildcardPattern> list = Lists.newArrayList(); - for (String pattern : patterns) { - if (!"**/*".equals(pattern)) { - list.add(WildcardPattern.create(pattern)); - } - } - return list.toArray(new WildcardPattern[list.size()]); - } - - static WildcardPattern[] sourceExclusions(Settings settings) { - return exclusions(settings, CoreProperties.GLOBAL_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_EXCLUSIONS_PROPERTY); - } - - static WildcardPattern[] testExclusions(Settings settings) { - return exclusions(settings, CoreProperties.GLOBAL_TEST_EXCLUSIONS_PROPERTY, CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY); - } - - private static WildcardPattern[] exclusions(Settings settings, String globalExclusionsProperty, String exclusionsProperty) { - String[] globalExclusions = settings.getStringArray(globalExclusionsProperty); - String[] exclusions = settings.getStringArray(exclusionsProperty); - String[] patterns = sanitize(ObjectArrays.concat(globalExclusions, exclusions, String.class)); - return WildcardPattern.create(patterns); - } - - private static String[] sanitize(String[] patterns) { - for (int i = 0; i < patterns.length; i++) { - patterns[i] = StringUtils.trim(patterns[i]); - } - return patterns; - } -} diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageFileFilters.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageFileFilters.java index f5cc8aacfa7..608330ba4e3 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageFileFilters.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/LanguageFileFilters.java @@ -23,9 +23,10 @@ import org.apache.commons.io.IOCase; import org.apache.commons.io.filefilter.IOFileFilter; import org.apache.commons.io.filefilter.SuffixFileFilter; import org.apache.commons.io.filefilter.TrueFileFilter; +import org.sonar.api.BatchComponent; import org.sonar.api.resources.Languages; -public class LanguageFileFilters { +public class LanguageFileFilters implements BatchComponent { private final Languages languages; public LanguageFileFilters(Languages languages) { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProvider.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProvider.java index 119d3851843..90b84addc0a 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProvider.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProvider.java @@ -19,19 +19,19 @@ */ package org.sonar.batch.scan.filesystem; +import com.google.common.base.Joiner; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.StringUtils; -import org.jfree.util.Log; import org.picocontainer.injectors.ProviderAdapter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; -import org.sonar.api.scan.filesystem.FailToCreateFileException; import org.sonar.api.scan.filesystem.FileFilter; -import org.sonar.api.scan.filesystem.ModuleFileSystem; +import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.bootstrap.TempDirectories; import java.io.File; @@ -45,10 +45,10 @@ import java.util.Locale; public class ModuleFileSystemProvider extends ProviderAdapter { private static final Logger LOG = LoggerFactory.getLogger(ModuleFileSystemProvider.class); - private ModuleFileSystem singleton; + private DefaultModuleFileSystem singleton; - public ModuleFileSystem provide(ProjectDefinition module, PathResolver pathResolver, TempDirectories tempDirectories, - LanguageFileFilters languageFileFilters, Settings settings, FileFilter[] pluginFileFilters) { + public DefaultModuleFileSystem provide(ProjectDefinition module, PathResolver pathResolver, TempDirectories tempDirectories, + LanguageFileFilters languageFileFilters, Settings settings, FileFilter[] pluginFileFilters) { if (singleton == null) { DefaultModuleFileSystem.Builder builder = new DefaultModuleFileSystem.Builder(); @@ -59,6 +59,7 @@ public class ModuleFileSystemProvider extends ProviderAdapter { // files and directories // TODO should the basedir always exist ? If yes, then we check also check that it's a dir but not a file builder.baseDir(module.getBaseDir()); + builder.buildDir(module.getBuildDir()); builder.sourceCharset(guessCharset(settings)); builder.workingDir(guessWorkingDir(module, tempDirectories)); initBinaryDirs(module, pathResolver, builder); @@ -82,7 +83,7 @@ public class ModuleFileSystemProvider extends ProviderAdapter { try { FileUtils.forceMkdir(workDir); } catch (Exception e) { - throw new FailToCreateFileException("Fail to create working dir: " + workDir.getAbsolutePath(), e); + throw new IllegalStateException("Fail to create working dir: " + workDir.getAbsolutePath(), e); } } return workDir; @@ -102,14 +103,17 @@ public class ModuleFileSystemProvider extends ProviderAdapter { } private void initSources(ProjectDefinition module, PathResolver pathResolver, DefaultModuleFileSystem.Builder builder) { - if (!module.getSourceDirs().isEmpty()) { - LOG.info("Source dirs: "); - for (String sourcePath : module.getSourceDirs()) { - File dir = pathResolver.relativeFile(module.getBaseDir(), sourcePath); - LOG.info(" " + dir.getAbsolutePath()); + List<String> paths = Lists.newArrayList(); + for (String sourcePath : module.getSourceDirs()) { + File dir = pathResolver.relativeFile(module.getBaseDir(), sourcePath); + if (dir.isDirectory() && dir.exists()) { + paths.add(dir.getAbsolutePath()); builder.addSourceDir(dir); } } + if (!paths.isEmpty()) { + LOG.info("Source dirs: " + Joiner.on(", ").join(paths)); + } List<File> sourceFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getSourceFiles()); if (!sourceFiles.isEmpty()) { LOG.info("Source files: "); @@ -121,17 +125,21 @@ public class ModuleFileSystemProvider extends ProviderAdapter { } private void initTests(ProjectDefinition module, PathResolver pathResolver, DefaultModuleFileSystem.Builder builder) { - if (!module.getTestDirs().isEmpty()) { - Log.info("Test dirs:"); - for (String testPath : module.getTestDirs()) { - File dir = pathResolver.relativeFile(module.getBaseDir(), testPath); - LOG.info(" " + dir.getAbsolutePath()); + List<String> paths = Lists.newArrayList(); + for (String testPath : module.getTestDirs()) { + File dir = pathResolver.relativeFile(module.getBaseDir(), testPath); + if (dir.exists() && dir.isDirectory()) { + paths.add(dir.getAbsolutePath()); builder.addTestDir(dir); } } + if (!paths.isEmpty()) { + LOG.info("Test dirs: " + Joiner.on(", ").join(paths)); + } + List<File> testFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getTestFiles()); if (!testFiles.isEmpty()) { - Log.info("Test files:"); + LOG.info("Test files:"); for (File testFile : testFiles) { LOG.info(" " + testFile.getAbsolutePath()); } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java deleted file mode 100644 index 357e5845f11..00000000000 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/PathResolver.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch.scan.filesystem; - -import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.collect.Lists; -import org.apache.commons.io.FilenameUtils; -import org.sonar.api.scan.filesystem.IllegalPathException; - -import java.io.File; -import java.util.List; - -/** - * @since 3.5 - */ -public class PathResolver { - - File relativeFile(File dir, String path) { - Preconditions.checkArgument(dir.isDirectory(), "Not a directory: " + dir.getAbsolutePath()); - File file = new File(path); - if (!file.isAbsolute()) { - try { - file = new File(dir, path).getCanonicalFile(); - } catch (Exception e) { - throw new IllegalPathException("Fail to resolve path '" + path + "' relative to: " + dir.getAbsolutePath()); - } - } - return file; - } - - List<File> relativeFiles(File dir, List<String> paths) { - List<File> result = Lists.newArrayList(); - for (String path : paths) { - result.add(relativeFile(dir, path)); - } - return result; - } - - String relativePath(File dir, File file) { - List<String> stack = Lists.newArrayList(); - String path = FilenameUtils.normalize(file.getAbsolutePath()); - File cursor = new File(path); - while (cursor != null) { - if (containsFile(dir, cursor)) { - return Joiner.on("/").join(stack); - } - stack.add(0, cursor.getName()); - cursor = cursor.getParentFile(); - } - return null; - } - - private boolean containsFile(File dir, File cursor) { - return FilenameUtils.equalsNormalizedOnSystem(dir.getAbsolutePath(), cursor.getAbsolutePath()); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/AbstractMavenPluginExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/AbstractMavenPluginExecutorTest.java index a208fcb5978..982a31d7167 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/AbstractMavenPluginExecutorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/AbstractMavenPluginExecutorTest.java @@ -21,16 +21,19 @@ package org.sonar.batch; import org.apache.maven.project.MavenProject; import org.junit.Test; -import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.maven.MavenPlugin; import org.sonar.api.batch.maven.MavenPluginHandler; import org.sonar.api.resources.Project; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import java.io.File; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; -import static org.junit.internal.matchers.IsCollectionContaining.hasItem; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyList; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; public class AbstractMavenPluginExecutorTest { @@ -56,10 +59,10 @@ public class AbstractMavenPluginExecutorTest { pom.getBuild().setDirectory("target"); Project foo = new Project("foo"); foo.setPom(pom); - ProjectDefinition definition = ProjectDefinition.create(); - executor.execute(foo, definition, new AddSourceMavenPluginHandler()); + DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class); + executor.execute(foo, fs, new AddSourceMavenPluginHandler()); - assertThat(definition.getSourceDirs(), hasItem("src/java")); + verify(fs).resetDirs(any(File.class), any(File.class), any(File.class), anyList(), anyList(), anyList()); } static class AddSourceMavenPluginHandler implements MavenPluginHandler { @@ -80,7 +83,7 @@ public class AbstractMavenPluginExecutorTest { } public String[] getGoals() { - return new String[] { "fake" }; + return new String[]{"fake"}; } public void configure(Project project, MavenPlugin plugin) { diff --git a/sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java b/sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java deleted file mode 100644 index 65773cad905..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/DefaultProjectFileSystem2Test.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch; - -import org.hamcrest.core.Is; -import org.junit.Test; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.resources.Languages; -import org.sonar.api.resources.Project; -import org.sonar.test.TestUtils; - -import java.io.File; - -import static org.junit.Assert.assertThat; -import static org.junit.internal.matchers.IsCollectionContaining.hasItem; - -public class DefaultProjectFileSystem2Test { - @Test - public void shouldIgnoreInexistingSourceDirs() { - File exists = TestUtils.getResource("/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs"); - File notExists = new File("target/unknown"); - - ProjectDefinition definition = ProjectDefinition.create().addSourceDirs(exists, notExists); - - DefaultProjectFileSystem2 fs = new DefaultProjectFileSystem2(new Project("foo"), new Languages(), definition); - assertThat(fs.getSourceDirs().size(), Is.is(1)); - assertThat(fs.getSourceDirs(), hasItem(exists)); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java index 325fbdd4a53..b4274ecd00d 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/MavenProjectConverterTest.java @@ -25,7 +25,9 @@ import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.project.MavenProject; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import org.hamcrest.core.Is; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.test.TestUtils; @@ -46,9 +48,13 @@ import static org.junit.Assert.fail; public class MavenProjectConverterTest { + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + /** * See SONAR-2681 */ + @Test public void shouldThrowExceptionWhenUnableToDetermineProjectStructure() { MavenProject root = new MavenProject(); root.setFile(new File("/foo/pom.xml")); @@ -64,14 +70,18 @@ public class MavenProjectConverterTest { } @Test - public void shouldConvertModules() { + public void shouldConvertModules() throws IOException { + File basedir = temp.newFolder(); + MavenProject root = new MavenProject(); - root.setFile(new File("/foo/pom.xml")); + root.setFile(new File(basedir, "pom.xml")); root.getBuild().setDirectory("target"); + root.getBuild().setOutputDirectory("target/classes"); root.getModules().add("module/pom.xml"); MavenProject module = new MavenProject(); - module.setFile(new File("/foo/module/pom.xml")); + module.setFile(new File(basedir, "module/pom.xml")); module.getBuild().setDirectory("target"); + module.getBuild().setOutputDirectory("target/classes"); ProjectDefinition project = MavenProjectConverter.convert(Arrays.asList(root, module), root); assertThat(project.getSubProjects().size(), is(1)); diff --git a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java index 069840eaf86..db80de5c1bf 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/bootstrap/BootstrapContainerTest.java @@ -26,6 +26,7 @@ import org.sonar.api.batch.maven.MavenPluginHandler; import org.sonar.api.resources.Project; import org.sonar.batch.FakeMavenPluginExecutor; import org.sonar.batch.MavenPluginExecutor; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import static org.fest.assertions.Assertions.assertThat; @@ -75,10 +76,10 @@ public class BootstrapContainerTest { } public static class MyMavenPluginExecutor implements MavenPluginExecutor { - public void execute(Project project, ProjectDefinition projectDef, String goal) { + public void execute(Project project, DefaultModuleFileSystem fs, String goal) { } - public MavenPluginHandler execute(Project project, ProjectDefinition projectDef, MavenPluginHandler handler) { + public MavenPluginHandler execute(Project project, DefaultModuleFileSystem fs, MavenPluginHandler handler) { return handler; } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java b/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java index a2a6ce5dc71..b892aa9af66 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java @@ -27,11 +27,11 @@ import org.sonar.api.CoreProperties; import org.sonar.api.batch.SensorContext; import org.sonar.api.config.Settings; import org.sonar.api.platform.Server; -import org.sonar.api.resources.ProjectFileSystem; import org.sonar.api.resources.Resource; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RulePriority; import org.sonar.api.rules.Violation; +import org.sonar.api.scan.filesystem.ModuleFileSystem; import org.sonar.batch.index.DefaultIndex; import org.sonar.core.i18n.RuleI18nManager; import org.sonar.java.api.JavaClass; @@ -55,7 +55,7 @@ public class DryRunExporterTest { SensorContext sensorContext = mock(SensorContext.class); Resource resource = JavaClass.create("KEY"); Violation violation = mock(Violation.class); - ProjectFileSystem projectFileSystem = mock(ProjectFileSystem.class); + ModuleFileSystem fileSystem = mock(ModuleFileSystem.class); Server server = mock(Server.class); RuleI18nManager ruleI18nManager = mock(RuleI18nManager.class); Settings settings; @@ -67,7 +67,7 @@ public class DryRunExporterTest { public void setUp() { settings = new Settings(); settings.setProperty(CoreProperties.DRY_RUN, true); - dryRunExporter = spy(new DryRunExporter(settings, sonarIndex, projectFileSystem, server, ruleI18nManager)); + dryRunExporter = spy(new DryRunExporter(settings, sonarIndex, fileSystem, server, ruleI18nManager)); } @Test @@ -139,7 +139,7 @@ public class DryRunExporterTest { when(server.getVersion()).thenReturn("3.4"); doReturn(Arrays.<Violation>asList()).when(dryRunExporter).getViolations(resource); settings.setProperty("sonar.dryRun.export.path", "output.json"); - when(projectFileSystem.getSonarWorkingDirectory()).thenReturn(sonarDirectory); + when(fileSystem.workingDir()).thenReturn(sonarDirectory); dryRunExporter.execute(sensorContext); diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/MavenPhaseExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/MavenPhaseExecutorTest.java index ea40f8a6ce5..8d185ff0a46 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/phases/MavenPhaseExecutorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/phases/MavenPhaseExecutorTest.java @@ -30,27 +30,28 @@ import org.junit.Test; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.resources.Project; import org.sonar.batch.MavenPluginExecutor; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; public class MavenPhaseExecutorTest { @Test public void doNothingIfNoPhase() { - ProjectDefinition projectDef = ProjectDefinition.create(); + DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class); MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class); - MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(projectDef, mavenPluginExecutor); + MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(fs, mavenPluginExecutor); Project project = new Project("key"); phaseExecutor.execute(project); - verify(mavenPluginExecutor, never()).execute(eq(project), eq(projectDef), anyString()); + verify(mavenPluginExecutor, never()).execute(eq(project), eq(fs), anyString()); } @Test public void executePhase() { - ProjectDefinition projectDef = ProjectDefinition.create(); + DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class); MavenPluginExecutor mavenPluginExecutor = mock(MavenPluginExecutor.class); - MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(projectDef, mavenPluginExecutor); + MavenPhaseExecutor phaseExecutor = new MavenPhaseExecutor(fs, mavenPluginExecutor); Project project = new Project("key"); PropertiesConfiguration conf = new PropertiesConfiguration(); @@ -59,6 +60,6 @@ public class MavenPhaseExecutorTest { phaseExecutor.execute(project); - verify(mavenPluginExecutor).execute(project, projectDef, "myphase"); + verify(mavenPluginExecutor).execute(project, fs, "myphase"); } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/phases/PostJobsExecutorTest.java b/sonar-batch/src/test/java/org/sonar/batch/phases/PostJobsExecutorTest.java index 1af0a26cc9e..dc7eb79101f 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/phases/PostJobsExecutorTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/phases/PostJobsExecutorTest.java @@ -28,6 +28,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.resources.Project; import org.sonar.batch.MavenPluginExecutor; import org.sonar.batch.local.DryRunExporter; +import org.sonar.batch.scan.filesystem.DefaultModuleFileSystem; import java.util.Arrays; @@ -48,7 +49,7 @@ public class PostJobsExecutorTest { @Before public void setUp() { - executor = new PostJobsExecutor(selector, project, ProjectDefinition.create(), mavenPluginExecutor, localModeExporter); + executor = new PostJobsExecutor(selector, project, mock(DefaultModuleFileSystem.class), mavenPluginExecutor, localModeExporter); } @Test diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java index 8d45a5703e6..8646364216a 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/DefaultModuleFileSystemTest.java @@ -28,9 +28,11 @@ import org.sonar.api.resources.AbstractLanguage; import org.sonar.api.resources.Languages; import org.sonar.api.scan.filesystem.FileFilter; import org.sonar.api.scan.filesystem.JavaIoFileFilter; +import org.sonar.api.scan.filesystem.PathResolver; import java.io.File; import java.io.IOException; +import java.util.Arrays; import java.util.List; import static org.fest.assertions.Assertions.assertThat; @@ -184,4 +186,33 @@ public class DefaultModuleFileSystemTest { return new String[]{"java", "jav"}; } } + + @Test + public void test_reset_dirs() throws IOException { + File basedir = temp.newFolder(); + DefaultModuleFileSystem fileSystem = new DefaultModuleFileSystem.Builder() + .baseDir(basedir) + .sourceCharset(Charsets.UTF_8) + .workingDir(basedir) + .addSourceDir(new File(basedir, "src/main/java")) + .addFileFilter(JavaIoFileFilter.create(FileFilterUtils.nameFileFilter("Foo.java"))) + .pathResolver(new PathResolver()) + .build(); + + File existingDir = temp.newFolder("new_folder"); + File notExistingDir = new File(existingDir, "not_exist"); + + fileSystem.resetDirs(existingDir, existingDir, existingDir, + Arrays.asList(existingDir, notExistingDir), Arrays.asList(existingDir, notExistingDir), Arrays.asList(existingDir, notExistingDir)); + + assertThat(fileSystem.baseDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); + assertThat(fileSystem.workingDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); + assertThat(fileSystem.buildDir().getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); + assertThat(fileSystem.sourceDirs()).hasSize(1); + assertThat(fileSystem.sourceDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); + assertThat(fileSystem.testDirs()).hasSize(1); + assertThat(fileSystem.testDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); + assertThat(fileSystem.binaryDirs()).hasSize(1); + assertThat(fileSystem.binaryDirs().get(0).getCanonicalPath()).isEqualTo(existingDir.getCanonicalPath()); + } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFileFilterTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFileFilterTest.java index 13fc2529b11..0bdf7ea726b 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFileFilterTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionFileFilterTest.java @@ -27,6 +27,7 @@ import org.sonar.api.config.Settings; import org.sonar.api.resources.File; import org.sonar.api.resources.JavaFile; import org.sonar.api.scan.filesystem.FileFilter; +import org.sonar.api.scan.filesystem.ModuleExclusions; import org.sonar.api.scan.filesystem.ModuleFileSystem; import java.io.IOException; @@ -42,7 +43,7 @@ public class ExclusionFileFilterTest { public void source_inclusions() throws IOException { Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.java"); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE); context.setFileRelativePath("com/mycompany/Foo.java"); @@ -61,7 +62,7 @@ public class ExclusionFileFilterTest { public void source_exclusions() throws IOException { Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Dao.java"); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); FileFilterContext context = new FileFilterContext(mock(ModuleFileSystem.class), FileFilter.FileType.SOURCE); context.setFileRelativePath("com/mycompany/FooDao.java"); @@ -80,7 +81,7 @@ public class ExclusionFileFilterTest { public void resource_inclusions() throws IOException { Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.c"); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); assertThat(filter.isIgnored(new File("org/sonar", "FooDao.c"))).isFalse(); assertThat(filter.isIgnored(new File("org/sonar", "Foo.c"))).isTrue(); @@ -90,7 +91,7 @@ public class ExclusionFileFilterTest { public void resource_exclusions() throws IOException { Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Dao.c"); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); assertThat(filter.isIgnored(new File("org/sonar", "FooDao.c"))).isTrue(); assertThat(filter.isIgnored(new File("org/sonar", "Foo.c"))).isFalse(); @@ -103,7 +104,7 @@ public class ExclusionFileFilterTest { public void java_resource_inclusions() throws IOException { Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Dao.java"); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); assertThat(filter.isIgnored(new JavaFile("org.sonar", "FooDao"))).isFalse(); assertThat(filter.isIgnored(new JavaFile("org.sonar", "Foo"))).isTrue(); @@ -116,7 +117,7 @@ public class ExclusionFileFilterTest { public void java_resource_exclusions() throws IOException { Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "**/*Dao.java"); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); assertThat(filter.isIgnored(new JavaFile("org.sonar", "FooDao"))).isTrue(); assertThat(filter.isIgnored(new JavaFile("org.sonar", "Foo"))).isFalse(); @@ -129,7 +130,7 @@ public class ExclusionFileFilterTest { settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, "source/exclusions"); settings.setProperty(CoreProperties.PROJECT_TEST_INCLUSIONS_PROPERTY, "test/inclusions"); settings.setProperty(CoreProperties.PROJECT_TEST_EXCLUSIONS_PROPERTY, "test/exclusions"); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); assertThat(filter.sourceInclusions()[0].toString()).isEqualTo("source/inclusions"); assertThat(filter.testInclusions()[0].toString()).isEqualTo("test/inclusions"); @@ -141,7 +142,7 @@ public class ExclusionFileFilterTest { public void should_trim_pattern() throws IOException { Settings settings = new Settings(); settings.setProperty(CoreProperties.PROJECT_EXCLUSIONS_PROPERTY, " **/*Dao.java "); - ExclusionFileFilter filter = new ExclusionFileFilter(settings); + ExclusionFileFilter filter = new ExclusionFileFilter(new ModuleExclusions(settings)); assertThat(filter.sourceExclusions()[0].toString()).isEqualTo("**/*Dao.java"); } diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionPatternsTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionPatternsTest.java deleted file mode 100644 index 230b56c66d5..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ExclusionPatternsTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch.scan.filesystem; - -import org.junit.Test; -import org.sonar.api.CoreProperties; -import org.sonar.api.config.Settings; -import org.sonar.api.utils.WildcardPattern; - -import static org.fest.assertions.Assertions.assertThat; - -public class ExclusionPatternsTest { - @Test - public void ignore_inclusion_of_world() { - Settings settings = new Settings(); - settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*"); - assertThat(ExclusionPatterns.sourceInclusions(settings)).isEmpty(); - } - - @Test - public void load_inclusion() { - Settings settings = new Settings(); - settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "**/*Foo.java"); - WildcardPattern[] inclusions = ExclusionPatterns.sourceInclusions(settings); - - assertThat(inclusions).hasSize(1); - assertThat(inclusions[0].toString()).isEqualTo("**/*Foo.java"); - } -} diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProviderTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProviderTest.java index 5fa1bc1a492..6a406912055 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProviderTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemProviderTest.java @@ -20,6 +20,7 @@ package org.sonar.batch.scan.filesystem; import com.google.common.base.Charsets; +import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -28,6 +29,7 @@ import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.config.Settings; import org.sonar.api.scan.filesystem.FileFilter; import org.sonar.api.scan.filesystem.ModuleFileSystem; +import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.batch.bootstrap.TempDirectories; import java.io.File; @@ -84,6 +86,39 @@ public class ModuleFileSystemProviderTest { assertThat(fs.sourceCharset()).isEqualTo(Charsets.ISO_8859_1); } + @Test + public void test_directories() throws IOException { + ModuleFileSystemProvider provider = new ModuleFileSystemProvider(); + + File baseDir = temp.newFolder("base"); + File buildDir = temp.newFolder("build"); + File sourceDir = new File(baseDir, "src/main/java"); + FileUtils.forceMkdir(sourceDir); + File testDir = new File(baseDir, "src/test/java"); + FileUtils.forceMkdir(testDir); + File binaryDir = new File(baseDir, "target/classes"); + FileUtils.forceMkdir(binaryDir); + + ProjectDefinition project = ProjectDefinition.create() + .setBaseDir(baseDir) + .setBuildDir(buildDir) + .addSourceDirs("src/main/java", "src/main/unknown") + .addTestDirs("src/test/java", "src/test/unknown") + .addBinaryDir("target/classes"); + + ModuleFileSystem fs = provider.provide(project, new PathResolver(), new TempDirectories(), mock(LanguageFileFilters.class), + new Settings(), new FileFilter[0]); + + assertThat(fs.baseDir().getCanonicalPath()).isEqualTo(baseDir.getCanonicalPath()); + assertThat(fs.buildDir().getCanonicalPath()).isEqualTo(buildDir.getCanonicalPath()); + assertThat(fs.sourceDirs()).hasSize(1); + assertThat(fs.sourceDirs().get(0).getCanonicalPath()).endsWith("src/main/java"); + assertThat(fs.testDirs()).hasSize(1); + assertThat(fs.testDirs().get(0).getCanonicalPath()).endsWith("src/test/java"); + assertThat(fs.binaryDirs()).hasSize(1); + assertThat(fs.binaryDirs().get(0).getCanonicalPath()).endsWith("target/classes"); + } + private ProjectDefinition newSimpleModule() { return ProjectDefinition.create() .setBaseDir(temp.newFolder("base")); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java deleted file mode 100644 index 8515aa7a9f7..00000000000 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/PathResolverTest.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Sonar, open source software quality management tool. - * Copyright (C) 2008-2012 SonarSource - * mailto:contact AT sonarsource DOT com - * - * Sonar 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. - * - * Sonar 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 Sonar; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 - */ -package org.sonar.batch.scan.filesystem; - -import org.apache.commons.io.FilenameUtils; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; - -import java.io.File; -import java.io.IOException; -import java.util.Arrays; -import java.util.List; - -import static org.fest.assertions.Assertions.assertThat; - -public class PathResolverTest { - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - @Test - public void get_file_by_relative_path() throws IOException { - PathResolver resolver = new PathResolver(); - File rootDir = temp.newFolder(); - File file = resolver.relativeFile(rootDir, "org/foo/Bar.java"); - assertThat(file.getName()).isEqualTo("Bar.java"); - assertThat(FilenameUtils.separatorsToUnix(file.getCanonicalPath())).endsWith("org/foo/Bar.java"); - assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath()); - } - - @Test - public void get_file_by_absolute_path() throws IOException { - PathResolver resolver = new PathResolver(); - File rootDir = temp.newFolder(); - File file = resolver.relativeFile(rootDir, new File(rootDir, "org/foo/Bar.java").getAbsolutePath()); - assertThat(file.getName()).isEqualTo("Bar.java"); - assertThat(FilenameUtils.separatorsToUnix(file.getCanonicalPath())).endsWith("org/foo/Bar.java"); - assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath()); - } - - @Test - public void get_files_by_relative_paths() throws IOException { - PathResolver resolver = new PathResolver(); - File rootDir = temp.newFolder(); - List<File> files = resolver.relativeFiles(rootDir, Arrays.asList("org/foo/Bar.java", "org/hello/World.java")); - assertThat(files).hasSize(2); - for (File file : files) { - assertThat(file.getName()).endsWith(".java"); - assertThat(file.getParentFile().getParentFile().getParentFile().getCanonicalPath()).isEqualTo(rootDir.getCanonicalPath()); - } - } - - @Test - public void get_relative_path() throws IOException { - PathResolver resolver = new PathResolver(); - File rootDir = temp.newFolder(); - File org = new File(rootDir, "org"); - File hello = new File(org, "hello"); - File world = new File(hello, "World.java"); - - assertThat(resolver.relativePath(rootDir, world)).isEqualTo("org/hello/World.java"); - } - - @Test - public void null_relative_path_when_file_is_not_in_dir() throws IOException { - PathResolver resolver = new PathResolver(); - File rootDir = temp.newFolder(); - - assertThat(resolver.relativePath(rootDir, new File("Elsewhere.java"))).isNull(); - } -} diff --git a/sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt b/sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt deleted file mode 100644 index f0f877cedcc..00000000000 --- a/sonar-batch/src/test/resources/org/sonar/batch/DefaultProjectFileSystem2Test/shouldIgnoreInexistingSourceDirs/fake.txt +++ /dev/null @@ -1 +0,0 @@ -fake
\ No newline at end of file |