diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2017-01-11 17:49:34 +0100 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2017-01-27 16:26:30 +0100 |
commit | 7b3024ee784a83f274a8bcc76475cf2a91219283 (patch) | |
tree | cf3256f9164e5df584b41b244396c3d2f617cf7e /sonar-scanner-engine/src | |
parent | 6840dc54995084e8410b5b6903353a94034cad34 (diff) | |
download | sonarqube-7b3024ee784a83f274a8bcc76475cf2a91219283.tar.gz sonarqube-7b3024ee784a83f274a8bcc76475cf2a91219283.zip |
SONAR-8622 Lazily generate metadata for input files
Diffstat (limited to 'sonar-scanner-engine/src')
54 files changed, 671 insertions, 590 deletions
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/FileHashes.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/FileHashes.java index bac3c9b6888..0cec7c50bd1 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/FileHashes.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/FileHashes.java @@ -24,7 +24,7 @@ import com.google.common.collect.Multimap; import java.util.Collection; import org.apache.commons.codec.binary.Hex; import org.apache.commons.lang.ObjectUtils; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.FileMetadata; /** @@ -50,7 +50,7 @@ public final class FileHashes { return new FileHashes(hashes, linesByHash); } - public static FileHashes create(DefaultInputFile f) { + public static FileHashes create(InputFile f) { final byte[][] hashes = new byte[f.lines()][]; FileMetadata.computeLineHashesForIssueTracking(f, (lineIdx, hash) -> hashes[lineIdx - 1] = hash); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java index b0183caa188..e83785cf44b 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/issue/tracking/LocalIssueTracking.java @@ -30,6 +30,7 @@ import java.util.Map; import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.batch.ScannerSide; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.rule.ActiveRule; @@ -128,7 +129,7 @@ public class LocalIssueTracking { private boolean shouldCopyServerIssues(BatchComponent component) { if (!mode.scanAllFiles() && component.isFile()) { - DefaultInputFile inputFile = (DefaultInputFile) component.inputComponent(); + InputFile inputFile = (InputFile) component.inputComponent(); if (inputFile.status() == Status.SAME) { return true; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java index 7c569227b14..06c4893d6ea 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/report/SourcePublisher.java @@ -22,7 +22,7 @@ package org.sonar.scanner.report; import org.apache.commons.io.ByteOrderMark; import org.apache.commons.io.IOUtils; import org.apache.commons.io.input.BOMInputStream; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.InputFile; import org.sonar.scanner.index.BatchComponent; import org.sonar.scanner.index.BatchComponentCache; import org.sonar.scanner.protocol.output.ScannerReportWriter; @@ -49,7 +49,7 @@ public class SourcePublisher implements ReportPublisherStep { continue; } - DefaultInputFile inputFile = (DefaultInputFile) resource.inputComponent(); + InputFile inputFile = (InputFile) resource.inputComponent(); File iofile = writer.getSourceFile(resource.batchId()); int line = 0; try (FileOutputStream output = new FileOutputStream(iofile); BOMInputStream bomIn = new BOMInputStream(new FileInputStream(inputFile.file()), diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java index 1033130b961..fa31b9c7419 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java @@ -64,7 +64,8 @@ import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem; import org.sonar.scanner.scan.filesystem.ExclusionFilters; import org.sonar.scanner.scan.filesystem.FileIndexer; import org.sonar.scanner.scan.filesystem.FileSystemLogger; -import org.sonar.scanner.scan.filesystem.InputFileBuilderFactory; +import org.sonar.scanner.scan.filesystem.IndexedFileBuilderProvider; +import org.sonar.scanner.scan.filesystem.MetadataGeneratorProvider; import org.sonar.scanner.scan.filesystem.LanguageDetectionFactory; import org.sonar.scanner.scan.filesystem.ModuleFileSystemInitializer; import org.sonar.scanner.scan.filesystem.ModuleInputFileCache; @@ -122,11 +123,12 @@ public class ModuleScanContainer extends ComponentContainer { ModuleInputFileCache.class, FileExclusions.class, ExclusionFilters.class, - InputFileBuilderFactory.class, + new MetadataGeneratorProvider(), FileMetadata.class, StatusDetectionFactory.class, LanguageDetectionFactory.class, FileIndexer.class, + new IndexedFileBuilderProvider(), ComponentIndexer.class, LanguageVerifier.class, FileSystemLogger.class, diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicates.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicates.java index 77e1bc39827..713ca7a3d89 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicates.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicates.java @@ -19,9 +19,8 @@ */ package org.sonar.scanner.scan.filesystem; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.internal.AbstractFilePredicate; -import org.sonar.api.batch.fs.internal.DefaultInputFile; /** * Additional {@link org.sonar.api.batch.fs.FilePredicate}s that are @@ -41,8 +40,8 @@ class AdditionalFilePredicates { } @Override - public boolean apply(InputFile f) { - return key.equals(((DefaultInputFile) f).key()); + public boolean apply(IndexedFile f) { + return key.equals(f.key()); } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java index fc2c46cfb6f..03b9fb9285e 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/DefaultModuleFileSystem.java @@ -26,12 +26,12 @@ import java.nio.charset.Charset; import java.util.List; import org.apache.commons.lang.StringUtils; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; import org.sonar.api.utils.MessageException; import org.sonar.scanner.analysis.DefaultAnalysisMode; +import org.sonar.scanner.repository.ProjectRepositories; /** * @since 3.5 @@ -46,22 +46,26 @@ public class DefaultModuleFileSystem extends DefaultFileSystem { private List<File> testDirsOrFiles = Lists.newArrayList(); private ComponentIndexer componentIndexer; private boolean initialized; + private Charset charset = null; public DefaultModuleFileSystem(ModuleInputFileCache moduleInputFileCache, Project project, - Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode) { + Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode, + ProjectRepositories projectRepositories) { super(initializer.baseDir(), moduleInputFileCache); - setFields(project, settings, indexer, initializer, componentIndexer, mode); + setFields(project, settings, indexer, initializer, componentIndexer, mode, projectRepositories); } @VisibleForTesting public DefaultModuleFileSystem(Project project, - Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode) { + Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode, + ProjectRepositories projectRepositories) { super(initializer.baseDir().toPath()); - setFields(project, settings, indexer, initializer, componentIndexer, mode); + setFields(project, settings, indexer, initializer, componentIndexer, mode, projectRepositories); } private void setFields(Project project, - Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode) { + Settings settings, FileIndexer indexer, ModuleFileSystemInitializer initializer, ComponentIndexer componentIndexer, DefaultAnalysisMode mode, + ProjectRepositories projectRepositories) { this.componentIndexer = componentIndexer; this.moduleKey = project.getKey(); this.settings = settings; @@ -72,7 +76,7 @@ public class DefaultModuleFileSystem extends DefaultFileSystem { // filter the files sensors have access to if (!mode.scanAllFiles()) { - setDefaultPredicate(predicates.not(predicates.hasStatus(Status.SAME))); + setDefaultPredicate(new SameInputFilePredicate(projectRepositories, moduleKey)); } } @@ -94,12 +98,13 @@ public class DefaultModuleFileSystem extends DefaultFileSystem { @Override public Charset encoding() { - final Charset charset; - String encoding = settings.getString(CoreProperties.ENCODING_PROPERTY); - if (StringUtils.isNotEmpty(encoding)) { - charset = Charset.forName(StringUtils.trim(encoding)); - } else { - charset = Charset.defaultCharset(); + if (charset == null) { + String encoding = settings.getString(CoreProperties.ENCODING_PROPERTY); + if (StringUtils.isNotEmpty(encoding)) { + charset = Charset.forName(StringUtils.trim(encoding)); + } else { + charset = Charset.defaultCharset(); + } } return charset; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ExclusionFilters.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ExclusionFilters.java index 2d7975e7ea3..e0dfdd1c5dd 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ExclusionFilters.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ExclusionFilters.java @@ -23,6 +23,7 @@ import org.apache.commons.lang.ArrayUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.ScannerSide; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.PathPattern; import org.sonar.api.scan.filesystem.FileExclusions; @@ -67,7 +68,7 @@ public class ExclusionFilters { } } - public boolean accept(InputFile inputFile, InputFile.Type type) { + public boolean accept(IndexedFile indexedFile, InputFile.Type type) { PathPattern[] inclusionPatterns; PathPattern[] exclusionPatterns; if (InputFile.Type.MAIN == type) { @@ -83,7 +84,7 @@ public class ExclusionFilters { if (inclusionPatterns.length > 0) { boolean matchInclusion = false; for (PathPattern pattern : inclusionPatterns) { - matchInclusion |= pattern.match(inputFile); + matchInclusion |= pattern.match(indexedFile); } if (!matchInclusion) { return false; @@ -91,7 +92,7 @@ public class ExclusionFilters { } if (exclusionPatterns.length > 0) { for (PathPattern pattern : exclusionPatterns) { - if (pattern.match(inputFile)) { + if (pattern.match(indexedFile)) { return false; } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java index 13aa962ccca..595773f62b5 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java @@ -19,7 +19,6 @@ */ package org.sonar.scanner.scan.filesystem; -import com.google.common.util.concurrent.ThreadFactoryBuilder; import java.io.File; import java.io.IOException; import java.nio.file.FileSystemLoopException; @@ -30,26 +29,23 @@ import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.nio.file.attribute.BasicFileAttributes; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.batch.ScannerSide; import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Type; -import org.sonar.api.batch.fs.InputFileFilter; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.scan.filesystem.PathResolver; +import org.sonar.api.batch.fs.InputFileFilter; import org.sonar.api.utils.MessageException; import org.sonar.scanner.util.ProgressReport; @@ -63,21 +59,22 @@ public class FileIndexer { private final InputFileFilter[] filters; private final boolean isAggregator; private final ExclusionFilters exclusionFilters; - private final InputFileBuilderFactory inputFileBuilderFactory; private ProgressReport progressReport; - private ExecutorService executorService; - private List<Future<Void>> tasks; + private IndexedFileBuilder indexedFileBuilder; + private MetadataGenerator metadataGenerator; - public FileIndexer(ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory, ProjectDefinition def, InputFileFilter[] filters) { + public FileIndexer(ExclusionFilters exclusionFilters, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def, + InputFileFilter[] filters) { + this.indexedFileBuilder = indexedFileBuilder; + this.metadataGenerator = inputFileBuilder; this.filters = filters; this.exclusionFilters = exclusionFilters; - this.inputFileBuilderFactory = inputFileBuilderFactory; this.isAggregator = !def.getSubProjects().isEmpty(); } - public FileIndexer(ExclusionFilters exclusionFilters, InputFileBuilderFactory inputFileBuilderFactory, ProjectDefinition def) { - this(exclusionFilters, inputFileBuilderFactory, def, new InputFileFilter[0]); + public FileIndexer(ExclusionFilters exclusionFilters, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def) { + this(exclusionFilters, indexedFileBuilder, inputFileBuilder, def, new InputFileFilter[0]); } void index(DefaultModuleFileSystem fileSystem) { @@ -91,14 +88,8 @@ public class FileIndexer { Progress progress = new Progress(); - InputFileBuilder inputFileBuilder = inputFileBuilderFactory.create(fileSystem); - int threads = Math.max(1, Runtime.getRuntime().availableProcessors() - 1); - executorService = Executors.newFixedThreadPool(threads, new ThreadFactoryBuilder().setNameFormat("FileIndexer-%d").build()); - tasks = new ArrayList<>(); - indexFiles(fileSystem, progress, inputFileBuilder, fileSystem.sources(), InputFile.Type.MAIN); - indexFiles(fileSystem, progress, inputFileBuilder, fileSystem.tests(), InputFile.Type.TEST); - - waitForTasksToComplete(); + indexFiles(fileSystem, progress, fileSystem.sources(), InputFile.Type.MAIN); + indexFiles(fileSystem, progress, fileSystem.tests(), InputFile.Type.TEST); progressReport.stop(progress.count() + " files indexed"); @@ -107,27 +98,13 @@ public class FileIndexer { } } - private void waitForTasksToComplete() { - executorService.shutdown(); - for (Future<Void> task : tasks) { - try { - task.get(); - } catch (ExecutionException e) { - // Unwrap ExecutionException - throw e.getCause() instanceof RuntimeException ? (RuntimeException) e.getCause() : new IllegalStateException(e.getCause()); - } catch (InterruptedException e) { - throw new IllegalStateException(e); - } - } - } - - private void indexFiles(DefaultModuleFileSystem fileSystem, Progress progress, InputFileBuilder inputFileBuilder, List<File> sources, InputFile.Type type) { + private void indexFiles(DefaultModuleFileSystem fileSystem, Progress progress, List<File> sources, InputFile.Type type) { try { for (File dirOrFile : sources) { if (dirOrFile.isDirectory()) { - indexDirectory(inputFileBuilder, fileSystem, progress, dirOrFile, type); + indexDirectory(fileSystem, progress, dirOrFile, type); } else { - indexFile(inputFileBuilder, fileSystem, progress, dirOrFile.toPath(), type); + indexFile(fileSystem, progress, dirOrFile.toPath(), type); } } } catch (IOException e) { @@ -135,57 +112,45 @@ public class FileIndexer { } } - private void indexDirectory(final InputFileBuilder inputFileBuilder, final DefaultModuleFileSystem fileSystem, final Progress status, - final File dirToIndex, final InputFile.Type type) throws IOException { + private void indexDirectory(final DefaultModuleFileSystem fileSystem, final Progress status, final File dirToIndex, final InputFile.Type type) throws IOException { Files.walkFileTree(dirToIndex.toPath().normalize(), Collections.singleton(FileVisitOption.FOLLOW_LINKS), Integer.MAX_VALUE, - new IndexFileVisitor(inputFileBuilder, fileSystem, status, type)); + new IndexFileVisitor(fileSystem, status, type)); } - private void indexFile(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress progress, Path sourceFile, InputFile.Type type) throws IOException { + private void indexFile(DefaultModuleFileSystem fileSystem, Progress progress, Path sourceFile, InputFile.Type type) throws IOException { // get case of real file without resolving link Path realFile = sourceFile.toRealPath(LinkOption.NOFOLLOW_LINKS); - DefaultInputFile inputFile = inputFileBuilder.create(realFile.toFile()); - if (inputFile != null) { - // Set basedir on input file prior to adding it to the FS since exclusions filters may require the absolute path - inputFile.setModuleBaseDir(fileSystem.baseDirPath()); - if (exclusionFilters.accept(inputFile, type)) { - indexFile(inputFileBuilder, fileSystem, progress, inputFile, type); + DefaultIndexedFile indexedFile = indexedFileBuilder.create(realFile, type, fileSystem.baseDirPath()); + if (indexedFile != null) { + if (exclusionFilters.accept(indexedFile, type)) { + InputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.readMetadata(f, fileSystem.encoding())); + if (accept(inputFile)) { + fileSystem.add(inputFile); + } + indexParentDir(fileSystem, indexedFile); + progress.markAsIndexed(indexedFile); + LOG.debug("'{}' indexed {} with language '{}'", indexedFile.relativePath(), type == Type.TEST ? "as test " : "", indexedFile.language()); } else { progress.increaseExcludedByPatternsCount(); } } } - private void indexFile(final InputFileBuilder inputFileBuilder, final DefaultModuleFileSystem fs, - final Progress status, final DefaultInputFile inputFile, final InputFile.Type type) { - - tasks.add(executorService.submit(() -> { - DefaultInputFile completedInputFile = inputFileBuilder.completeAndComputeMetadata(inputFile, type); - if (completedInputFile != null && accept(completedInputFile)) { - LOG.debug("'{}' indexed {}with language '{}' and charset '{}'", - inputFile.relativePath(), - type == Type.TEST ? "as test " : "", - inputFile.language(), - inputFile.charset()); - fs.add(completedInputFile); - status.markAsIndexed(completedInputFile); - File parentDir = completedInputFile.file().getParentFile(); - String relativePath = new PathResolver().relativePath(fs.baseDir(), parentDir); - if (relativePath != null) { - DefaultInputDir inputDir = new DefaultInputDir(fs.moduleKey(), relativePath); - fs.add(inputDir); - } - } - return null; - })); - + private void indexParentDir(DefaultModuleFileSystem fileSystem, IndexedFile indexedFile) { + File parentDir = indexedFile.file().getParentFile(); + String relativePath = new PathResolver().relativePath(fileSystem.baseDir(), parentDir); + if (relativePath != null) { + DefaultInputDir inputDir = new DefaultInputDir(fileSystem.moduleKey(), relativePath); + inputDir.setModuleBaseDir(fileSystem.baseDirPath()); + fileSystem.add(inputDir); + } } - private boolean accept(InputFile inputFile) { + private boolean accept(InputFile indexedFile) { // InputFileFilter extensions for (InputFileFilter filter : filters) { - if (!filter.accept(inputFile)) { - LOG.debug("'{}' excluded by {}", inputFile.relativePath(), filter.getClass().getName()); + if (!filter.accept(indexedFile)) { + LOG.debug("'{}' excluded by {}", indexedFile.relativePath(), filter.getClass().getName()); return false; } } @@ -193,13 +158,11 @@ public class FileIndexer { } private class IndexFileVisitor implements FileVisitor<Path> { - private InputFileBuilder inputFileBuilder; private DefaultModuleFileSystem fileSystem; private Progress status; private Type type; - IndexFileVisitor(InputFileBuilder inputFileBuilder, DefaultModuleFileSystem fileSystem, Progress status, InputFile.Type type) { - this.inputFileBuilder = inputFileBuilder; + IndexFileVisitor(DefaultModuleFileSystem fileSystem, Progress status, InputFile.Type type) { this.fileSystem = fileSystem; this.status = status; this.type = type; @@ -221,7 +184,7 @@ public class FileIndexer { @Override public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { if (!Files.isHidden(file)) { - indexFile(inputFileBuilder, fileSystem, status, file, type); + indexFile(fileSystem, status, file, type); } return FileVisitResult.CONTINUE; } @@ -246,7 +209,7 @@ public class FileIndexer { private final Set<Path> indexed = new HashSet<>(); private int excludedByPatternsCount = 0; - synchronized void markAsIndexed(InputFile inputFile) { + synchronized void markAsIndexed(IndexedFile inputFile) { if (indexed.contains(inputFile.path())) { throw MessageException.of("File " + inputFile + " can't be indexed twice. Please check that inclusion/exclusion patterns produce " + "disjoint sets for main and test files"); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java new file mode 100644 index 00000000000..352065dbcb7 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilder.java @@ -0,0 +1,65 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scanner.scan.filesystem; + +import java.nio.file.Path; + +import javax.annotation.CheckForNull; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.CoreProperties; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; +import org.sonar.api.config.Settings; +import org.sonar.api.scan.filesystem.PathResolver; + +public class IndexedFileBuilder { + private static final Logger LOG = LoggerFactory.getLogger(IndexedFileBuilder.class); + private final String moduleKey; + private final PathResolver pathResolver; + private final LanguageDetection langDetection; + private final Settings settings; + + IndexedFileBuilder(String moduleKey, PathResolver pathResolver, Settings settings, LanguageDetection langDetection) { + this.moduleKey = moduleKey; + this.pathResolver = pathResolver; + this.settings = settings; + this.langDetection = langDetection; + } + + @CheckForNull + DefaultIndexedFile create(Path file, InputFile.Type type, Path moduleBaseDir) { + String relativePath = pathResolver.relativePath(moduleBaseDir, file); + if (relativePath == null) { + LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", file.toAbsolutePath(), moduleBaseDir); + return null; + } + DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type); + String language = langDetection.language(indexedFile); + if (language == null && !settings.getBoolean(CoreProperties.IMPORT_UNKNOWN_FILES_KEY)) { + LOG.debug("'{}' language is not supported by any analyzer. Skipping it.", relativePath); + return null; + } + + indexedFile.setLanguage(language); + return indexedFile; + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java new file mode 100644 index 00000000000..c892bf9ff8f --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/IndexedFileBuilderProvider.java @@ -0,0 +1,33 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scanner.scan.filesystem; + +import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.batch.bootstrap.ProjectDefinition; +import org.sonar.api.config.Settings; +import org.sonar.api.scan.filesystem.PathResolver; + +public class IndexedFileBuilderProvider extends ProviderAdapter { + + public IndexedFileBuilder provide(ProjectDefinition def, PathResolver pathResolver, Settings settings, LanguageDetectionFactory langDetectionFactory) { + return new IndexedFileBuilder(def.getKeyWithBranch(), pathResolver, settings, langDetectionFactory.create()); + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactory.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactory.java deleted file mode 100644 index 310484591ab..00000000000 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.scanner.scan.filesystem; - -import org.sonar.api.batch.ScannerSide; -import org.sonar.api.batch.bootstrap.ProjectDefinition; -import org.sonar.api.batch.fs.internal.FileMetadata; -import org.sonar.api.config.Settings; -import org.sonar.api.scan.filesystem.PathResolver; - -@ScannerSide -public class InputFileBuilderFactory { - - private final String moduleKey; - private final PathResolver pathResolver; - private final LanguageDetectionFactory langDetectionFactory; - private final StatusDetectionFactory statusDetectionFactory; - private final Settings settings; - private final FileMetadata fileMetadata; - - public InputFileBuilderFactory(ProjectDefinition def, PathResolver pathResolver, LanguageDetectionFactory langDetectionFactory, - StatusDetectionFactory statusDetectionFactory, Settings settings, FileMetadata fileMetadata) { - this.fileMetadata = fileMetadata; - this.moduleKey = def.getKeyWithBranch(); - this.pathResolver = pathResolver; - this.langDetectionFactory = langDetectionFactory; - this.statusDetectionFactory = statusDetectionFactory; - this.settings = settings; - } - - InputFileBuilder create(DefaultModuleFileSystem fs) { - return new InputFileBuilder(moduleKey, pathResolver, langDetectionFactory.create(), statusDetectionFactory.create(), fs, settings, fileMetadata); - } -} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java index 10708b1d392..b83402a7733 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/LanguageDetection.java @@ -30,7 +30,7 @@ import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; import org.sonar.api.batch.fs.internal.PathPattern; import org.sonar.api.config.Settings; import org.sonar.api.utils.MessageException; @@ -88,7 +88,7 @@ class LanguageDetection { } @CheckForNull - String language(InputFile inputFile) { + String language(DefaultIndexedFile inputFile) { String detectedLanguage = null; for (String languageKey : languagesToConsider) { if (isCandidateForLanguage(inputFile, languageKey)) { @@ -113,7 +113,7 @@ class LanguageDetection { return null; } - private boolean isCandidateForLanguage(InputFile inputFile, String languageKey) { + private boolean isCandidateForLanguage(DefaultIndexedFile inputFile, String languageKey) { PathPattern[] patterns = patternsByLanguage.get(languageKey); if (patterns != null) { for (PathPattern pathPattern : patterns) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java index 0cdf970a4e1..5468bd7ae6e 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGenerator.java @@ -20,107 +20,36 @@ package org.sonar.scanner.scan.filesystem; import com.google.common.annotations.VisibleForTesting; + import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import javax.annotation.CheckForNull; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.FileSystem; -import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.FileMetadata; -import org.sonar.api.config.Settings; -import org.sonar.api.scan.filesystem.PathResolver; - -class InputFileBuilder { - - private static final Logger LOG = LoggerFactory.getLogger(InputFileBuilder.class); +import org.sonar.api.batch.fs.internal.Metadata; +class MetadataGenerator { + private static final Logger LOG = LoggerFactory.getLogger(MetadataGenerator.class); @VisibleForTesting static final Charset UTF_32BE = Charset.forName("UTF-32BE"); @VisibleForTesting static final Charset UTF_32LE = Charset.forName("UTF-32LE"); - private final String moduleKey; - private final PathResolver pathResolver; - private final LanguageDetection langDetection; private final StatusDetection statusDetection; - private final DefaultModuleFileSystem fs; - private final Settings settings; private final FileMetadata fileMetadata; - InputFileBuilder(String moduleKey, PathResolver pathResolver, LanguageDetection langDetection, - StatusDetection statusDetection, DefaultModuleFileSystem fs, Settings settings, FileMetadata fileMetadata) { - this.moduleKey = moduleKey; - this.pathResolver = pathResolver; - this.langDetection = langDetection; + MetadataGenerator(StatusDetection statusDetection, FileMetadata fileMetadata) { this.statusDetection = statusDetection; - this.fs = fs; - this.settings = settings; this.fileMetadata = fileMetadata; } - String moduleKey() { - return moduleKey; - } - - PathResolver pathResolver() { - return pathResolver; - } - - LanguageDetection langDetection() { - return langDetection; - } - - StatusDetection statusDetection() { - return statusDetection; - } - - FileSystem fs() { - return fs; - } - - @CheckForNull - DefaultInputFile create(File file) { - String relativePath = pathResolver.relativePath(fs.baseDir(), file); - if (relativePath == null) { - LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", file.getAbsolutePath(), fs.baseDir()); - return null; - } - return new DefaultInputFile(moduleKey, relativePath); - } - - /** - * Optimization to not compute InputFile metadata if the file is excluded from analysis. - */ - @CheckForNull - DefaultInputFile completeAndComputeMetadata(DefaultInputFile inputFile, InputFile.Type type) { - inputFile.setType(type); - inputFile.setModuleBaseDir(fs.baseDir().toPath()); - - String lang = langDetection.language(inputFile); - if (lang == null && !settings.getBoolean(CoreProperties.IMPORT_UNKNOWN_FILES_KEY)) { - // Return fast to skip costly metadata computation - LOG.debug("'{}' language is not supported by any analyzer. Skipping it.", inputFile.relativePath()); - return null; - } - inputFile.setLanguage(lang); - - Charset charset = detectCharset(inputFile.file(), fs.encoding()); - inputFile.setCharset(charset); - - inputFile.initMetadata(fileMetadata.readMetadata(inputFile.file(), charset)); - - inputFile.setStatus(statusDetection.status(inputFile.moduleKey(), inputFile.relativePath(), inputFile.hash())); - - return inputFile; - } - /** * @return charset detected from BOM in given file or given defaultCharset * @throws IllegalStateException if an I/O error occurs @@ -146,4 +75,18 @@ class InputFileBuilder { throw new IllegalStateException("Unable to read file " + file.getAbsolutePath(), e); } } + + public Metadata readMetadata(final DefaultInputFile inputFile, Charset defaultEncoding) { + try { + Charset charset = detectCharset(inputFile.file(), defaultEncoding); + inputFile.setCharset(charset); + Metadata metadata = fileMetadata.readMetadata(inputFile.file(), charset); + inputFile.setStatus(statusDetection.status(inputFile.moduleKey(), inputFile.relativePath(), metadata.hash())); + LOG.debug("'{}' generated metadata {} with and charset '{}'", + inputFile.relativePath(), inputFile.type() == Type.TEST ? "as test " : "", charset); + return metadata; + } catch (Exception e) { + throw new IllegalStateException(e); + } + } } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java new file mode 100644 index 00000000000..13bfd484184 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProvider.java @@ -0,0 +1,31 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scanner.scan.filesystem; + +import org.picocontainer.injectors.ProviderAdapter; +import org.sonar.api.batch.ScannerSide; +import org.sonar.api.batch.fs.internal.FileMetadata; + +@ScannerSide +public class MetadataGeneratorProvider extends ProviderAdapter { + public MetadataGenerator provide(StatusDetectionFactory statusDetectionFactory, FileMetadata fileMetadata) { + return new MetadataGenerator(statusDetectionFactory.create(), fileMetadata); + } +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java new file mode 100644 index 00000000000..5ec413082cd --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/SameInputFilePredicate.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scanner.scan.filesystem; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.InputFilePredicate; +import org.sonar.scanner.repository.FileData; +import org.sonar.scanner.repository.ProjectRepositories; + +public class SameInputFilePredicate implements InputFilePredicate { + private static final Logger LOG = LoggerFactory.getLogger(SameInputFilePredicate.class); + private final ProjectRepositories projectRepositories; + private final String moduleKey; + + public SameInputFilePredicate(ProjectRepositories projectRepositories, String moduleKey) { + this.projectRepositories = projectRepositories; + this.moduleKey = moduleKey; + } + + @Override + public boolean apply(InputFile inputFile) { + FileData fileDataPerPath = projectRepositories.fileData(moduleKey, inputFile.relativePath()); + if (fileDataPerPath == null) { + // ADDED + return true; + } + String previousHash = fileDataPerPath.hash(); + if (StringUtils.isEmpty(previousHash)) { + // ADDED + return true; + } + + // this will trigger computation of metadata + String hash = ((DefaultInputFile) inputFile).hash(); + if (StringUtils.equals(hash, previousHash)) { + // SAME + LOG.debug("'{}' filtering unmodified file", inputFile.relativePath()); + return false; + } + + // CHANGED + return true; + } + +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java index 218754a197d..8beba97adae 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java @@ -33,7 +33,6 @@ import java.util.stream.Stream; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.TextRange; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.measure.Metric; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage; @@ -353,7 +352,7 @@ public class DefaultSensorStorage implements SensorStorage { @Override public void store(DefaultHighlighting highlighting) { ScannerReportWriter writer = reportPublisher.getWriter(); - DefaultInputFile inputFile = (DefaultInputFile) highlighting.inputFile(); + InputFile inputFile = highlighting.inputFile(); int componentRef = componentCache.get(inputFile).batchId(); if (writer.hasComponentData(FileStructure.Domain.SYNTAX_HIGHLIGHTINGS, componentRef)) { throw new UnsupportedOperationException("Trying to save highlighting twice for the same file is not supported: " + inputFile.absolutePath()); diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultHighlightable.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultHighlightable.java index 357ae80d801..5d9795f042d 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultHighlightable.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultHighlightable.java @@ -20,7 +20,7 @@ package org.sonar.scanner.source; import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; import org.sonar.api.batch.sensor.internal.SensorStorage; @@ -32,11 +32,11 @@ import org.sonar.api.source.Highlightable; public class DefaultHighlightable implements Highlightable { private static final HighlightingBuilder NO_OP_BUILDER = new NoOpHighlightingBuilder(); - private final DefaultInputFile inputFile; + private final InputFile inputFile; private final SensorStorage sensorStorage; private final AnalysisMode analysisMode; - public DefaultHighlightable(DefaultInputFile inputFile, SensorStorage sensorStorage, AnalysisMode analysisMode) { + public DefaultHighlightable(InputFile inputFile, SensorStorage sensorStorage, AnalysisMode analysisMode) { this.inputFile = inputFile; this.sensorStorage = sensorStorage; this.analysisMode = analysisMode; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultSymbolizable.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultSymbolizable.java index f14604292d7..e2b6f3b4391 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultSymbolizable.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/DefaultSymbolizable.java @@ -22,7 +22,7 @@ package org.sonar.scanner.source; import java.util.Collections; import java.util.List; import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.source.Symbol; import org.sonar.api.source.Symbolizable; @@ -95,11 +95,11 @@ public class DefaultSymbolizable implements Symbolizable { } } - private final DefaultInputFile inputFile; + private final InputFile inputFile; private final DefaultSensorStorage sensorStorage; private final AnalysisMode analysisMode; - public DefaultSymbolizable(DefaultInputFile inputFile, DefaultSensorStorage sensorStorage, AnalysisMode analysisMode) { + public DefaultSymbolizable(InputFile inputFile, DefaultSensorStorage sensorStorage, AnalysisMode analysisMode) { this.inputFile = inputFile; this.sensorStorage = sensorStorage; this.analysisMode = analysisMode; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/HighlightableBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/HighlightableBuilder.java index da793d3e981..e1e598408e8 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/HighlightableBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/HighlightableBuilder.java @@ -23,7 +23,6 @@ import javax.annotation.CheckForNull; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.source.Highlightable; import org.sonar.scanner.deprecated.perspectives.PerspectiveBuilder; @@ -44,7 +43,7 @@ public class HighlightableBuilder extends PerspectiveBuilder<Highlightable> { public Highlightable loadPerspective(Class<Highlightable> perspectiveClass, InputComponent component) { if (component.isFile()) { InputFile path = (InputFile) component; - return new DefaultHighlightable((DefaultInputFile) path, sensorStorage, analysisMode); + return new DefaultHighlightable(path, sensorStorage, analysisMode); } return null; } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/LinesSensor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/LinesSensor.java index 6017d05ca7e..726eec05aa3 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/LinesSensor.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/LinesSensor.java @@ -30,7 +30,7 @@ import org.sonar.api.batch.sensor.SensorDescriptor; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.measures.CoreMetrics; -@Phase(name = Phase.Name.PRE) +@Phase(name = Phase.Name.POST) public final class LinesSensor implements Sensor { @Override diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/SymbolizableBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/SymbolizableBuilder.java index 947670bf769..d85fff4faea 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/SymbolizableBuilder.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/source/SymbolizableBuilder.java @@ -23,7 +23,6 @@ import javax.annotation.CheckForNull; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.source.Symbolizable; import org.sonar.scanner.deprecated.perspectives.PerspectiveBuilder; import org.sonar.scanner.sensor.DefaultSensorStorage; @@ -44,7 +43,7 @@ public class SymbolizableBuilder extends PerspectiveBuilder<Symbolizable> { public Symbolizable loadPerspective(Class<Symbolizable> perspectiveClass, InputComponent component) { if (component.isFile()) { InputFile path = (InputFile) component; - return new DefaultSymbolizable((DefaultInputFile) path, sensorStorage, analysisMode); + return new DefaultSymbolizable(path, sensorStorage, analysisMode); } return null; } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java index 37d74deeb24..0eedca40755 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/DefaultFileLinesContextTest.java @@ -24,7 +24,7 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; @@ -78,7 +78,7 @@ public class DefaultFileLinesContextTest { when(metricFinder.<String>findByKey(CoreMetrics.EXECUTABLE_LINES_DATA_KEY)).thenReturn(CoreMetrics.EXECUTABLE_LINES_DATA); when(metricFinder.<String>findByKey(CoreMetrics.COMMENT_LINES_DATA_KEY)).thenReturn(CoreMetrics.COMMENT_LINES_DATA); measureCache = mock(MeasureCache.class); - fileLineMeasures = new DefaultFileLinesContext(sensorContextTester, new DefaultInputFile("foo", "src/foo.php").initMetadata("Foo\nbar\nbiz"), metricFinder, + fileLineMeasures = new DefaultFileLinesContext(sensorContextTester, new TestInputFileBuilder("foo", "src/foo.php").initMetadata("Foo\nbar\nbiz").build(), metricFinder, measureCache); } @@ -95,13 +95,13 @@ public class DefaultFileLinesContextTest { @Test public void validateLineGreaterThanZero() { - thrown.expectMessage("Line number should be positive for file [moduleKey=foo, relative=src/foo.php, basedir=null]."); + thrown.expectMessage("Line number should be positive for file [moduleKey=foo, relative=src/foo.php, basedir=foo]."); fileLineMeasures.setIntValue(HITS_METRIC_KEY, 0, 2); } @Test public void validateLineLowerThanLineCount() { - thrown.expectMessage("Line 4 is out of range for file [moduleKey=foo, relative=src/foo.php, basedir=null]. File has 3 lines"); + thrown.expectMessage("Line 4 is out of range for file [moduleKey=foo, relative=src/foo.php, basedir=foo]. File has 3 lines"); fileLineMeasures.setIntValue(HITS_METRIC_KEY, 4, 2); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java index ccf34b15f18..15545a45716 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdExecutorTest.java @@ -31,8 +31,8 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.config.MapSettings; import org.sonar.api.config.Settings; import org.sonar.api.resources.Project; @@ -102,9 +102,10 @@ public class CpdExecutorTest { private BatchComponent createComponent(String relativePath, int lines) { org.sonar.api.resources.Resource sampleFile = org.sonar.api.resources.File.create("relativePath").setEffectiveKey("foo:" + relativePath); return componentCache.add(sampleFile, null) - .setInputComponent(new DefaultInputFile("foo", relativePath) + .setInputComponent(new TestInputFileBuilder("foo", relativePath) .setModuleBaseDir(baseDir.toPath()) - .setLines(lines)); + .setLines(lines) + .build()); } @Test diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/deprecated/JavaCpdBlockIndexerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/deprecated/JavaCpdBlockIndexerTest.java index f43120e5c84..77908318914 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/deprecated/JavaCpdBlockIndexerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/deprecated/JavaCpdBlockIndexerTest.java @@ -33,8 +33,9 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.CoreProperties; import org.sonar.api.batch.fs.FileSystem; +import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.config.Settings; import org.sonar.api.config.MapSettings; import org.sonar.duplications.block.Block; @@ -58,7 +59,7 @@ public class JavaCpdBlockIndexerTest { private Settings settings; private JavaCpdBlockIndexer engine; - private DefaultInputFile file; + private InputFile file; @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -69,7 +70,7 @@ public class JavaCpdBlockIndexerTest { File baseDir = temp.newFolder(); DefaultFileSystem fs = new DefaultFileSystem(baseDir); - file = new DefaultInputFile("foo", "src/ManyStatements.java").setLanguage(JAVA); + file = new TestInputFileBuilder("foo", "src/ManyStatements.java").setLanguage(JAVA).build(); fs.add(file); BatchComponentCache batchComponentCache = new BatchComponentCache(); batchComponentCache.add(org.sonar.api.resources.File.create("src/Foo.java").setEffectiveKey("foo:src/ManyStatements.java"), null).setInputComponent(file); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java index fb41e6b2ad9..bf3eb736cf4 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericCoverageReportParserTest.java @@ -25,6 +25,7 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorContextTester; import static org.assertj.core.api.Assertions.assertThat; @@ -216,9 +217,10 @@ public class GenericCoverageReportParserTest { } private DefaultInputFile setupFile(String path) { - return new DefaultInputFile(context.module().key(), path) + return new TestInputFileBuilder(context.module().key(), path) .setLanguage("bla") .setType(InputFile.Type.TEST) - .initMetadata("1\n2\n3\n4\n5\n6"); + .initMetadata("1\n2\n3\n4\n5\n6") + .build(); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java index 3ee34b3f4f0..f9c44a658dd 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/genericcoverage/GenericTestExecutionReportParserTest.java @@ -25,6 +25,7 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorContextTester; import org.sonar.api.test.MutableTestCase; import org.sonar.api.test.MutableTestPlan; @@ -142,10 +143,11 @@ public class GenericTestExecutionReportParserTest { } private DefaultInputFile setupFile(String path) { - return new DefaultInputFile(context.module().key(), path) + return new TestInputFileBuilder(context.module().key(), path) .setLanguage("bla") .setType(InputFile.Type.TEST) - .initMetadata("1\n2\n3\n4\n5\n6"); + .initMetadata("1\n2\n3\n4\n5\n6") + .build(); } private MutableTestPlan mockMutableTestPlan(MutableTestCase testCase) { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuableFactoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuableFactoryTest.java index 996e5066856..1cbed75f3e5 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuableFactoryTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/IssuableFactoryTest.java @@ -20,8 +20,8 @@ package org.sonar.scanner.issue; import org.junit.Test; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.issue.Issuable; import org.sonar.scanner.DefaultProjectTree; import org.sonar.scanner.sensor.DefaultSensorContext; @@ -37,7 +37,7 @@ public class IssuableFactoryTest { @Test public void file_should_be_issuable() { IssuableFactory factory = new IssuableFactory(mock(DefaultSensorContext.class)); - Issuable issuable = factory.loadPerspective(Issuable.class, new DefaultInputFile("foo", "src/Foo.java")); + Issuable issuable = factory.loadPerspective(Issuable.class, new TestInputFileBuilder("foo", "src/Foo.java").build()); assertThat(issuable).isNotNull(); assertThat(issuable.issues()).isEmpty(); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java index 61ac1a0fadd..d2f75e47d62 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ModuleIssuesTest.java @@ -26,7 +26,7 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.rule.internal.RulesBuilder; import org.sonar.api.batch.sensor.issue.internal.DefaultIssue; @@ -67,7 +67,7 @@ public class ModuleIssuesTest { ModuleIssues moduleIssues; BatchComponentCache componentCache = new BatchComponentCache(); - InputFile file = new DefaultInputFile("foo", "src/Foo.php").initMetadata("Foo\nBar\nBiz\n"); + InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").initMetadata("Foo\nBar\nBiz\n").build(); ReportPublisher reportPublisher = mock(ReportPublisher.class, RETURNS_DEEP_STUBS); @Before diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java index f0b9ef844f5..07b19afa357 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/issue/ignore/scanner/IssueExclusionsLoaderTest.java @@ -30,7 +30,7 @@ import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.scanner.issue.ignore.pattern.IssueExclusionPatternInitializer; import org.sonar.scanner.issue.ignore.pattern.IssueInclusionPatternInitializer; import org.sonar.scanner.issue.ignore.pattern.PatternMatcher; @@ -102,11 +102,15 @@ public class IssueExclusionsLoaderTest { @Test public void shouldAnalyzeProject() throws IOException { File javaFile1 = new File(baseDir, "src/main/java/Foo.java"); - fs.add(new DefaultInputFile("polop", "src/main/java/Foo.java") - .setType(InputFile.Type.MAIN)); + fs.add(new TestInputFileBuilder("polop", "src/main/java/Foo.java") + .setModuleBaseDir(baseDir.toPath()) + .setType(InputFile.Type.MAIN) + .build()); File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java"); - fs.add(new DefaultInputFile("polop", "src/test/java/FooTest.java") - .setType(InputFile.Type.TEST)); + fs.add(new TestInputFileBuilder("polop", "src/test/java/FooTest.java") + .setModuleBaseDir(baseDir.toPath()) + .setType(InputFile.Type.TEST) + .build()); when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true); @@ -122,12 +126,12 @@ public class IssueExclusionsLoaderTest { @Test public void shouldAnalyseFilesOnlyWhenRegexConfigured() { - File javaFile1 = new File(baseDir, "src/main/java/Foo.java"); - fs.add(new DefaultInputFile("polop", "src/main/java/Foo.java") - .setType(InputFile.Type.MAIN)); - File javaTestFile1 = new File(baseDir, "src/test/java/FooTest.java"); - fs.add(new DefaultInputFile("polop", "src/test/java/FooTest.java") - .setType(InputFile.Type.TEST)); + fs.add(new TestInputFileBuilder("polop", "src/main/java/Foo.java") + .setType(InputFile.Type.MAIN) + .build()); + fs.add(new TestInputFileBuilder("polop", "src/test/java/FooTest.java") + .setType(InputFile.Type.TEST) + .build()); when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(false); scanner.execute(); @@ -142,8 +146,10 @@ public class IssueExclusionsLoaderTest { @Test public void shouldReportFailure() throws IOException { File phpFile1 = new File(baseDir, "src/Foo.php"); - fs.add(new DefaultInputFile("polop", "src/Foo.php") - .setType(InputFile.Type.MAIN)); + fs.add(new TestInputFileBuilder("polop", "src/Foo.php") + .setModuleBaseDir(baseDir.toPath()) + .setType(InputFile.Type.MAIN) + .build()); when(exclusionPatternInitializer.hasFileContentPattern()).thenReturn(true); doThrow(new IOException("BUG")).when(regexpScanner).scan("polop:src/Foo.php", phpFile1, UTF_8); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java index de4ecaac496..b9fd9dda603 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java @@ -27,6 +27,7 @@ import java.util.Map; import org.apache.commons.io.FileUtils; import org.junit.After; import org.junit.Before; +import org.junit.Ignore; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java index 0f6eb6dbdcc..abd3a13b8dd 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/ComponentsPublisherTest.java @@ -28,8 +28,8 @@ import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.internal.DefaultInputDir; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.resources.Directory; import org.sonar.api.resources.Project; import org.sonar.api.utils.DateUtils; @@ -76,17 +76,17 @@ public class ComponentsPublisherTest { org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", FakeJava.INSTANCE, false); file.setEffectiveKey("module1:src/Foo.java"); file.setId(4).setUuid("FILE_UUID"); - resourceCache.add(file, dir).setInputComponent(new DefaultInputFile("module1", "src/Foo.java").setLines(2)); + resourceCache.add(file, dir).setInputComponent(new TestInputFileBuilder("module1", "src/Foo.java").setLines(2).build()); org.sonar.api.resources.File fileWithoutLang = org.sonar.api.resources.File.create("src/make", null, false); fileWithoutLang.setEffectiveKey("module1:src/make"); fileWithoutLang.setId(5).setUuid("FILE_WITHOUT_LANG_UUID"); - resourceCache.add(fileWithoutLang, dir).setInputComponent(new DefaultInputFile("module1", "src/make").setLines(10)); + resourceCache.add(fileWithoutLang, dir).setInputComponent(new TestInputFileBuilder("module1", "src/make").setLines(10).build()); org.sonar.api.resources.File testFile = org.sonar.api.resources.File.create("test/FooTest.java", FakeJava.INSTANCE, true); testFile.setEffectiveKey("module1:test/FooTest.java"); testFile.setId(6).setUuid("TEST_FILE_UUID"); - resourceCache.add(testFile, dir).setInputComponent(new DefaultInputFile("module1", "test/FooTest.java").setLines(4)); + resourceCache.add(testFile, dir).setInputComponent(new TestInputFileBuilder("module1", "test/FooTest.java").setLines(4).build()); ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef); @@ -118,7 +118,7 @@ public class ComponentsPublisherTest { assertThat(module1Protobuf.getDescription()).isEqualTo("Module description"); assertThat(module1Protobuf.getVersion()).isEqualTo("1.0"); } - + @Test public void add_components_without_version_and_name() throws IOException { ProjectDefinition rootDef = ProjectDefinition.create().setKey("foo"); @@ -141,17 +141,17 @@ public class ComponentsPublisherTest { org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", FakeJava.INSTANCE, false); file.setEffectiveKey("module1:src/Foo.java"); file.setId(4).setUuid("FILE_UUID"); - resourceCache.add(file, dir).setInputComponent(new DefaultInputFile("module1", "src/Foo.java").setLines(2)); + resourceCache.add(file, dir).setInputComponent(new TestInputFileBuilder("module1", "src/Foo.java").setLines(2).build()); org.sonar.api.resources.File fileWithoutLang = org.sonar.api.resources.File.create("src/make", null, false); fileWithoutLang.setEffectiveKey("module1:src/make"); fileWithoutLang.setId(5).setUuid("FILE_WITHOUT_LANG_UUID"); - resourceCache.add(fileWithoutLang, dir).setInputComponent(new DefaultInputFile("module1", "src/make").setLines(10)); + resourceCache.add(fileWithoutLang, dir).setInputComponent(new TestInputFileBuilder("module1", "src/make").setLines(10).build()); org.sonar.api.resources.File testFile = org.sonar.api.resources.File.create("test/FooTest.java", FakeJava.INSTANCE, true); testFile.setEffectiveKey("module1:test/FooTest.java"); testFile.setId(6).setUuid("TEST_FILE_UUID"); - resourceCache.add(testFile, dir).setInputComponent(new DefaultInputFile("module1", "test/FooTest.java").setLines(4)); + resourceCache.add(testFile, dir).setInputComponent(new TestInputFileBuilder("module1", "test/FooTest.java").setLines(4).build()); ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef); @@ -214,7 +214,7 @@ public class ComponentsPublisherTest { org.sonar.api.resources.File file = org.sonar.api.resources.File.create("src/Foo.java", FakeJava.INSTANCE, false); file.setEffectiveKey("module1:my_branch:my_branch:src/Foo.java"); file.setId(4).setUuid("FILE_UUID"); - resourceCache.add(file, dir).setInputComponent(new DefaultInputFile("module1", "src/Foo.java").setLines(2)); + resourceCache.add(file, dir).setInputComponent(new TestInputFileBuilder("module1", "src/Foo.java").setLines(2).build()); ImmutableProjectReactor reactor = new ImmutableProjectReactor(rootDef); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java index 95757460e10..067169696e4 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/CoveragePublisherTest.java @@ -25,8 +25,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.resources.Project; @@ -58,7 +58,7 @@ public class CoveragePublisherTest { BatchComponentCache resourceCache = new BatchComponentCache(); sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"); resourceCache.add(p, null).setInputComponent(new DefaultInputModule("foo")); - resourceCache.add(sampleFile, null).setInputComponent(new DefaultInputFile("foo", "src/Foo.php").setLines(5)); + resourceCache.add(sampleFile, null).setInputComponent(new TestInputFileBuilder("foo", "src/Foo.php").setLines(5).build()); measureCache = mock(MeasureCache.class); when(measureCache.byMetric(anyString(), anyString())).thenReturn(null); publisher = new CoveragePublisher(resourceCache, measureCache); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java index 190907e001d..6ee89c3e5b9 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/MeasuresPublisherTest.java @@ -28,8 +28,8 @@ import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.resources.Project; @@ -69,7 +69,7 @@ public class MeasuresPublisherTest { BatchComponentCache resourceCache = new BatchComponentCache(); sampleFile = org.sonar.api.resources.File.create("src/Foo.php").setEffectiveKey(FILE_KEY); resourceCache.add(p, null).setInputComponent(new DefaultInputModule("foo")); - resourceCache.add(sampleFile, null).setInputComponent(new DefaultInputFile("foo", "src/Foo.php")); + resourceCache.add(sampleFile, null).setInputComponent(new TestInputFileBuilder("foo", "src/Foo.php").build()); measureCache = mock(MeasureCache.class); when(measureCache.byComponentKey(anyString())).thenReturn(Collections.<DefaultMeasure<?>>emptyList()); publisher = new MeasuresPublisher(resourceCache, measureCache, mock(TestPlanBuilder.class)); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java index e16b36173ef..0ecc47a1088 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/report/SourcePublisherTest.java @@ -28,8 +28,8 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.resources.Project; import org.sonar.api.resources.Qualifiers; import org.sonar.scanner.index.BatchComponentCache; @@ -61,7 +61,11 @@ public class SourcePublisherTest { File baseDir = temp.newFolder(); sourceFile = new File(baseDir, "src/Foo.php"); resourceCache.add(sampleFile, null).setInputComponent( - new DefaultInputFile("foo", "src/Foo.php").setLines(5).setModuleBaseDir(baseDir.toPath()).setCharset(StandardCharsets.ISO_8859_1)); + new TestInputFileBuilder("foo", "src/Foo.php") + .setLines(5) + .setModuleBaseDir(baseDir.toPath()) + .setCharset(StandardCharsets.ISO_8859_1) + .build()); publisher = new SourcePublisher(resourceCache); File outputDir = temp.newFolder(); writer = new ScannerReportWriter(outputDir); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java index 4d4e77f8814..38548c7370b 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/AdditionalFilePredicatesTest.java @@ -21,21 +21,24 @@ package org.sonar.scanner.scan.filesystem; import org.junit.Test; import org.sonar.api.batch.fs.FilePredicate; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.IndexedFile; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; import org.sonar.scanner.scan.filesystem.AdditionalFilePredicates; import static org.assertj.core.api.Assertions.assertThat; +import java.nio.file.Paths; + public class AdditionalFilePredicatesTest { @Test public void key() { FilePredicate predicate = new AdditionalFilePredicates.KeyPredicate("struts:Action.java"); - DefaultInputFile inputFile = new DefaultInputFile("struts", "Action.java"); - assertThat(predicate.apply(inputFile)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("struts", Paths.get("module"), "Action.java"); + assertThat(predicate.apply(indexedFile)).isTrue(); - inputFile = new DefaultInputFile("struts", "Filter.java"); - assertThat(predicate.apply(inputFile)).isFalse(); + indexedFile = new DefaultIndexedFile("struts", Paths.get("module"), "Filter.java"); + assertThat(predicate.apply(indexedFile)).isFalse(); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ComponentIndexerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ComponentIndexerTest.java index dc09e7942d9..0db12d01f39 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ComponentIndexerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ComponentIndexerTest.java @@ -31,6 +31,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.resources.AbstractLanguage; import org.sonar.api.resources.Directory; import org.sonar.api.resources.Languages; @@ -42,6 +43,7 @@ import org.sonar.scanner.analysis.DefaultAnalysisMode; import org.sonar.scanner.index.BatchComponent; import org.sonar.scanner.index.BatchComponentCache; import org.sonar.scanner.index.DefaultIndex; +import org.sonar.scanner.repository.ProjectRepositories; import org.sonar.scanner.scan.filesystem.ComponentIndexer; import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem; import org.sonar.scanner.scan.filesystem.FileIndexer; @@ -87,7 +89,7 @@ public class ComponentIndexerTest { public void should_index_java_files() throws IOException { Languages languages = new Languages(FakeJava.INSTANCE); ComponentIndexer indexer = createIndexer(languages); - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode); + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode, new ProjectRepositories()); fs.add(newInputFile("src/main/java/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false, Status.ADDED)); fs.add(newInputFile("src/main/java2/foo/bar/Foo.java", "", "foo/bar/Foo.java", "java", false, Status.ADDED)); // should index even if filter is applied @@ -119,7 +121,7 @@ public class ComponentIndexerTest { public void should_index_cobol_files() throws IOException { Languages languages = new Languages(cobolLanguage); ComponentIndexer indexer = createIndexer(languages); - DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode); + DefaultModuleFileSystem fs = new DefaultModuleFileSystem(project, null, mock(FileIndexer.class), initializer, indexer, mode, new ProjectRepositories()); fs.add(newInputFile("src/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false, Status.ADDED)); fs.add(newInputFile("src2/foo/bar/Foo.cbl", "", "foo/bar/Foo.cbl", "cobol", false, Status.ADDED)); fs.add(newInputFile("src/test/foo/bar/FooTest.cbl", "", "foo/bar/FooTest.cbl", "cobol", true, Status.ADDED)); @@ -134,10 +136,11 @@ public class ComponentIndexerTest { private DefaultInputFile newInputFile(String path, String content, String sourceRelativePath, String languageKey, boolean unitTest, InputFile.Status status) throws IOException { File file = new File(baseDir, path); FileUtils.write(file, content); - return new DefaultInputFile("foo", path) + return new TestInputFileBuilder("foo", path) .setLanguage(languageKey) .setType(unitTest ? InputFile.Type.TEST : InputFile.Type.MAIN) - .setStatus(status); + .setStatus(status) + .build(); } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ExclusionFiltersTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ExclusionFiltersTest.java index 0007577b88c..748ddbe32c5 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ExclusionFiltersTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ExclusionFiltersTest.java @@ -19,34 +19,43 @@ */ package org.sonar.scanner.scan.filesystem; +import static org.assertj.core.api.Assertions.assertThat; + import java.io.File; import java.io.IOException; +import java.nio.file.Path; + +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; +import org.sonar.api.batch.fs.IndexedFile; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.config.Settings; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; import org.sonar.api.config.MapSettings; +import org.sonar.api.config.Settings; import org.sonar.api.scan.filesystem.FileExclusions; -import static org.assertj.core.api.Assertions.assertThat; - public class ExclusionFiltersTest { @Rule public TemporaryFolder temp = new TemporaryFolder(); + private Path moduleBaseDir; + + @Before + public void setUp() throws IOException { + moduleBaseDir = temp.newFolder().toPath(); + } @Test public void no_inclusions_nor_exclusions() throws IOException { ExclusionFilters filter = new ExclusionFilters(new FileExclusions(new MapSettings())); filter.prepare(); - java.io.File file = temp.newFile(); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue(); - assertThat(filter.accept(inputFile, InputFile.Type.TEST)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue(); + assertThat(filter.accept(indexedFile, InputFile.Type.TEST)).isTrue(); } @Test @@ -56,12 +65,11 @@ public class ExclusionFiltersTest { ExclusionFilters filter = new ExclusionFilters(new FileExclusions(settings)); filter.prepare(); - java.io.File file = temp.newFile(); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue(); - inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse(); + indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse(); } @Test @@ -72,13 +80,11 @@ public class ExclusionFiltersTest { filter.prepare(); - java.io.File file = temp.newFile(); - - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse(); + IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse(); - inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDto.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue(); + indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDto.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue(); } @Test @@ -91,22 +97,20 @@ public class ExclusionFiltersTest { filter.prepare(); - java.io.File file = temp.newFile(); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse(); + IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/FooDao.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse(); - inputFile = new DefaultInputFile("foo", "src/main/java/com/mycompany/Foo.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue(); + indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/com/mycompany/Foo.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue(); // source exclusions do not apply to tests - inputFile = new DefaultInputFile("foo", "src/test/java/com/mycompany/FooDao.java").setModuleBaseDir(temp.newFolder().toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.TEST)).isTrue(); + indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/test/java/com/mycompany/FooDao.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.TEST)).isTrue(); } @Test public void match_exclusion_by_absolute_path() throws IOException { - File baseDir = temp.newFile(); - File excludedFile = new File(baseDir, "src/main/java/org/bar/Bar.java"); + File excludedFile = new File(moduleBaseDir.toString(), "src/main/java/org/bar/Bar.java"); Settings settings = new MapSettings(); settings.setProperty(CoreProperties.PROJECT_INCLUSIONS_PROPERTY, "src/main/java/**/*"); @@ -115,11 +119,11 @@ public class ExclusionFiltersTest { filter.prepare(); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/main/java/org/bar/Foo.java").setModuleBaseDir(baseDir.toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isTrue(); + IndexedFile indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/org/bar/Foo.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isTrue(); - inputFile = new DefaultInputFile("foo", "src/main/java/org/bar/Bar.java").setModuleBaseDir(baseDir.toPath()); - assertThat(filter.accept(inputFile, InputFile.Type.MAIN)).isFalse(); + indexedFile = new DefaultIndexedFile("foo", moduleBaseDir, "src/main/java/org/bar/Bar.java"); + assertThat(filter.accept(indexedFile, InputFile.Type.MAIN)).isFalse(); } @Test diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java deleted file mode 100644 index d8b01f1b14e..00000000000 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * SonarQube - * Copyright (C) 2009-2016 SonarSource SA - * mailto:contact AT sonarsource DOT com - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 3 of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ -package org.sonar.scanner.scan.filesystem; - -import java.io.File; -import java.io.FileNotFoundException; -import java.nio.charset.StandardCharsets; -import org.apache.commons.io.FileUtils; -import org.junit.Assert; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; -import org.sonar.api.batch.fs.internal.FileMetadata; -import org.sonar.api.config.MapSettings; -import org.sonar.api.scan.filesystem.PathResolver; -import org.sonar.api.utils.PathUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -public class InputFileBuilderTest { - - @Rule - public TemporaryFolder temp = new TemporaryFolder(); - - LanguageDetection langDetection = mock(LanguageDetection.class); - StatusDetection statusDetection = mock(StatusDetection.class); - DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class); - - @Test - public void should_detect_charset_from_BOM() { - File basedir = new File("src/test/resources/org/sonar/scanner/scan/filesystem/"); - when(fs.baseDir()).thenReturn(basedir); - when(fs.encoding()).thenReturn(StandardCharsets.US_ASCII); - when(langDetection.language(any(InputFile.class))).thenReturn("java"); - InputFileBuilder builder = new InputFileBuilder("moduleKey", new PathResolver(), langDetection, statusDetection, fs, new MapSettings(), new FileMetadata()); - - assertThat(createAndComplete(builder, new File(basedir, "without_BOM.txt")).charset()) - .isEqualTo(StandardCharsets.US_ASCII); - assertThat(createAndComplete(builder, new File(basedir, "UTF-8.txt")).charset()) - .isEqualTo(StandardCharsets.UTF_8); - assertThat(createAndComplete(builder, new File(basedir, "UTF-16BE.txt")).charset()) - .isEqualTo(StandardCharsets.UTF_16BE); - assertThat(createAndComplete(builder, new File(basedir, "UTF-16LE.txt")).charset()) - .isEqualTo(StandardCharsets.UTF_16LE); - assertThat(createAndComplete(builder, new File(basedir, "UTF-32BE.txt")).charset()) - .isEqualTo(InputFileBuilder.UTF_32BE); - assertThat(createAndComplete(builder, new File(basedir, "UTF-32LE.txt")).charset()) - .isEqualTo(InputFileBuilder.UTF_32LE); - - try { - createAndComplete(builder, new File(basedir, "non_existing")); - Assert.fail(); - } catch (IllegalStateException e) { - assertThat(e.getMessage()).isEqualTo("Unable to read file " + new File(basedir, "non_existing").getAbsolutePath()); - assertThat(e.getCause()).isInstanceOf(FileNotFoundException.class); - } - } - - private static DefaultInputFile createAndComplete(InputFileBuilder builder, File file) { - DefaultInputFile inputFile = builder.create(file); - builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN); - return inputFile; - } - - @Test - public void complete_input_file() throws Exception { - // file system - File basedir = temp.newFolder(); - File srcFile = new File(basedir, "src/main/java/foo/Bar.java"); - FileUtils.touch(srcFile); - FileUtils.write(srcFile, "single line"); - when(fs.baseDir()).thenReturn(basedir); - when(fs.encoding()).thenReturn(StandardCharsets.UTF_8); - - // lang - when(langDetection.language(any(InputFile.class))).thenReturn("java"); - - // status - when(statusDetection.status("foo", "src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a")) - .thenReturn(InputFile.Status.ADDED); - - InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), - langDetection, statusDetection, fs, new MapSettings(), new FileMetadata()); - DefaultInputFile inputFile = builder.create(srcFile); - builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN); - - assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN); - assertThat(inputFile.file()).isEqualTo(srcFile.getAbsoluteFile()); - assertThat(inputFile.absolutePath()).isEqualTo(PathUtils.sanitize(srcFile.getAbsolutePath())); - assertThat(inputFile.language()).isEqualTo("java"); - assertThat(inputFile.key()).isEqualTo("struts:src/main/java/foo/Bar.java"); - assertThat(inputFile.relativePath()).isEqualTo("src/main/java/foo/Bar.java"); - assertThat(inputFile.lines()).isEqualTo(1); - } - - @Test - public void return_null_if_file_outside_basedir() throws Exception { - // file system - File basedir = temp.newFolder(); - File otherDir = temp.newFolder(); - File srcFile = new File(otherDir, "src/main/java/foo/Bar.java"); - FileUtils.touch(srcFile); - when(fs.baseDir()).thenReturn(basedir); - - InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), - langDetection, statusDetection, fs, new MapSettings(), new FileMetadata()); - DefaultInputFile inputFile = builder.create(srcFile); - - assertThat(inputFile).isNull(); - } - - @Test - public void return_null_if_language_not_detected() throws Exception { - // file system - File basedir = temp.newFolder(); - File srcFile = new File(basedir, "src/main/java/foo/Bar.java"); - FileUtils.touch(srcFile); - FileUtils.write(srcFile, "single line"); - when(fs.baseDir()).thenReturn(basedir); - when(fs.encoding()).thenReturn(StandardCharsets.UTF_8); - - // lang - when(langDetection.language(any(InputFile.class))).thenReturn(null); - - InputFileBuilder builder = new InputFileBuilder("struts", new PathResolver(), - langDetection, statusDetection, fs, new MapSettings(), new FileMetadata()); - DefaultInputFile inputFile = builder.create(srcFile); - inputFile = builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN); - - assertThat(inputFile).isNull(); - } - -} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputPathCacheTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputPathCacheTest.java index 7d5b242ac0d..a08039430a0 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputPathCacheTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputPathCacheTest.java @@ -28,6 +28,7 @@ import org.sonar.api.batch.fs.InputFile.Status; import org.sonar.api.batch.fs.InputFile.Type; import org.sonar.api.batch.fs.InputPath; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.scanner.scan.filesystem.InputPathCache; import java.nio.charset.StandardCharsets; @@ -49,15 +50,16 @@ public class InputPathCacheTest { @Test public void should_add_input_file() throws Exception { InputPathCache cache = new InputPathCache(); - DefaultInputFile fooFile = new DefaultInputFile("foo", "src/main/java/Foo.java").setModuleBaseDir(temp.newFolder().toPath()); + DefaultInputFile fooFile = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setModuleBaseDir(temp.newFolder().toPath()).build(); cache.put("struts", fooFile); - cache.put("struts-core", new DefaultInputFile("foo", "src/main/java/Bar.java") + cache.put("struts-core", new TestInputFileBuilder("foo", "src/main/java/Bar.java") .setLanguage("bla") .setType(Type.MAIN) .setStatus(Status.ADDED) .setLines(2) .setCharset(StandardCharsets.UTF_8) - .setModuleBaseDir(temp.newFolder().toPath())); + .setModuleBaseDir(temp.newFolder().toPath()) + .build()); DefaultInputFile loadedFile = (DefaultInputFile) cache.getFile("struts-core", "src/main/java/Bar.java"); assertThat(loadedFile.relativePath()).isEqualTo("src/main/java/Bar.java"); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java index 16e66383578..874351ee3e0 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/LanguageDetectionTest.java @@ -26,8 +26,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.CoreProperties; -import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; import org.sonar.api.config.Settings; import org.sonar.api.config.MapSettings; import org.sonar.api.resources.Language; @@ -61,23 +60,23 @@ public class LanguageDetectionTest { LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("java", "java", "jav"), new MockLanguage("cobol", "cbl", "cob"))); LanguageDetection detection = new LanguageDetection(new MapSettings(), languages); - assertThat(detection.language(newInputFile("Foo.java"))).isEqualTo("java"); - assertThat(detection.language(newInputFile("src/Foo.java"))).isEqualTo("java"); - assertThat(detection.language(newInputFile("Foo.JAVA"))).isEqualTo("java"); - assertThat(detection.language(newInputFile("Foo.jav"))).isEqualTo("java"); - assertThat(detection.language(newInputFile("Foo.Jav"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("Foo.java"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("src/Foo.java"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("Foo.JAVA"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("Foo.jav"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("Foo.Jav"))).isEqualTo("java"); - assertThat(detection.language(newInputFile("abc.cbl"))).isEqualTo("cobol"); - assertThat(detection.language(newInputFile("abc.CBL"))).isEqualTo("cobol"); + assertThat(detection.language(newIndexedFile("abc.cbl"))).isEqualTo("cobol"); + assertThat(detection.language(newIndexedFile("abc.CBL"))).isEqualTo("cobol"); - assertThat(detection.language(newInputFile("abc.php"))).isNull(); - assertThat(detection.language(newInputFile("abc"))).isNull(); + assertThat(detection.language(newIndexedFile("abc.php"))).isNull(); + assertThat(detection.language(newIndexedFile("abc"))).isNull(); } @Test public void should_not_fail_if_no_language() throws Exception { LanguageDetection detection = spy(new LanguageDetection(new MapSettings(), new DefaultLanguagesRepository(new Languages()))); - assertThat(detection.language(newInputFile("Foo.java"))).isNull(); + assertThat(detection.language(newIndexedFile("Foo.java"))).isNull(); } @Test @@ -85,7 +84,7 @@ public class LanguageDetectionTest { LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("abap", "abap", "ABAP"))); LanguageDetection detection = new LanguageDetection(new MapSettings(), languages); - assertThat(detection.language(newInputFile("abc.abap"))).isEqualTo("abap"); + assertThat(detection.language(newIndexedFile("abc.abap"))).isEqualTo("abap"); } @Test @@ -96,16 +95,16 @@ public class LanguageDetectionTest { // No side-effect on non-ABAP projects LanguageDetection detection = new LanguageDetection(new MapSettings(), languages); - assertThat(detection.language(newInputFile("abc"))).isNull(); - assertThat(detection.language(newInputFile("abc.abap"))).isNull(); - assertThat(detection.language(newInputFile("abc.java"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("abc"))).isNull(); + assertThat(detection.language(newIndexedFile("abc.abap"))).isNull(); + assertThat(detection.language(newIndexedFile("abc.java"))).isEqualTo("java"); Settings settings = new MapSettings(); settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "abap"); detection = new LanguageDetection(settings, languages); - assertThat(detection.language(newInputFile("abc"))).isEqualTo("abap"); - assertThat(detection.language(newInputFile("abc.txt"))).isEqualTo("abap"); - assertThat(detection.language(newInputFile("abc.java"))).isEqualTo("abap"); + assertThat(detection.language(newIndexedFile("abc"))).isEqualTo("abap"); + assertThat(detection.language(newIndexedFile("abc.txt"))).isEqualTo("abap"); + assertThat(detection.language(newIndexedFile("abc.java"))).isEqualTo("abap"); } @Test @@ -115,10 +114,10 @@ public class LanguageDetectionTest { Settings settings = new MapSettings(); settings.setProperty(CoreProperties.PROJECT_LANGUAGE_PROPERTY, "java"); LanguageDetection detection = new LanguageDetection(settings, languages); - assertThat(detection.language(newInputFile("abc"))).isNull(); - assertThat(detection.language(newInputFile("abc.php"))).isNull(); - assertThat(detection.language(newInputFile("abc.java"))).isEqualTo("java"); - assertThat(detection.language(newInputFile("src/abc.java"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("abc"))).isNull(); + assertThat(detection.language(newIndexedFile("abc.php"))).isNull(); + assertThat(detection.language(newIndexedFile("abc.java"))).isEqualTo("java"); + assertThat(detection.language(newIndexedFile("src/abc.java"))).isEqualTo("java"); } @Test @@ -137,7 +136,7 @@ public class LanguageDetectionTest { LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("xml", "xhtml"), new MockLanguage("web", "xhtml"))); LanguageDetection detection = new LanguageDetection(new MapSettings(), languages); try { - detection.language(newInputFile("abc.xhtml")); + detection.language(newIndexedFile("abc.xhtml")); fail(); } catch (MessageException e) { assertThat(e.getMessage()) @@ -155,8 +154,8 @@ public class LanguageDetectionTest { settings.setProperty("sonar.lang.patterns.xml", "xml/**"); settings.setProperty("sonar.lang.patterns.web", "web/**"); LanguageDetection detection = new LanguageDetection(settings, languages); - assertThat(detection.language(newInputFile("xml/abc.xhtml"))).isEqualTo("xml"); - assertThat(detection.language(newInputFile("web/abc.xhtml"))).isEqualTo("web"); + assertThat(detection.language(newIndexedFile("xml/abc.xhtml"))).isEqualTo("xml"); + assertThat(detection.language(newIndexedFile("web/abc.xhtml"))).isEqualTo("web"); } @Test @@ -168,10 +167,10 @@ public class LanguageDetectionTest { LanguageDetection detection = new LanguageDetection(settings, languages); - assertThat(detection.language(newInputFile("abc.abap"))).isEqualTo("abap"); - assertThat(detection.language(newInputFile("abc.cobol"))).isEqualTo("cobol"); + assertThat(detection.language(newIndexedFile("abc.abap"))).isEqualTo("abap"); + assertThat(detection.language(newIndexedFile("abc.cobol"))).isEqualTo("cobol"); try { - detection.language(newInputFile("abc.txt")); + detection.language(newIndexedFile("abc.txt")); fail(); } catch (MessageException e) { assertThat(e.getMessage()) @@ -181,9 +180,9 @@ public class LanguageDetectionTest { } } - private InputFile newInputFile(String path) throws IOException { + private DefaultIndexedFile newIndexedFile(String path) throws IOException { File basedir = temp.newFolder(); - return new DefaultInputFile("foo", path).setModuleBaseDir(basedir.toPath()); + return new DefaultIndexedFile("foo", basedir.toPath(), path); } static class MockLanguage implements Language { diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactoryTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java index c8346db929f..26542931d04 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderFactoryTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorProviderTest.java @@ -21,30 +21,17 @@ package org.sonar.scanner.scan.filesystem; import org.junit.Test; import org.mockito.Mockito; -import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.internal.FileMetadata; -import org.sonar.api.config.MapSettings; -import org.sonar.api.scan.filesystem.PathResolver; -import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -public class InputFileBuilderFactoryTest { +public class MetadataGeneratorProviderTest { @Test public void create_builder() { - PathResolver pathResolver = new PathResolver(); - LanguageDetectionFactory langDetectionFactory = mock(LanguageDetectionFactory.class, Mockito.RETURNS_MOCKS); StatusDetectionFactory statusDetectionFactory = mock(StatusDetectionFactory.class, Mockito.RETURNS_MOCKS); - DefaultModuleFileSystem fs = mock(DefaultModuleFileSystem.class); - InputFileBuilderFactory factory = new InputFileBuilderFactory(ProjectDefinition.create().setKey("struts"), pathResolver, langDetectionFactory, - statusDetectionFactory, new MapSettings(), new FileMetadata()); - InputFileBuilder builder = factory.create(fs); - - assertThat(builder.langDetection()).isNotNull(); - assertThat(builder.statusDetection()).isNotNull(); - assertThat(builder.pathResolver()).isSameAs(pathResolver); - assertThat(builder.fs()).isSameAs(fs); - assertThat(builder.moduleKey()).isEqualTo("struts"); + MetadataGeneratorProvider factory = new MetadataGeneratorProvider(); + MetadataGenerator builder = factory.provide(statusDetectionFactory, new FileMetadata()); + //TODO } } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java new file mode 100644 index 00000000000..17f7f61a27a --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/MetadataGeneratorTest.java @@ -0,0 +1,159 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scanner.scan.filesystem; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.io.File; +import java.io.FileNotFoundException; +import java.nio.charset.StandardCharsets; + +import org.apache.commons.io.FileUtils; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultIndexedFile; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.FileMetadata; +import org.sonar.api.batch.fs.internal.Metadata; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.api.config.MapSettings; +import org.sonar.api.scan.filesystem.PathResolver; +import org.sonar.api.utils.PathUtils; + +public class MetadataGeneratorTest { + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Mock + private StatusDetection statusDetection; + @Mock + private DefaultModuleFileSystem fs; + @Mock + private FileMetadata metadata; + + private MetadataGenerator builder; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + builder = new MetadataGenerator(statusDetection, metadata); + // TODO + } + /* + * @Test + * public void should_detect_charset_from_BOM() { + * File basedir = new File("src/test/resources/org/sonar/scanner/scan/filesystem/"); + * when(fs.baseDir()).thenReturn(basedir); + * when(fs.encoding()).thenReturn(StandardCharsets.US_ASCII); + * + * assertThat(createAndComplete(builder, new File(basedir, "without_BOM.txt")).charset()) + * .isEqualTo(StandardCharsets.US_ASCII); + * assertThat(createAndComplete(builder, new File(basedir, "UTF-8.txt")).charset()) + * .isEqualTo(StandardCharsets.UTF_8); + * assertThat(createAndComplete(builder, new File(basedir, "UTF-16BE.txt")).charset()) + * .isEqualTo(StandardCharsets.UTF_16BE); + * assertThat(createAndComplete(builder, new File(basedir, "UTF-16LE.txt")).charset()) + * .isEqualTo(StandardCharsets.UTF_16LE); + * assertThat(createAndComplete(builder, new File(basedir, "UTF-32BE.txt")).charset()) + * .isEqualTo(InputFileBuilder.UTF_32BE); + * assertThat(createAndComplete(builder, new File(basedir, "UTF-32LE.txt")).charset()) + * .isEqualTo(InputFileBuilder.UTF_32LE); + * + * try { + * createAndComplete(builder, new File(basedir, "non_existing")); + * Assert.fail(); + * } catch (IllegalStateException e) { + * assertThat(e.getMessage()).isEqualTo("Unable to read file " + new File(basedir, "non_existing").getAbsolutePath()); + * assertThat(e.getCause()).isInstanceOf(FileNotFoundException.class); + * } + * } + * + * private static DefaultInputFile createAndComplete(InputFileBuilder builder, File file) { + * DefaultInputFile inputFile = new TestInputFileBuilder("module", file.toString()) + * .setMetadata() + * .build(); + * return inputFile; + * } + * + * @Test + * public void complete_input_file() throws Exception { + * // file system + * File basedir = temp.newFolder(); + * File srcFile = new File(basedir, "src/main/java/foo/Bar.java"); + * FileUtils.touch(srcFile); + * FileUtils.write(srcFile, "single line"); + * when(fs.baseDir()).thenReturn(basedir); + * when(fs.encoding()).thenReturn(StandardCharsets.UTF_8); + * + * // status + * when(statusDetection.status("foo", "src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a")) + * .thenReturn(InputFile.Status.ADDED); + * + * Metadata metadata = builder.readMetadata(srcFile); + * builder.readMetadata(inputFile); + * + * assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN); + * assertThat(inputFile.file()).isEqualTo(srcFile.getAbsoluteFile()); + * assertThat(inputFile.absolutePath()).isEqualTo(PathUtils.sanitize(srcFile.getAbsolutePath())); + * assertThat(inputFile.language()).isEqualTo("java"); + * assertThat(inputFile.key()).isEqualTo("struts:src/main/java/foo/Bar.java"); + * assertThat(inputFile.relativePath()).isEqualTo("src/main/java/foo/Bar.java"); + * assertThat(inputFile.lines()).isEqualTo(1); + * } + * + * @Test + * public void set_metadata() throws Exception { + * DefaultInputFile inputFile = new TestInputFileBuilder("module", "src/main/java/foo/Bar.java").build(); + * when() + * + * Metadata metadata = builder.readMetadata(inputFile); + * + * } + * + * @Test + * public void return_null_if_language_not_detected() throws Exception { + * // file system + * File basedir = temp.newFolder(); + * File srcFile = new File(basedir, "src/main/java/foo/Bar.java"); + * FileUtils.touch(srcFile); + * FileUtils.write(srcFile, "single line"); + * when(fs.baseDir()).thenReturn(basedir); + * when(fs.encoding()).thenReturn(StandardCharsets.UTF_8); + * + * // lang + * when(langDetection.language(any(DefaultIndexedFile.class))).thenReturn(null); + * + * InputFileBuilder builder = new InputFileBuilder(statusDetection, fs, new FileMetadata()); + * DefaultInputFile inputFile = builder.create(srcFile); + * inputFile = builder.completeAndComputeMetadata(inputFile, InputFile.Type.MAIN); + * + * assertThat(inputFile).isNull(); + * } + */ +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/ConsoleReportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/ConsoleReportTest.java index 227934bc39f..eba14f3a7b1 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/ConsoleReportTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/ConsoleReportTest.java @@ -26,7 +26,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.config.Settings; import org.sonar.api.config.MapSettings; import org.sonar.api.rule.Severity; @@ -82,7 +82,7 @@ public class ConsoleReportTest { @Test public void testNoNewIssue() { settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true"); - when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php"))); + when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/Foo.php").build())); when(issueCache.all()).thenReturn(Arrays.asList(createIssue(false, null))); report.execute(); assertDeprecated(); @@ -95,7 +95,7 @@ public class ConsoleReportTest { @Test public void testOneNewIssue() { settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true"); - when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php"))); + when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/Foo.php").build())); when(issueCache.all()).thenReturn(Arrays.asList(createIssue(true, Severity.BLOCKER))); report.execute(); assertDeprecated(); @@ -109,7 +109,7 @@ public class ConsoleReportTest { @Test public void testOneNewIssuePerSeverity() { settings.setProperty(ConsoleReport.CONSOLE_REPORT_ENABLED_KEY, "true"); - when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/Foo.php"))); + when(inputPathCache.allFiles()).thenReturn(Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/Foo.php").build())); when(issueCache.all()).thenReturn(Arrays.asList( createIssue(true, Severity.BLOCKER), createIssue(true, Severity.CRITICAL), @@ -128,11 +128,11 @@ public class ConsoleReportTest { " +1 info\n" + "\n-------------------------------------------\n\n"); } - + private void assertDeprecated() { assertThat(getLogs()).contains("Console report is deprecated"); } - + private void assertNotDeprecated() { assertThat(getLogs()).doesNotContain("Console report is deprecated"); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java index e7109daa410..c75da60b841 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/report/JSONReportTest.java @@ -36,6 +36,7 @@ import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputDir; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.rule.Rules; import org.sonar.api.batch.rule.internal.RulesBuilder; import org.sonar.api.config.Settings; @@ -81,7 +82,7 @@ public class JSONReportTest { when(server.getVersion()).thenReturn("3.6"); userRepository = mock(UserRepositoryLoader.class); DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts"); - DefaultInputFile inputFile = new DefaultInputFile("struts", "src/main/java/org/apache/struts/Action.java"); + DefaultInputFile inputFile = new TestInputFileBuilder("struts", "src/main/java/org/apache/struts/Action.java").build(); inputFile.setStatus(InputFile.Status.CHANGED); InputPathCache fileCache = mock(InputPathCache.class); when(fileCache.allFiles()).thenReturn(Arrays.<InputFile>asList(inputFile)); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java index 5ee591b3995..02867cc63ee 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scm/DefaultBlameOutputTest.java @@ -27,7 +27,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.InputComponent; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.scm.BlameLine; import org.sonar.scanner.index.BatchComponent; import org.sonar.scanner.index.BatchComponentCache; @@ -54,25 +54,25 @@ public class DefaultBlameOutputTest { @Test public void shouldNotFailIfNotSameNumberOfLines() { - InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(10); + InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(10).build(); new DefaultBlameOutput(null, null, Arrays.asList(file)).blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy"))); } @Test public void shouldFailIfNotExpectedFile() { - InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1); + InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").build(); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("It was not expected to blame file src/main/java/Foo.java"); - new DefaultBlameOutput(null, null, Arrays.<InputFile>asList(new DefaultInputFile("foo", "src/main/java/Foo2.java"))) + new DefaultBlameOutput(null, null, Arrays.<InputFile>asList(new TestInputFileBuilder("foo", "src/main/java/Foo2.java").build())) .blameResult(file, Arrays.asList(new BlameLine().revision("1").author("guy"))); } @Test public void shouldFailIfNullDate() { - InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1); + InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(1).build(); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Blame date is null for file src/main/java/Foo.java at line 1"); @@ -83,7 +83,7 @@ public class DefaultBlameOutputTest { @Test public void shouldFailIfNullRevision() { - InputFile file = new DefaultInputFile("foo", "src/main/java/Foo.java").setLines(1); + InputFile file = new TestInputFileBuilder("foo", "src/main/java/Foo.java").setLines(1).build(); thrown.expect(IllegalArgumentException.class); thrown.expectMessage("Blame revision is blank for file src/main/java/Foo.java at line 1"); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java index 715c779c7e1..b2ed93632e8 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java @@ -28,8 +28,8 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentCaptor; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.measure.MetricFinder; import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; @@ -93,7 +93,7 @@ public class DefaultSensorStorageTest { @Test public void shouldFailIfUnknownMetric() { - InputFile file = new DefaultInputFile("foo", "src/Foo.php"); + InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build(); thrown.expect(UnsupportedOperationException.class); thrown.expectMessage("Unknown metric: lines"); @@ -106,7 +106,7 @@ public class DefaultSensorStorageTest { @Test public void shouldSaveFileMeasureToSensorContext() { - InputFile file = new DefaultInputFile("foo", "src/Foo.php"); + InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build(); ArgumentCaptor<DefaultMeasure> argumentCaptor = ArgumentCaptor.forClass(DefaultMeasure.class); Resource sonarFile = File.create("src/Foo.php").setEffectiveKey("foo:src/Foo.php"); @@ -144,8 +144,8 @@ public class DefaultSensorStorageTest { @Test(expected = UnsupportedOperationException.class) public void duplicateHighlighting() throws Exception { Resource sonarFile = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java"); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java") - .setModuleBaseDir(temp.newFolder().toPath()); + InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .setModuleBaseDir(temp.newFolder().toPath()).build(); componentCache.add(sonarFile, null).setInputComponent(inputFile); DefaultHighlighting h = new DefaultHighlighting(null) .onFile(inputFile); @@ -156,8 +156,8 @@ public class DefaultSensorStorageTest { @Test(expected = UnsupportedOperationException.class) public void duplicateSymbolTable() throws Exception { Resource sonarFile = File.create("src/Foo.java").setEffectiveKey("foo:src/Foo.java"); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.java") - .setModuleBaseDir(temp.newFolder().toPath()); + InputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.java") + .setModuleBaseDir(temp.newFolder().toPath()).build(); componentCache.add(sonarFile, null).setInputComponent(inputFile); DefaultSymbolTable st = new DefaultSymbolTable(null) .onFile(inputFile); @@ -173,7 +173,7 @@ public class DefaultSensorStorageTest { @Test public void shouldValidateStrictlyPositiveLine() throws Exception { - DefaultInputFile file = new DefaultInputFile("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()); + InputFile file = new TestInputFileBuilder("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()).build(); Map<Integer, Integer> map = ImmutableMap.of(0, 3); String data = KeyValueFormat.format(map); @@ -184,7 +184,7 @@ public class DefaultSensorStorageTest { @Test public void shouldValidateMaxLine() throws Exception { - DefaultInputFile file = new DefaultInputFile("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()); + InputFile file = new TestInputFileBuilder("module", "testfile").setModuleBaseDir(temp.newFolder().toPath()).build(); Map<Integer, Integer> map = ImmutableMap.of(11, 3); String data = KeyValueFormat.format(map); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorOptimizerTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorOptimizerTest.java index 3fac6d4f0e8..c5bbf5b0311 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorOptimizerTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/SensorOptimizerTest.java @@ -26,7 +26,7 @@ import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.rule.ActiveRules; import org.sonar.api.batch.rule.internal.ActiveRulesBuilder; import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor; @@ -68,7 +68,7 @@ public class SensorOptimizerTest { .onlyOnLanguages("java", "php"); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); - fs.add(new DefaultInputFile("foo", "src/Foo.java").setLanguage("java")); + fs.add(new TestInputFileBuilder("foo", "src/Foo.java").setLanguage("java").build()); assertThat(optimizer.shouldExecute(descriptor)).isTrue(); } @@ -78,10 +78,10 @@ public class SensorOptimizerTest { .onlyOnFileType(InputFile.Type.MAIN); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); - fs.add(new DefaultInputFile("foo", "tests/FooTest.java").setType(InputFile.Type.TEST)); + fs.add(new TestInputFileBuilder("foo", "tests/FooTest.java").setType(InputFile.Type.TEST).build()); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); - fs.add(new DefaultInputFile("foo", "src/Foo.java").setType(InputFile.Type.MAIN)); + fs.add(new TestInputFileBuilder("foo", "src/Foo.java").setType(InputFile.Type.MAIN).build()); assertThat(optimizer.shouldExecute(descriptor)).isTrue(); } @@ -92,11 +92,11 @@ public class SensorOptimizerTest { .onlyOnFileType(InputFile.Type.MAIN); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); - fs.add(new DefaultInputFile("foo", "tests/FooTest.java").setLanguage("java").setType(InputFile.Type.TEST)); - fs.add(new DefaultInputFile("foo", "src/Foo.cbl").setLanguage("cobol").setType(InputFile.Type.MAIN)); + fs.add(new TestInputFileBuilder("foo", "tests/FooTest.java").setLanguage("java").setType(InputFile.Type.TEST).build()); + fs.add(new TestInputFileBuilder("foo", "src/Foo.cbl").setLanguage("cobol").setType(InputFile.Type.MAIN).build()); assertThat(optimizer.shouldExecute(descriptor)).isFalse(); - fs.add(new DefaultInputFile("foo", "src/Foo.java").setLanguage("java").setType(InputFile.Type.MAIN)); + fs.add(new TestInputFileBuilder("foo", "src/Foo.java").setLanguage("java").setType(InputFile.Type.MAIN).build()); assertThat(optimizer.shouldExecute(descriptor)).isTrue(); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/coverage/CoverageExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/coverage/CoverageExclusionsTest.java index 68d4080cb9b..4171333b655 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/coverage/CoverageExclusionsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/coverage/CoverageExclusionsTest.java @@ -22,7 +22,7 @@ package org.sonar.scanner.sensor.coverage; import org.junit.Before; import org.junit.Test; import org.sonar.api.batch.fs.InputFile; -import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.config.MapSettings; import org.sonar.api.config.PropertyDefinitions; import org.sonar.api.config.Settings; @@ -43,7 +43,7 @@ public class CoverageExclusionsTest { @Test public void shouldExcludeFileBasedOnPattern() { - InputFile file = new DefaultInputFile("foo", "src/org/polop/File.php"); + InputFile file = new TestInputFileBuilder("foo", "src/org/polop/File.php").build(); settings.setProperty("sonar.coverage.exclusions", "src/org/polop/*"); coverageExclusions.initPatterns(); assertThat(coverageExclusions.isExcluded(file)).isTrue(); @@ -51,7 +51,7 @@ public class CoverageExclusionsTest { @Test public void shouldNotExcludeFileBasedOnPattern() { - InputFile file = new DefaultInputFile("foo", "src/org/polop/File.php"); + InputFile file = new TestInputFileBuilder("foo", "src/org/polop/File.php").build(); settings.setProperty("sonar.coverage.exclusions", "src/org/other/*"); coverageExclusions.initPatterns(); assertThat(coverageExclusions.isExcluded(file)).isFalse(); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/CodeColorizersTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/CodeColorizersTest.java index 22f8d2b98de..6a19804649b 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/CodeColorizersTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/CodeColorizersTest.java @@ -29,8 +29,8 @@ import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.FileMetadata; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.highlighting.NewHighlighting; import org.sonar.api.batch.sensor.highlighting.TypeOfText; import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; @@ -125,8 +125,9 @@ public class CodeColorizersTest { File htmlFile = new File(this.getClass().getResource("CodeColorizersTest/package.html").toURI()); SensorStorage sensorStorage = mock(SensorStorage.class); DefaultHighlighting highlighting = new DefaultHighlighting(sensorStorage); - highlighting.onFile(new DefaultInputFile("FOO", "package.html") - .initMetadata(new FileMetadata().readMetadata(htmlFile, StandardCharsets.UTF_8))); + highlighting.onFile(new TestInputFileBuilder("FOO", "package.html") + .setMetadata(new FileMetadata().readMetadata(htmlFile, StandardCharsets.UTF_8)) + .build()); codeColorizers.toSyntaxHighlighting(htmlFile, StandardCharsets.UTF_8, "web", highlighting); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultHighlightableTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultHighlightableTest.java index 9f4672a80a8..af830bc9cdb 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultHighlightableTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultHighlightableTest.java @@ -25,6 +25,7 @@ import org.junit.rules.ExpectedException; import org.mockito.ArgumentCaptor; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.scanner.source.DefaultHighlightable; @@ -41,8 +42,9 @@ public class DefaultHighlightableTest { @Test public void should_store_highlighting_rules() { SensorStorage sensorStorage = mock(SensorStorage.class); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php") - .initMetadata("azerty\nbla bla"); + DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata("azerty\nbla bla") + .build(); DefaultHighlightable highlightablePerspective = new DefaultHighlightable(inputFile, sensorStorage, mock(AnalysisMode.class)); highlightablePerspective.newHighlighting().highlight(0, 6, "k").highlight(7, 10, "cppd").done(); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultSymbolizableTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultSymbolizableTest.java index 2e199df452d..5c0230035e4 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultSymbolizableTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DefaultSymbolizableTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.mockito.ArgumentCaptor; import org.sonar.api.batch.AnalysisMode; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.source.Symbol; import org.sonar.api.source.Symbolizable; @@ -40,8 +41,8 @@ public class DefaultSymbolizableTest { public void should_update_cache_when_done() { DefaultSensorStorage sensorStorage = mock(DefaultSensorStorage.class); - DefaultInputFile inputFile = new DefaultInputFile("foo", "src/Foo.php") - .initMetadata(Strings.repeat("azerty\n", 20)); + DefaultInputFile inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata(Strings.repeat("azerty\n", 20)).build(); DefaultSymbolizable symbolPerspective = new DefaultSymbolizable(inputFile, sensorStorage, mock(AnalysisMode.class)); Symbolizable.SymbolTableBuilder symbolTableBuilder = symbolPerspective.newSymbolTableBuilder(); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DeprecatedDefaultSymbolTableTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DeprecatedDefaultSymbolTableTest.java index 88f55e1e3f2..99188f4d6dd 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DeprecatedDefaultSymbolTableTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/DeprecatedDefaultSymbolTableTest.java @@ -27,6 +27,7 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.sonar.api.batch.fs.TextRange; import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable; import org.sonar.api.source.Symbol; import org.sonar.api.source.Symbolizable; @@ -42,8 +43,9 @@ public class DeprecatedDefaultSymbolTableTest { @Before public void prepare() { - inputFile = new DefaultInputFile("foo", "src/Foo.php") - .initMetadata(Strings.repeat("azerty\n", 20)); + inputFile = new TestInputFileBuilder("foo", "src/Foo.php") + .initMetadata(Strings.repeat("azerty\n", 20)) + .build(); } @Test diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/HighlightableBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/HighlightableBuilderTest.java index f68fe762e42..4aafebd7719 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/HighlightableBuilderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/HighlightableBuilderTest.java @@ -21,8 +21,8 @@ package org.sonar.scanner.source; import org.junit.Test; import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.batch.sensor.internal.SensorStorage; import org.sonar.api.source.Highlightable; @@ -34,7 +34,7 @@ public class HighlightableBuilderTest { @Test public void should_load_default_perspective() { HighlightableBuilder builder = new HighlightableBuilder(mock(SensorStorage.class), mock(AnalysisMode.class)); - Highlightable perspective = builder.loadPerspective(Highlightable.class, new DefaultInputFile("foo", "foo.c")); + Highlightable perspective = builder.loadPerspective(Highlightable.class, new TestInputFileBuilder("foo", "foo.c").build()); assertThat(perspective).isNotNull().isInstanceOf(DefaultHighlightable.class); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/SymbolizableBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/SymbolizableBuilderTest.java index 9a5e2edbc9f..7496ce162d4 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/SymbolizableBuilderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/source/SymbolizableBuilderTest.java @@ -21,8 +21,8 @@ package org.sonar.scanner.source; import org.junit.Test; import org.sonar.api.batch.AnalysisMode; -import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.DefaultInputModule; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; import org.sonar.api.component.Perspective; import org.sonar.api.source.Symbolizable; import org.sonar.scanner.sensor.DefaultSensorStorage; @@ -35,7 +35,7 @@ public class SymbolizableBuilderTest { @Test public void should_load_perspective() { SymbolizableBuilder perspectiveBuilder = new SymbolizableBuilder(mock(DefaultSensorStorage.class), mock(AnalysisMode.class)); - Perspective perspective = perspectiveBuilder.loadPerspective(Symbolizable.class, new DefaultInputFile("foo", "foo.c")); + Perspective perspective = perspectiveBuilder.loadPerspective(Symbolizable.class, new TestInputFileBuilder("foo", "foo.c").build()); assertThat(perspective).isInstanceOf(Symbolizable.class); } |