From f280711447aef1c46827208bb999e480f68a340c Mon Sep 17 00:00:00 2001 From: Julien HENRY Date: Thu, 3 Jul 2014 17:31:17 +0200 Subject: [PATCH] SONAR-5419 sonar.sources and sonar.tests should support a mixed list of files and folders --- .../mediumtest/AnalyzerMediumTester.java | 12 + .../batch/scan/ProjectReactorBuilder.java | 25 +- .../filesystem/DefaultModuleFileSystem.java | 61 ++--- .../batch/scan/filesystem/FileIndexer.java | 42 ++-- .../ModuleFileSystemInitializer.java | 40 ++- .../mediumtest/fs/FileSystemMediumTest.java | 144 +++++++++++ .../mediumtest/issues/IssuesMediumTest.java | 126 ++++++++++ .../MeasuresMediumTest.java} | 42 +--- .../DefaultModuleFileSystemTest.java | 16 +- .../ModuleFileSystemInitializerTest.java | 12 +- .../batch/bootstrap/ProjectDefinition.java | 228 +++++++++++++----- 11 files changed, 564 insertions(+), 184 deletions(-) create mode 100644 sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java create mode 100644 sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java rename sonar-batch/src/test/java/org/sonar/batch/mediumtest/{xoo/XooMediumTest.java => measures/MeasuresMediumTest.java} (75%) diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/AnalyzerMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/AnalyzerMediumTester.java index c597e96d29c..a141d3c83c4 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/AnalyzerMediumTester.java +++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/AnalyzerMediumTester.java @@ -28,6 +28,7 @@ import org.sonar.api.SonarPlugin; import org.sonar.api.batch.analyzer.issue.AnalyzerIssue; import org.sonar.api.batch.analyzer.measure.AnalyzerMeasure; import org.sonar.api.batch.debt.internal.DefaultDebtModel; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.rule.internal.RulesBuilder; import org.sonar.api.measures.CoreMetrics; @@ -45,6 +46,7 @@ import org.sonar.batch.languages.Language; import org.sonar.batch.languages.LanguagesReferential; import org.sonar.batch.rule.QProfile; import org.sonar.batch.rules.QProfilesReferential; +import org.sonar.batch.scan.filesystem.InputFileCache; import org.sonar.batch.scan2.AnalyzerIssueCache; import org.sonar.batch.scan2.AnalyzerMeasureCache; import org.sonar.batch.scan2.ProjectScanContainer; @@ -227,6 +229,7 @@ public class AnalyzerMediumTester { public static class TaskResult implements ScanTaskObserver { private List issues = new ArrayList(); private List measures = new ArrayList(); + private List inputFiles = new ArrayList(); @Override public void scanTaskCompleted(ProjectScanContainer container) { @@ -237,6 +240,11 @@ public class AnalyzerMediumTester { for (AnalyzerMeasure measure : container.getComponentByType(AnalyzerMeasureCache.class).all()) { measures.add(measure); } + + InputFileCache inputFileCache = container.getComponentByType(InputFileCache.class); + for (InputFile inputFile : inputFileCache.all()) { + inputFiles.add(inputFile); + } } public List issues() { @@ -247,6 +255,10 @@ public class AnalyzerMediumTester { return measures; } + public List inputFiles() { + return inputFiles; + } + } private static class FakeSettingsReferential implements SettingsReferential { diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java index 027abd427eb..68f62cf4e98 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/ProjectReactorBuilder.java @@ -304,8 +304,8 @@ public class ProjectReactorBuilder { } // Check sonar.tests - String[] testDirs = getListFromProperty(props, PROPERTY_TESTS); - checkExistenceOfDirectories(projectId, baseDir, testDirs, PROPERTY_TESTS); + String[] testPaths = getListFromProperty(props, PROPERTY_TESTS); + checkExistenceOfPaths(projectId, baseDir, testPaths, PROPERTY_TESTS); // Check sonar.binaries String[] binDirs = getListFromProperty(props, PROPERTY_BINARIES); @@ -332,8 +332,8 @@ public class ProjectReactorBuilder { Properties properties = project.getProperties(); // We need to check the existence of source directories - String[] sourceDirs = getListFromProperty(properties, PROPERTY_SOURCES); - checkExistenceOfDirectories(project.getKey(), project.getBaseDir(), sourceDirs, PROPERTY_SOURCES); + String[] sourcePaths = getListFromProperty(properties, PROPERTY_SOURCES); + checkExistenceOfPaths(project.getKey(), project.getBaseDir(), sourcePaths, PROPERTY_SOURCES); // And we need to resolve patterns that may have been used in "sonar.libraries" List libPaths = Lists.newArrayList(); @@ -415,8 +415,8 @@ public class ProjectReactorBuilder { } @VisibleForTesting - protected static void checkExistenceOfDirectories(String moduleRef, File baseDir, String[] sourceDirs, String propName) { - for (String path : sourceDirs) { + protected static void checkExistenceOfDirectories(String moduleRef, File baseDir, String[] dirPaths, String propName) { + for (String path : dirPaths) { File sourceFolder = resolvePath(baseDir, path); if (!sourceFolder.isDirectory()) { LOG.error(MessageFormat.format(INVALID_VALUE_OF_X_FOR_Y, propName, moduleRef)); @@ -427,6 +427,19 @@ public class ProjectReactorBuilder { } + @VisibleForTesting + protected static void checkExistenceOfPaths(String moduleRef, File baseDir, String[] paths, String propName) { + for (String path : paths) { + File sourceFolder = resolvePath(baseDir, path); + if (!sourceFolder.exists()) { + LOG.error(MessageFormat.format(INVALID_VALUE_OF_X_FOR_Y, propName, moduleRef)); + throw new IllegalStateException("The folder '" + path + "' does not exist for '" + moduleRef + + "' (base directory = " + baseDir.getAbsolutePath() + ")"); + } + } + + } + /** * Returns files matching specified pattern. */ 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 0e534a334f9..2706e54731f 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 @@ -41,6 +41,7 @@ import javax.annotation.Nullable; import java.io.File; import java.nio.charset.Charset; +import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; @@ -59,11 +60,9 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module private final Settings settings; private File buildDir; - private List sourceDirs = Lists.newArrayList(); - private List testDirs = Lists.newArrayList(); + private List sourceDirsOrFiles = Lists.newArrayList(); + private List testDirsOrFiles = Lists.newArrayList(); private List binaryDirs = Lists.newArrayList(); - private List sourceFiles = Lists.newArrayList(); - private List testFiles = Lists.newArrayList(); private ComponentIndexer componentIndexer; private boolean initialized; @@ -71,19 +70,19 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module * Used by scan2 */ public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, ProjectDefinition def, Settings settings, - FileIndexer indexer, ModuleFileSystemInitializer initializer) { + FileIndexer indexer, ModuleFileSystemInitializer initializer) { this(moduleInputFileCache, def.getKey(), settings, indexer, initializer, null); } public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, ProjectDefinition def, Project project, - Settings settings, FileIndexer indexer, + Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer) { this(moduleInputFileCache, project.getKey(), settings, indexer, initializer, componentIndexer); } private DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, String moduleKey, Settings settings, - FileIndexer indexer, ModuleFileSystemInitializer initializer, + FileIndexer indexer, ModuleFileSystemInitializer initializer, @Nullable ComponentIndexer componentIndexer) { super(moduleInputFileCache); this.componentIndexer = componentIndexer; @@ -95,11 +94,9 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module } setWorkDir(initializer.workingDir()); this.buildDir = initializer.buildDir(); - this.sourceDirs = initializer.sourceDirs(); - this.testDirs = initializer.testDirs(); + this.sourceDirsOrFiles = initializer.sources(); + this.testDirsOrFiles = initializer.tests(); this.binaryDirs = initializer.binaryDirs(); - this.sourceFiles = initializer.additionalSourceFiles(); - this.testFiles = initializer.additionalTestFiles(); } public boolean isInitialized() { @@ -118,25 +115,35 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module @Override public List sourceDirs() { - return sourceDirs; + return keepOnlyDirs(sourceDirsOrFiles); + } + + public List sources() { + return sourceDirsOrFiles; } @Override public List testDirs() { - return testDirs; + return keepOnlyDirs(testDirsOrFiles); } - @Override - public List binaryDirs() { - return binaryDirs; + public List tests() { + return testDirsOrFiles; } - List sourceFiles() { - return sourceFiles; + private List keepOnlyDirs(List dirsOrFiles) { + List result = new ArrayList(); + for (File f : dirsOrFiles) { + if (f.isDirectory()) { + result.add(f); + } + } + return result; } - List testFiles() { - return testFiles; + @Override + public List binaryDirs() { + return binaryDirs; } @Override @@ -223,9 +230,9 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module } setBaseDir(basedir); this.buildDir = buildDir; - this.sourceDirs = existingDirs(sourceDirs); - this.testDirs = existingDirs(testDirs); - this.binaryDirs = existingDirs(binaryDirs); + this.sourceDirsOrFiles = existingDirsOrFiles(sourceDirs); + this.testDirsOrFiles = existingDirsOrFiles(testDirs); + this.binaryDirs = existingDirsOrFiles(binaryDirs); } public void index() { @@ -239,11 +246,11 @@ public class DefaultModuleFileSystem extends DefaultFileSystem implements Module } } - private List existingDirs(List dirs) { + private List existingDirsOrFiles(List dirsOrFiles) { ImmutableList.Builder builder = ImmutableList.builder(); - for (File dir : dirs) { - if (dir.exists() && dir.isDirectory()) { - builder.add(dir); + for (File dirOrFile : dirsOrFiles) { + if (dirOrFile.exists()) { + builder.add(dirOrFile); } } return builder.build(); diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java index f63ce8e80d9..81eb9b0e4da 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/FileIndexer.java @@ -87,19 +87,8 @@ public class FileIndexer implements BatchComponent { executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() + 1); InputFileBuilder inputFileBuilder = inputFileBuilderFactory.create(fileSystem); - if (!fileSystem.sourceFiles().isEmpty() || !fileSystem.testFiles().isEmpty()) { - // Index only provided files - indexFiles(inputFileBuilder, fileSystem, progress, fileSystem.sourceFiles(), InputFile.Type.MAIN); - indexFiles(inputFileBuilder, fileSystem, progress, fileSystem.testFiles(), InputFile.Type.TEST); - } else { - for (File mainDir : fileSystem.sourceDirs()) { - indexDirectory(inputFileBuilder, fileSystem, progress, mainDir, InputFile.Type.MAIN); - } - for (File testDir : fileSystem.testDirs()) { - indexDirectory(inputFileBuilder, fileSystem, progress, testDir, InputFile.Type.TEST); - } - - } + indexFiles(fileSystem, progress, inputFileBuilder, fileSystem.sources(), InputFile.Type.MAIN); + indexFiles(fileSystem, progress, inputFileBuilder, fileSystem.tests(), InputFile.Type.TEST); executor.shutdown(); try { @@ -122,22 +111,33 @@ public class FileIndexer implements BatchComponent { } + private void indexFiles(DefaultModuleFileSystem fileSystem, Progress progress, InputFileBuilder inputFileBuilder, List sources, InputFile.Type type) { + for (File dirOrFile : sources) { + if (dirOrFile.isDirectory()) { + indexDirectory(inputFileBuilder, fileSystem, progress, dirOrFile, type); + } else { + indexFile(inputFileBuilder, fileSystem, progress, dirOrFile, type); + } + } + } + private void indexFiles(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress progress, List sourceFiles, InputFile.Type type) { for (File sourceFile : sourceFiles) { - DeprecatedDefaultInputFile inputFile = inputFileBuilder.create(sourceFile); - if (inputFile != null && exclusionFilters.accept(inputFile, type)) { - indexFile(inputFileBuilder, fileSystem, progress, inputFile, type); - } + indexFile(inputFileBuilder, fileSystem, progress, sourceFile, type); } } private void indexDirectory(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress status, File dirToIndex, InputFile.Type type) { Collection files = FileUtils.listFiles(dirToIndex, FILE_FILTER, DIR_FILTER); for (File file : files) { - DeprecatedDefaultInputFile inputFile = inputFileBuilder.create(file); - if (inputFile != null && exclusionFilters.accept(inputFile, type)) { - indexFile(inputFileBuilder, fileSystem, status, inputFile, type); - } + indexFile(inputFileBuilder, fileSystem, status, file, type); + } + } + + private void indexFile(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress progress, File sourceFile, InputFile.Type type) { + DeprecatedDefaultInputFile inputFile = inputFileBuilder.create(sourceFile); + if (inputFile != null && exclusionFilters.accept(inputFile, type)) { + indexFile(inputFileBuilder, fileSystem, progress, inputFile, type); } } diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializer.java b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializer.java index 5f9d1081ac9..fa79c8e682d 100644 --- a/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializer.java +++ b/sonar-batch/src/main/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializer.java @@ -35,11 +35,9 @@ import java.util.List; public class ModuleFileSystemInitializer implements BatchComponent { private File baseDir, workingDir, buildDir; - private List sourceDirs = Lists.newArrayList(); - private List testDirs = Lists.newArrayList(); + private List sourceDirsOrFiles = Lists.newArrayList(); + private List testDirsOrFiles = Lists.newArrayList(); private List binaryDirs = Lists.newArrayList(); - private List additionalSourceFiles; - private List additionalTestFiles; public ModuleFileSystemInitializer(ProjectDefinition module, TempFolder tempUtils, PathResolver pathResolver) { baseDir = module.getBaseDir(); @@ -64,23 +62,21 @@ public class ModuleFileSystemInitializer implements BatchComponent { } private void initSources(ProjectDefinition module, PathResolver pathResolver) { - for (String sourcePath : module.getSourceDirs()) { - File dir = pathResolver.relativeFile(module.getBaseDir(), sourcePath); - if (dir.isDirectory() && dir.exists()) { - sourceDirs.add(dir); + for (String sourcePath : module.sources()) { + File dirOrFile = pathResolver.relativeFile(module.getBaseDir(), sourcePath); + if (dirOrFile.exists()) { + sourceDirsOrFiles.add(dirOrFile); } } - additionalSourceFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getSourceFiles()); } private void initTests(ProjectDefinition module, PathResolver pathResolver) { - for (String testPath : module.getTestDirs()) { - File dir = pathResolver.relativeFile(module.getBaseDir(), testPath); - if (dir.exists() && dir.isDirectory()) { - testDirs.add(dir); + for (String testPath : module.tests()) { + File dirOrFile = pathResolver.relativeFile(module.getBaseDir(), testPath); + if (dirOrFile.exists()) { + testDirsOrFiles.add(dirOrFile); } } - additionalTestFiles = pathResolver.relativeFiles(module.getBaseDir(), module.getTestFiles()); } private void initBinaryDirs(ProjectDefinition module, PathResolver pathResolver) { @@ -102,23 +98,15 @@ public class ModuleFileSystemInitializer implements BatchComponent { return buildDir; } - List sourceDirs() { - return sourceDirs; + List sources() { + return sourceDirsOrFiles; } - List testDirs() { - return testDirs; + List tests() { + return testDirsOrFiles; } List binaryDirs() { return binaryDirs; } - - List additionalSourceFiles() { - return additionalSourceFiles; - } - - List additionalTestFiles() { - return additionalTestFiles; - } } diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java new file mode 100644 index 00000000000..aafeada87cf --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/fs/FileSystemMediumTest.java @@ -0,0 +1,144 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 02110-1301, USA. + */ +package org.sonar.batch.mediumtest.fs; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.rule.RuleKey; +import org.sonar.batch.mediumtest.AnalyzerMediumTester; +import org.sonar.batch.mediumtest.AnalyzerMediumTester.TaskResult; +import org.sonar.batch.mediumtest.xoo.plugin.XooPlugin; +import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo; + +import java.io.File; +import java.io.IOException; + +import static org.fest.assertions.Assertions.assertThat; + +public class FileSystemMediumTest { + + @org.junit.Rule + public TemporaryFolder temp = new TemporaryFolder(); + + public AnalyzerMediumTester tester = AnalyzerMediumTester.builder() + .registerPlugin("xoo", new XooPlugin()) + .registerLanguage(new Xoo()) + .addDefaultQProfile("xoo", "Sonar Way") + .activateRule(RuleKey.of("xoo", "OneIssuePerLine")) + .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) + .build(); + + private File baseDir; + + private ImmutableMap.Builder builder; + + @Before + public void prepare() throws IOException { + tester.start(); + + baseDir = temp.newFolder(); + + builder = ImmutableMap.builder() + .put("sonar.task", "scan") + .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) + .put("sonar.projectKey", "com.foo.project") + .put("sonar.projectName", "Foo Project") + .put("sonar.projectVersion", "1.0-SNAPSHOT") + .put("sonar.projectDescription", "Description of Foo Project"); + } + + @After + public void stop() { + tester.stop(); + } + + @Test + public void scanProjectWithSourceDir() throws IOException { + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + FileUtils.write(xooFile, "Sample xoo\ncontent"); + + TaskResult result = tester.newTask() + .properties(builder + .put("sonar.sources", "src") + .build()) + .start(); + + assertThat(result.inputFiles()).hasSize(1); + assertThat(result.inputFiles().get(0).type()).isEqualTo(InputFile.Type.MAIN); + } + + @Test + public void scanProjectWithTestDir() throws IOException { + File test = new File(baseDir, "test"); + test.mkdir(); + + File xooFile = new File(test, "sampleTest.xoo"); + FileUtils.write(xooFile, "Sample test xoo\ncontent"); + + TaskResult result = tester.newTask() + .properties(builder + .put("sonar.sources", "") + .put("sonar.tests", "test") + .build()) + .start(); + + assertThat(result.inputFiles()).hasSize(1); + assertThat(result.inputFiles().get(0).type()).isEqualTo(InputFile.Type.TEST); + } + + @Test + public void scanProjectWithMixedSourcesAndTests() throws IOException { + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + FileUtils.write(xooFile, "Sample xoo\ncontent"); + + File xooFile2 = new File(baseDir, "another.xoo"); + FileUtils.write(xooFile2, "Sample xoo 2\ncontent"); + + File testDir = new File(baseDir, "test"); + testDir.mkdir(); + + File xooTestFile = new File(baseDir, "sampleTest2.xoo"); + FileUtils.write(xooTestFile, "Sample test xoo\ncontent"); + + File xooTestFile2 = new File(testDir, "sampleTest.xoo"); + FileUtils.write(xooTestFile2, "Sample test xoo 2\ncontent"); + + TaskResult result = tester.newTask() + .properties(builder + .put("sonar.sources", "src,another.xoo") + .put("sonar.tests", "test,sampleTest2.xoo") + .build()) + .start(); + + assertThat(result.inputFiles()).hasSize(4); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java new file mode 100644 index 00000000000..75663d74382 --- /dev/null +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/issues/IssuesMediumTest.java @@ -0,0 +1,126 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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 02110-1301, USA. + */ +package org.sonar.batch.mediumtest.issues; + +import com.google.common.collect.ImmutableMap; +import org.apache.commons.io.FileUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.analyzer.issue.AnalyzerIssue; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.rule.RuleKey; +import org.sonar.batch.mediumtest.AnalyzerMediumTester; +import org.sonar.batch.mediumtest.AnalyzerMediumTester.TaskResult; +import org.sonar.batch.mediumtest.xoo.plugin.XooPlugin; +import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo; + +import java.io.File; +import java.io.IOException; + +import static org.fest.assertions.Assertions.assertThat; + +public class IssuesMediumTest { + + @org.junit.Rule + public TemporaryFolder temp = new TemporaryFolder(); + + public AnalyzerMediumTester tester = AnalyzerMediumTester.builder() + .registerPlugin("xoo", new XooPlugin()) + .registerLanguage(new Xoo()) + .addDefaultQProfile("xoo", "Sonar Way") + .activateRule(RuleKey.of("xoo", "OneIssuePerLine")) + .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) + .build(); + + @Before + public void prepare() { + tester.start(); + } + + @After + public void stop() { + tester.stop(); + } + + @Test + public void scanSampleProject() throws Exception { + File projectDir = new File(IssuesMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + + TaskResult result = tester + .newScanTask(new File(projectDir, "sonar-project.properties")) + .start(); + + assertThat(result.issues()).hasSize(24); + } + + @Test + public void testIssueExclusion() throws Exception { + File projectDir = new File(IssuesMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + + TaskResult result = tester + .newScanTask(new File(projectDir, "sonar-project.properties")) + .property("sonar.issue.ignore.allfile", "1") + .property("sonar.issue.ignore.allfile.1.fileRegexp", "object") + .start(); + + assertThat(result.issues()).hasSize(19); + } + + @Test + public void scanTempProject() throws IOException { + + File baseDir = temp.newFolder(); + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + File xooMeasureFile = new File(srcDir, "sample.xoo.measures"); + FileUtils.write(xooFile, "Sample xoo\ncontent"); + FileUtils.write(xooMeasureFile, "lines:20"); + + TaskResult result = tester.newTask() + .properties(ImmutableMap.builder() + .put("sonar.task", "scan") + .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) + .put("sonar.projectKey", "com.foo.project") + .put("sonar.projectName", "Foo Project") + .put("sonar.projectVersion", "1.0-SNAPSHOT") + .put("sonar.projectDescription", "Description of Foo Project") + .put("sonar.sources", "src") + .build()) + .start(); + + assertThat(result.issues()).hasSize(20); + + boolean foundIssueAtLine1 = false; + for (AnalyzerIssue issue : result.issues()) { + if (issue.line() == 1) { + foundIssueAtLine1 = true; + assertThat(issue.inputFile()).isEqualTo(new DefaultInputFile("src/sample.xoo")); + assertThat(issue.message()).isEqualTo("This issue is generated on each line"); + assertThat(issue.effortToFix()).isNull(); + } + } + assertThat(foundIssueAtLine1).isTrue(); + } + +} diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/XooMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java similarity index 75% rename from sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/XooMediumTest.java rename to sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java index 14a22cbb14c..017f530d521 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/XooMediumTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/measures/MeasuresMediumTest.java @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -package org.sonar.batch.mediumtest.xoo; +package org.sonar.batch.mediumtest.measures; import com.google.common.collect.ImmutableMap; import org.apache.commons.io.FileUtils; @@ -25,11 +25,9 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.analyzer.issue.AnalyzerIssue; import org.sonar.api.batch.analyzer.measure.internal.DefaultAnalyzerMeasureBuilder; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.measures.CoreMetrics; -import org.sonar.api.rule.RuleKey; import org.sonar.batch.mediumtest.AnalyzerMediumTester; import org.sonar.batch.mediumtest.AnalyzerMediumTester.TaskResult; import org.sonar.batch.mediumtest.xoo.plugin.XooPlugin; @@ -40,17 +38,15 @@ import java.io.IOException; import static org.fest.assertions.Assertions.assertThat; -public class XooMediumTest { +public class MeasuresMediumTest { @org.junit.Rule public TemporaryFolder temp = new TemporaryFolder(); public AnalyzerMediumTester tester = AnalyzerMediumTester.builder() - // .registerPlugin("xoo", new File("target/sonar-xoo-plugin-2.0-SNAPSHOT.jar")) .registerPlugin("xoo", new XooPlugin()) .registerLanguage(new Xoo()) .addDefaultQProfile("xoo", "Sonar Way") - .activateRule(RuleKey.of("xoo", "OneIssuePerLine")) .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor")) .build(); @@ -65,33 +61,18 @@ public class XooMediumTest { } @Test - public void mediumTestOfSampleProject() throws Exception { - File projectDir = new File(XooMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); + public void computeMeasuresOnSampleProject() throws Exception { + File projectDir = new File(MeasuresMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); TaskResult result = tester .newScanTask(new File(projectDir, "sonar-project.properties")) .start(); assertThat(result.measures()).hasSize(19); - assertThat(result.issues()).hasSize(24); } @Test - public void testIssueExclusion() throws Exception { - File projectDir = new File(XooMediumTest.class.getResource("/mediumtest/xoo/sample").toURI()); - - TaskResult result = tester - .newScanTask(new File(projectDir, "sonar-project.properties")) - .property("sonar.issue.ignore.allfile", "1") - .property("sonar.issue.ignore.allfile.1.fileRegexp", "object") - .start(); - - assertThat(result.measures()).hasSize(19); - assertThat(result.issues()).hasSize(19); - } - - @Test - public void testMeasuresAndIssues() throws IOException { + public void computeMeasuresOnTempProject() throws IOException { File baseDir = temp.newFolder(); File srcDir = new File(baseDir, "src"); @@ -115,7 +96,6 @@ public class XooMediumTest { .start(); assertThat(result.measures()).hasSize(1); - assertThat(result.issues()).hasSize(20); assertThat(result.measures()).contains(new DefaultAnalyzerMeasureBuilder() .forMetric(CoreMetrics.LINES) @@ -123,20 +103,10 @@ public class XooMediumTest { .withValue(20) .build()); - boolean foundIssueAtLine1 = false; - for (AnalyzerIssue issue : result.issues()) { - if (issue.line() == 1) { - foundIssueAtLine1 = true; - assertThat(issue.inputFile()).isEqualTo(new DefaultInputFile("src/sample.xoo")); - assertThat(issue.message()).isEqualTo("This issue is generated on each line"); - assertThat(issue.effortToFix()).isNull(); - } - } - assertThat(foundIssueAtLine1).isTrue(); } @Test - public void testScmActivityAnalyzer() throws IOException { + public void testDistributionMeasure() throws IOException { File baseDir = temp.newFolder(); File srcDir = new File(baseDir, "src"); 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 0de8ac80c56..4d87aed7cd3 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 @@ -111,10 +111,14 @@ public class DefaultModuleFileSystemTest { when(initializer.buildDir()).thenReturn(buildDir); when(initializer.workingDir()).thenReturn(workingDir); when(initializer.binaryDirs()).thenReturn(Arrays.asList(new File(basedir, "target/classes"))); - when(initializer.sourceDirs()).thenReturn(Arrays.asList(new File(basedir, "src/main/java"), new File(basedir, "src/main/groovy"))); - when(initializer.testDirs()).thenReturn(Arrays.asList(new File(basedir, "src/test/java"))); - when(initializer.additionalSourceFiles()).thenReturn(Arrays.asList(additionalFile)); - when(initializer.additionalTestFiles()).thenReturn(Arrays.asList(additionalTest)); + File javaSrc = new File(basedir, "src/main/java"); + javaSrc.mkdirs(); + File groovySrc = new File(basedir, "src/main/groovy"); + groovySrc.mkdirs(); + when(initializer.sources()).thenReturn(Arrays.asList(javaSrc, groovySrc, additionalFile)); + File javaTest = new File(basedir, "src/test/java"); + javaTest.mkdirs(); + when(initializer.tests()).thenReturn(Arrays.asList(javaTest, additionalTest)); DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); @@ -125,8 +129,6 @@ public class DefaultModuleFileSystemTest { assertThat(fs.sourceDirs()).hasSize(2); assertThat(fs.testDirs()).hasSize(1); assertThat(fs.binaryDirs()).hasSize(1); - assertThat(fs.sourceFiles()).containsOnly(additionalFile); - assertThat(fs.testFiles()).containsOnly(additionalTest); } @Test @@ -134,7 +136,7 @@ public class DefaultModuleFileSystemTest { File basedir = temp.newFolder(); when(initializer.baseDir()).thenReturn(basedir); when(initializer.workingDir()).thenReturn(basedir); - when(initializer.sourceDirs()).thenReturn(Arrays.asList(new File(basedir, "src/main/java"))); + when(initializer.sources()).thenReturn(Arrays.asList(new File(basedir, "src/main/java"))); DefaultModuleFileSystem fs = new DefaultModuleFileSystem(moduleInputFileCache, ProjectDefinition.create(), new Project("foo"), settings, fileIndexer, initializer, componentIndexer); diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializerTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializerTest.java index 21e6203d565..78868ef607c 100644 --- a/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializerTest.java +++ b/sonar-batch/src/test/java/org/sonar/batch/scan/filesystem/ModuleFileSystemInitializerTest.java @@ -51,8 +51,8 @@ public class ModuleFileSystemInitializerTest { assertThat(initializer.baseDir().getCanonicalPath()).isEqualTo(baseDir.getCanonicalPath()); assertThat(initializer.workingDir().getCanonicalPath()).isEqualTo(workDir.getCanonicalPath()); - assertThat(initializer.sourceDirs()).isEmpty(); - assertThat(initializer.testDirs()).isEmpty(); + assertThat(initializer.sources()).isEmpty(); + assertThat(initializer.tests()).isEmpty(); } @Test @@ -77,10 +77,10 @@ public class ModuleFileSystemInitializerTest { assertThat(initializer.baseDir().getCanonicalPath()).isEqualTo(baseDir.getCanonicalPath()); assertThat(initializer.buildDir().getCanonicalPath()).isEqualTo(buildDir.getCanonicalPath()); - assertThat(initializer.sourceDirs()).hasSize(1); - assertThat(path(initializer.sourceDirs().get(0))).endsWith("src/main/java"); - assertThat(initializer.testDirs()).hasSize(1); - assertThat(path(initializer.testDirs().get(0))).endsWith("src/test/java"); + assertThat(initializer.sources()).hasSize(1); + assertThat(path(initializer.sources().get(0))).endsWith("src/main/java"); + assertThat(initializer.tests()).hasSize(1); + assertThat(path(initializer.tests().get(0))).endsWith("src/test/java"); assertThat(initializer.binaryDirs()).hasSize(1); assertThat(path(initializer.binaryDirs().get(0))).endsWith("target/classes"); } diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java index 62c4da3d653..b228e383421 100644 --- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java +++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/bootstrap/ProjectDefinition.java @@ -39,9 +39,28 @@ import java.util.Properties; */ public class ProjectDefinition { - public static final String SOURCE_DIRS_PROPERTY = "sonar.sources"; + public static final String SOURCES_PROPERTY = "sonar.sources"; + /** + * @deprecated since 4.5 use {@link #SOURCES_PROPERTY} + */ + @Deprecated + public static final String SOURCE_DIRS_PROPERTY = SOURCES_PROPERTY; + /** + * @deprecated since 4.5 use {@link #SOURCES_PROPERTY} + */ + @Deprecated public static final String SOURCE_FILES_PROPERTY = "sonar.sourceFiles"; - public static final String TEST_DIRS_PROPERTY = "sonar.tests"; + + public static final String TESTS_PROPERTY = "sonar.tests"; + /** + * @deprecated since 4.5 use {@link #TESTS_PROPERTY} + */ + @Deprecated + public static final String TEST_DIRS_PROPERTY = TESTS_PROPERTY; + /** + * @deprecated since 4.5 use {@link #TESTS_PROPERTY} + */ + @Deprecated public static final String TEST_FILES_PROPERTY = "sonar.testFiles"; public static final String BINARIES_PROPERTY = "sonar.binaries"; public static final String LIBRARIES_PROPERTY = "sonar.libraries"; @@ -167,39 +186,94 @@ public class ProjectDefinition { properties.put(key, newValue); } - public List getSourceDirs() { - String sources = properties.getProperty(SOURCE_DIRS_PROPERTY, ""); + /** + * @return Source files and folders. + */ + public List sources() { + String sources = properties.getProperty(SOURCES_PROPERTY, ""); return trim(StringUtils.split(sources, SEPARATOR)); } /** - * @param paths paths to directory with main sources. + * @deprecated since 4.5 use {@link #sources()} + */ + @Deprecated + public List getSourceDirs() { + return sources(); + } + + /** + * @param paths paths to file or directory with main sources. * They can be absolute or relative to project base directory. */ - public ProjectDefinition addSourceDirs(String... paths) { + public ProjectDefinition addSources(String... paths) { for (String path : paths) { - appendProperty(SOURCE_DIRS_PROPERTY, path); + appendProperty(SOURCES_PROPERTY, path); } return this; } - public ProjectDefinition addSourceDirs(File... dirs) { - for (File dir : dirs) { - addSourceDirs(dir.getAbsolutePath()); + /** + * @deprecated since 4.5 use {@link #addSources(String...)} + */ + @Deprecated + public ProjectDefinition addSourceDirs(String... paths) { + return addSources(paths); + } + + public ProjectDefinition addSources(File... fileOrDirs) { + for (File fileOrDir : fileOrDirs) { + addSources(fileOrDir.getAbsolutePath()); } return this; } - public ProjectDefinition resetSourceDirs() { - properties.remove(SOURCE_DIRS_PROPERTY); + /** + * @deprecated since 4.5 use {@link #addSources(File...)} + */ + @Deprecated + public ProjectDefinition addSourceDirs(File... dirs) { + return addSources(dirs); + } + + public ProjectDefinition resetSources() { + properties.remove(SOURCES_PROPERTY); return this; } + /** + * @deprecated since 4.5 use {@link #resetSources()} + */ + @Deprecated + public ProjectDefinition resetSourceDirs() { + return resetSources(); + } + + public ProjectDefinition setSources(String... paths) { + resetSources(); + return addSources(paths); + } + + /** + * @deprecated since 4.5 use {@link #setSources(String...)} + */ + @Deprecated public ProjectDefinition setSourceDirs(String... paths) { - resetSourceDirs(); - return addSourceDirs(paths); + return setSources(paths); } + public ProjectDefinition setSources(File... filesOrDirs) { + resetSources(); + for (File fileOrDir : filesOrDirs) { + addSources(fileOrDir.getAbsolutePath()); + } + return this; + } + + /** + * @deprecated since 4.5 use {@link #setSources(File...)} + */ + @Deprecated public ProjectDefinition setSourceDirs(File... dirs) { resetSourceDirs(); for (File dir : dirs) { @@ -209,96 +283,140 @@ public class ProjectDefinition { } /** - * Adding source files is possible only if no source directories have been set. - * Absolute path or relative path from project base dir. + * @deprecated since 4.5 use {@link #addSources(File...)} */ + @Deprecated public ProjectDefinition addSourceFiles(String... paths) { - for (String path : paths) { - appendProperty(SOURCE_FILES_PROPERTY, path); - } - return this; + return addSources(paths); } /** - * Adding source files is possible only if no source directories have been set. + * @deprecated since 4.5 use {@link #addSources(File...)} */ + @Deprecated public ProjectDefinition addSourceFiles(File... files) { - for (File file : files) { - addSourceFiles(file.getAbsolutePath()); - } - return this; + return addSources(files); } + /** + * @deprecated since 4.5 use {@link #sources()} + */ + @Deprecated public List getSourceFiles() { - String sources = properties.getProperty(SOURCE_FILES_PROPERTY, ""); + return sources(); + } + + public List tests() { + String sources = properties.getProperty(TESTS_PROPERTY, ""); return trim(StringUtils.split(sources, SEPARATOR)); } + /** + * @deprecated since 4.5 use {@link #tests()} + */ + @Deprecated public List getTestDirs() { - String sources = properties.getProperty(TEST_DIRS_PROPERTY, ""); - return trim(StringUtils.split(sources, SEPARATOR)); + return tests(); } /** - * @param paths path to directory with test sources. + * @param paths path to files or directories with test sources. * It can be absolute or relative to project directory. */ - public ProjectDefinition addTestDirs(String... paths) { + public ProjectDefinition addTests(String... paths) { for (String path : paths) { - appendProperty(TEST_DIRS_PROPERTY, path); + appendProperty(TESTS_PROPERTY, path); } return this; } - public ProjectDefinition addTestDirs(File... dirs) { - for (File dir : dirs) { - addTestDirs(dir.getAbsolutePath()); + /** + * @deprecated since 4.5 use {@link #addTests(String...)} + */ + @Deprecated + public ProjectDefinition addTestDirs(String... paths) { + return addTests(paths); + } + + public ProjectDefinition addTests(File... fileOrDirs) { + for (File fileOrDir : fileOrDirs) { + addTests(fileOrDir.getAbsolutePath()); } return this; } + /** + * @deprecated since 4.5 use {@link #addTests(File...)} + */ + @Deprecated + public ProjectDefinition addTestDirs(File... dirs) { + return addTests(dirs); + } + + public ProjectDefinition setTests(String... paths) { + resetTests(); + return addTests(paths); + } + + /** + * @deprecated since 4.5 use {@link #setTests(String...)} + */ + @Deprecated public ProjectDefinition setTestDirs(String... paths) { - resetTestDirs(); - return addTestDirs(paths); + return setTests(paths); } - public ProjectDefinition setTestDirs(File... dirs) { - resetTestDirs(); - for (File dir : dirs) { - addTestDirs(dir.getAbsolutePath()); + public ProjectDefinition setTests(File... fileOrDirs) { + resetTests(); + for (File dir : fileOrDirs) { + addTests(dir.getAbsolutePath()); } return this; } - public ProjectDefinition resetTestDirs() { - properties.remove(TEST_DIRS_PROPERTY); + /** + * @deprecated since 4.5 use {@link #setTests(File...)} + */ + @Deprecated + public ProjectDefinition setTestDirs(File... dirs) { + return setTests(dirs); + } + + public ProjectDefinition resetTests() { + properties.remove(TESTS_PROPERTY); return this; } /** - * Adding source files is possible only if no source directories have been set. - * Absolute path or relative path from project base dir. + * @deprecated since 4.5 use {@link #resetTests()} + */ + @Deprecated + public ProjectDefinition resetTestDirs() { + return resetTests(); + } + + /** + * @deprecated since 4.5 use {@link #addTests(String...)} */ + @Deprecated public ProjectDefinition addTestFiles(String... paths) { - for (String path : paths) { - appendProperty(TEST_FILES_PROPERTY, path); - } - return this; + return addTests(paths); } /** - * Adding source files is possible only if no source directories have been set. + * @deprecated since 4.5 use {@link #addTests(File...)} */ + @Deprecated public ProjectDefinition addTestFiles(File... files) { - for (File file : files) { - addTestFiles(file.getAbsolutePath()); - } - return this; + return addTests(files); } + /** + * @deprecated since 4.5 use {@link #tests()} + */ + @Deprecated public List getTestFiles() { - String sources = properties.getProperty(TEST_FILES_PROPERTY, ""); - return trim(StringUtils.split(sources, SEPARATOR)); + return tests(); } public List getBinaries() { -- 2.39.5