@@ -26,22 +26,22 @@ import java.nio.charset.Charset; | |||
import java.nio.file.Files; | |||
import java.nio.file.Path; | |||
import javax.annotation.CheckForNull; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.TestInputFileBuilder; | |||
/** | |||
* This layer over {@link java.io.File} adds information for code analyzers. | |||
* For unit testing purpose you can create some {@link DefaultInputFile} and initialize | |||
* all fields using | |||
* For unit testing purpose, use {@link TestInputFileBuilder} and initialize | |||
* the needed fields: | |||
* | |||
* <pre> | |||
* new DefaultInputFile("moduleKey", "relative/path/from/module/baseDir.java") | |||
* new TestInputFileBuilder("moduleKey", "relative/path/from/module/baseDir.java") | |||
* .setModuleBaseDir(path) | |||
* .initMetadata(new FileMetadata().readMetadata(someReader)); | |||
* .build(); | |||
* </pre> | |||
* | |||
* @since 4.2 | |||
*/ | |||
public interface InputFile extends IndexedFile, InputPath { | |||
public interface InputFile extends IndexedFile { | |||
enum Type { | |||
MAIN, TEST |
@@ -35,6 +35,7 @@ import java.util.Map; | |||
import java.util.SortedSet; | |||
import java.util.TreeSet; | |||
import java.util.function.Predicate; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.StreamSupport; | |||
import javax.annotation.Nullable; | |||
@@ -163,7 +164,7 @@ public class DefaultFileSystem implements FileSystem { | |||
Iterable<InputFile> iterable = OptimizedFilePredicateAdapter.create(predicate).get(cache); | |||
if (defaultPredicate != null) { | |||
return StreamSupport.stream(iterable.spliterator(), false) | |||
.filter(defaultPredicate::test)::iterator; | |||
.filter(defaultPredicate::test).collect(Collectors.toList()); | |||
} | |||
return iterable; | |||
} | |||
@@ -202,7 +203,7 @@ public class DefaultFileSystem implements FileSystem { | |||
cache.add(inputDir); | |||
return this; | |||
} | |||
/** | |||
* Adds a language to the list. To be used only for unit tests that need to use {@link #languages()} without | |||
* using {@link #add(InputFile)}. | |||
@@ -275,10 +276,12 @@ public class DefaultFileSystem implements FileSystem { | |||
return filesByNameCache.get(filename); | |||
} | |||
@Override public Iterable<InputFile> getFilesByExtension(String extension) { | |||
@Override | |||
public Iterable<InputFile> getFilesByExtension(String extension) { | |||
return filesByExtensionCache.get(extension); | |||
} | |||
@Override | |||
protected void doAdd(InputFile inputFile) { | |||
fileMap.put(inputFile.relativePath(), inputFile); | |||
filesByNameCache.put(FilenamePredicate.getFilename(inputFile), inputFile); |
@@ -33,6 +33,7 @@ import org.sonar.api.batch.fs.TextRange; | |||
/** | |||
* @since 4.2 | |||
* To create {@link InputFile} in tests, use {@link TestInputFileBuilder}. | |||
*/ | |||
public class DefaultInputFile extends DefaultInputComponent implements InputFile { | |||
private final DefaultIndexedFile indexedFile; |
@@ -28,6 +28,11 @@ import javax.annotation.Nullable; | |||
import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.utils.PathUtils; | |||
/** | |||
* Intended to be used in unit tests that need to create {@link InputFile}s. | |||
* | |||
* @since 6.3 | |||
*/ | |||
public class TestInputFileBuilder { | |||
private static int batchId = 1; | |||
@@ -20,6 +20,7 @@ | |||
package org.sonar.api.batch.sensor.internal; | |||
import com.google.common.collect.ImmutableMap; | |||
import java.io.File; | |||
import java.io.Serializable; | |||
import java.nio.file.Path; | |||
@@ -39,6 +40,7 @@ import org.sonar.api.batch.fs.InputFile; | |||
import org.sonar.api.batch.fs.InputModule; | |||
import org.sonar.api.batch.fs.TextRange; | |||
import org.sonar.api.batch.fs.internal.DefaultFileSystem; | |||
import org.sonar.api.batch.fs.internal.DefaultInputFile; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.api.batch.fs.internal.DefaultTextPointer; | |||
import org.sonar.api.batch.rule.ActiveRules; | |||
@@ -340,6 +342,7 @@ public class SensorContextTester implements SensorContext { | |||
@Override | |||
public void markForPublishing(InputFile inputFile) { | |||
DefaultInputFile file = (DefaultInputFile) inputFile; | |||
file.setPublish(true); | |||
} | |||
} |
@@ -27,6 +27,7 @@ import org.junit.rules.TemporaryFolder; | |||
import java.io.File; | |||
import java.nio.charset.Charset; | |||
import java.util.Iterator; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -107,6 +108,20 @@ public class DefaultFileSystemTest { | |||
assertThat(fs.languages()).containsOnly("java", "php"); | |||
} | |||
@Test | |||
public void filesWithDefaultPredicate() { | |||
DefaultInputFile file1 = new TestInputFileBuilder("foo", "src/Foo.php").setLanguage("php").build(); | |||
fs.add(file1); | |||
fs.add(new TestInputFileBuilder("foo", "src/Bar.java").setLanguage("java").build()); | |||
fs.add(new TestInputFileBuilder("foo", "src/Baz.java").setLanguage("java").build()); | |||
fs.setDefaultPredicate(f -> f.relativePath().endsWith("Foo.php")); | |||
Iterator<File> iterator = fs.files(fs.predicates().all()).iterator(); | |||
assertThat(iterator.hasNext()).isTrue(); | |||
assertThat(iterator.next()).isEqualTo(file1.file()); | |||
assertThat(iterator.hasNext()).isFalse(); | |||
} | |||
@Test | |||
public void input_file_returns_null_if_file_not_found() { | |||
assertThat(fs.inputFile(fs.predicates().hasRelativePath("src/Bar.java"))).isNull(); |
@@ -19,7 +19,6 @@ | |||
*/ | |||
package org.sonar.scanner.phases; | |||
import org.sonar.api.batch.SensorContext; | |||
import org.sonar.api.batch.fs.internal.DefaultInputModule; | |||
import org.sonar.scanner.events.BatchStepEvent; | |||
@@ -73,14 +72,13 @@ public abstract class AbstractPhaseExecutor { | |||
initIssueExclusions(); | |||
sensorsExecutor.execute(sensorContext); | |||
afterSensors(); | |||
if (module.definition().getParent() == null) { | |||
executeOnRoot(); | |||
postJobsExecutor.execute(sensorContext); | |||
} | |||
cleanMemory(); | |||
eventBus.fireEvent(new ProjectAnalysisEvent(module, false)); | |||
} | |||
@@ -109,11 +107,4 @@ public abstract class AbstractPhaseExecutor { | |||
initializersExecutor.execute(); | |||
fsLogger.log(); | |||
} | |||
private void cleanMemory() { | |||
String cleanMemory = "Clean memory"; | |||
eventBus.fireEvent(new BatchStepEvent(cleanMemory, true)); | |||
// index.clear(); | |||
eventBus.fireEvent(new BatchStepEvent(cleanMemory, false)); | |||
} | |||
} |
@@ -39,12 +39,12 @@ public class DefaultPostJobContext implements PostJobContext { | |||
private final Settings settings; | |||
private final IssueCache cache; | |||
private final AnalysisMode analysisMode; | |||
private InputComponentStore inputComponentCache; | |||
private InputComponentStore inputComponentStore; | |||
public DefaultPostJobContext(Settings settings, IssueCache cache, InputComponentStore inputComponentCache, AnalysisMode analysisMode) { | |||
public DefaultPostJobContext(Settings settings, IssueCache cache, InputComponentStore inputComponentStore, AnalysisMode analysisMode) { | |||
this.settings = settings; | |||
this.cache = cache; | |||
this.inputComponentCache = inputComponentCache; | |||
this.inputComponentStore = inputComponentStore; | |||
this.analysisMode = analysisMode; | |||
} | |||
@@ -99,7 +99,7 @@ public class DefaultPostJobContext implements PostJobContext { | |||
@Override | |||
public InputComponent inputComponent() { | |||
return inputComponentCache.getByKey(wrapped.componentKey()); | |||
return inputComponentStore.getByKey(wrapped.componentKey()); | |||
} | |||
@Override |
@@ -37,17 +37,17 @@ import org.sonar.scanner.scan.measure.MeasureCache; | |||
public class CoveragePublisher implements ReportPublisherStep { | |||
private final InputComponentStore componentCache; | |||
private final InputComponentStore componentStore; | |||
private final MeasureCache measureCache; | |||
public CoveragePublisher(InputComponentStore componentCache, MeasureCache measureCache) { | |||
this.componentCache = componentCache; | |||
public CoveragePublisher(InputComponentStore componentStore, MeasureCache measureCache) { | |||
this.componentStore = componentStore; | |||
this.measureCache = measureCache; | |||
} | |||
@Override | |||
public void publish(ScannerReportWriter writer) { | |||
for (final DefaultInputFile inputFile : componentCache.allFilesToPublish()) { | |||
for (final DefaultInputFile inputFile : componentStore.allFilesToPublish()) { | |||
Map<Integer, LineCoverage.Builder> coveragePerLine = new LinkedHashMap<>(); | |||
int lineCount = inputFile.lines(); |
@@ -47,13 +47,13 @@ public class ConsoleReport implements Reporter { | |||
private Settings settings; | |||
private IssueCache issueCache; | |||
private InputComponentStore inputPathCache; | |||
private InputComponentStore componentStore; | |||
@VisibleForTesting | |||
public ConsoleReport(Settings settings, IssueCache issueCache, InputComponentStore inputPathCache) { | |||
public ConsoleReport(Settings settings, IssueCache issueCache, InputComponentStore componentStore) { | |||
this.settings = settings; | |||
this.issueCache = issueCache; | |||
this.inputPathCache = inputPathCache; | |||
this.componentStore = componentStore; | |||
} | |||
private static class Report { | |||
@@ -100,7 +100,7 @@ public class ConsoleReport implements Reporter { | |||
if (settings.getBoolean(CONSOLE_REPORT_ENABLED_KEY)) { | |||
LOG.warn("Console report is deprecated. Use SonarLint CLI to have local reports of issues"); | |||
Report r = new Report(); | |||
r.setNoFile(!inputPathCache.allFilesToPublish().iterator().hasNext()); | |||
r.setNoFile(!componentStore.allFilesToPublish().iterator().hasNext()); | |||
for (TrackedIssue issue : issueCache.all()) { | |||
r.process(issue); | |||
} |
@@ -42,23 +42,23 @@ public class IssuesReportBuilder { | |||
private final IssueCache issueCache; | |||
private final Rules rules; | |||
private final InputComponentStore inputComponentCache; | |||
private final InputComponentStore inputComponentStore; | |||
private final InputModuleHierarchy moduleHierarchy; | |||
private final ProjectAnalysisInfo projectAnalysisInfo; | |||
public IssuesReportBuilder(IssueCache issueCache, Rules rules, ProjectAnalysisInfo projectAnalysisInfo, InputModuleHierarchy moduleHierarchy, | |||
InputComponentStore inputComponentCache) { | |||
InputComponentStore inputComponentStore) { | |||
this.issueCache = issueCache; | |||
this.rules = rules; | |||
this.projectAnalysisInfo = projectAnalysisInfo; | |||
this.moduleHierarchy = moduleHierarchy; | |||
this.inputComponentCache = inputComponentCache; | |||
this.inputComponentStore = inputComponentStore; | |||
} | |||
public IssuesReport buildReport() { | |||
DefaultInputModule project = moduleHierarchy.root(); | |||
IssuesReport issuesReport = new IssuesReport(); | |||
issuesReport.setNoFile(!inputComponentCache.allFilesToPublish().iterator().hasNext()); | |||
issuesReport.setNoFile(!inputComponentStore.allFilesToPublish().iterator().hasNext()); | |||
issuesReport.setTitle(project.definition().getName()); | |||
issuesReport.setDate(projectAnalysisInfo.analysisDate()); | |||
@@ -71,7 +71,7 @@ public class IssuesReportBuilder { | |||
for (TrackedIssue issue : issues) { | |||
Rule rule = findRule(issue); | |||
RulePriority severity = RulePriority.valueOf(issue.severity()); | |||
InputComponent resource = inputComponentCache.getByKey(issue.componentKey()); | |||
InputComponent resource = inputComponentStore.getByKey(issue.componentKey()); | |||
if (!validate(issue, rule, resource)) { | |||
continue; | |||
} |
@@ -113,7 +113,7 @@ public final class ScmPublisher { | |||
return filesToBlame; | |||
} | |||
private void askToCopyDataFromPreviousAnalysis(DefaultInputFile f, ScannerReportWriter writer) { | |||
private static void askToCopyDataFromPreviousAnalysis(DefaultInputFile f, ScannerReportWriter writer) { | |||
Builder scmBuilder = ScannerReport.Changesets.newBuilder(); | |||
scmBuilder.setComponentRef(f.batchId()); | |||
scmBuilder.setCopyFromPrevious(true); |