SonarScanner build = SonarScanner.create().setProjectDir(ItUtils.projectDir("analysis/xoo-multi-languages"));
BuildResult result = orchestrator.executeBuild(build);
- assertThat(result.getLogs()).contains("2 files indexed");
+ // 4 files: 1 .xoo, 1.xoo2, 2 .measures
+ assertThat(result.getLogs()).contains("4 files indexed");
assertThat(result.getLogs()).contains("Quality profile for xoo: one-issue-per-line");
assertThat(result.getLogs()).contains("Quality profile for xoo2: one-issue-per-line-xoo2");
import javax.annotation.Nullable;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.batch.fs.InputPath;
-import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.Scopes;
/**
* @since 5.1
+ * @deprecated since 6.3. No longer taken into consideration as all files are always imported.
*/
+ @Deprecated
String IMPORT_UNKNOWN_FILES_KEY = "sonar.import_unknown_files";
/**
/**
* Test if provided file is valid for this predicate
*/
- boolean apply(IndexedFile inputFile);
+ boolean apply(InputFile inputFile);
}
package org.sonar.api.batch.fs.internal;
import org.sonar.api.batch.fs.FileSystem.Index;
-import org.sonar.api.batch.fs.IndexedFile;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.scan.filesystem.PathResolver;
import org.sonar.api.utils.PathUtils;
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
return path.equals(f.absolutePath());
}
package org.sonar.api.batch.fs.internal;
import com.google.common.collect.Iterables;
-import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FileSystem.Index;
import org.sonar.api.batch.fs.InputFile;
/**
- * Partial implementation of {@link FilePredicate}.
+ * Partial implementation of {@link OptimizedFilePredicate}.
* @since 5.1
*/
public abstract class AbstractFilePredicate implements OptimizedFilePredicate {
import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FileSystem.Index;
-import org.sonar.api.batch.fs.IndexedFile;
import org.sonar.api.batch.fs.InputFile;
import java.util.ArrayList;
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
for (OptimizedFilePredicate predicate : predicates) {
if (!predicate.apply(f)) {
return false;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.function.Predicate;
import java.util.stream.StreamSupport;
import javax.annotation.Nullable;
private Path workDir;
private Charset encoding;
protected final FilePredicates predicates;
- private InputFilePredicate defaultPredicate;
+ private Predicate<InputFile> defaultPredicate;
/**
* Only for testing
return this;
}
- public DefaultFileSystem setDefaultPredicate(@Nullable InputFilePredicate predicate) {
+ public DefaultFileSystem setDefaultPredicate(@Nullable Predicate<InputFile> predicate) {
this.defaultPredicate = predicate;
return this;
}
Iterable<InputFile> iterable = OptimizedFilePredicateAdapter.create(predicate).get(cache);
if (defaultPredicate != null) {
return StreamSupport.stream(iterable.spliterator(), false)
- .filter(defaultPredicate::apply)::iterator;
+ .filter(defaultPredicate::test)::iterator;
}
return iterable;
}
return dirMap.get(relativePath);
}
+ @Override
public InputModule module() {
return module;
}
private String language;
private final Type type;
+ /**
+ * Testing purposes only!
+ */
public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath) {
- this(moduleKey, moduleBaseDir, relativePath, TestInputFileBuilder.batchId++);
+ this(moduleKey, moduleBaseDir, relativePath, TestInputFileBuilder.nextBatchId());
}
public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath, int batchId) {
private Path moduleBaseDir;
public DefaultInputDir(String moduleKey, String relativePath) {
- this(moduleKey, relativePath, TestInputFileBuilder.batchId++);
+ this(moduleKey, relativePath, TestInputFileBuilder.nextBatchId());
}
public DefaultInputDir(String moduleKey, String relativePath, int batchId) {
import java.nio.charset.Charset;
import java.nio.file.Path;
import java.util.Arrays;
-import java.util.function.Function;
+import java.util.function.Consumer;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.fs.InputFile;
*/
public class DefaultInputFile extends DefaultInputComponent implements InputFile {
private final DefaultIndexedFile indexedFile;
- private final Function<DefaultInputFile, Metadata> metadataGenerator;
+ private final Consumer<DefaultInputFile> metadataGenerator;
private Status status;
private Charset charset;
private Metadata metadata;
+ private boolean publish = false;
- public DefaultInputFile(DefaultIndexedFile indexedFile, Function<DefaultInputFile, Metadata> metadataGenerator) {
+ public DefaultInputFile(DefaultIndexedFile indexedFile, Consumer<DefaultInputFile> metadataGenerator) {
super(indexedFile.batchId());
this.indexedFile = indexedFile;
this.metadataGenerator = metadataGenerator;
private void checkMetadata() {
if (metadata == null) {
- setMetadata(metadataGenerator.apply(this));
+ metadataGenerator.accept(this);
}
}
+ public void setPublish(boolean publish) {
+ this.publish = publish;
+ }
+
+ public boolean publish() {
+ return publish;
+ }
+
@Override
public String relativePath() {
return indexedFile.relativePath();
return Math.abs(Arrays.binarySearch(originalLineOffsets(), globalOffset) + 1);
}
- private DefaultInputFile setMetadata(Metadata metadata) {
+ public DefaultInputFile setMetadata(Metadata metadata) {
this.metadata = metadata;
return this;
}
private final String moduleKey;
private final ProjectDefinition definition;
+ /**
+ * For testing only!
+ */
public DefaultInputModule(String moduleKey) {
- this(ProjectDefinition.create().setKey(moduleKey), TestInputFileBuilder.batchId++);
+ this(ProjectDefinition.create().setKey(moduleKey), TestInputFileBuilder.nextBatchId());
}
public DefaultInputModule(ProjectDefinition definition, int batchId) {
import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FileSystem.Index;
-import org.sonar.api.batch.fs.IndexedFile;
import org.sonar.api.batch.fs.InputFile;
import java.util.Collections;
static final FilePredicate FALSE = new FalsePredicate();
@Override
- public boolean apply(IndexedFile inputFile) {
+ public boolean apply(InputFile inputFile) {
return false;
}
import org.sonar.api.batch.fs.InputComponent;
public interface InputComponentTree {
- public Collection<InputComponent> getChildren(InputComponent module);
+ Collection<InputComponent> getChildren(InputComponent module);
- public InputComponent getParent(InputComponent module);
+ InputComponent getParent(InputComponent module);
}
+++ /dev/null
-/*
- * 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.api.batch.fs.internal;
-
-import org.sonar.api.batch.fs.InputFile;
-
-@FunctionalInterface
-public interface InputFilePredicate {
- boolean apply(InputFile inputFile);
-}
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.InputFile;
/**
* @since 4.2
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
return language.equals(f.language());
}
}
package org.sonar.api.batch.fs.internal;
import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.InputFile;
/**
* @since 4.2
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
return !predicate.apply(f);
}
package org.sonar.api.batch.fs.internal;
import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.InputFile;
class OptimizedFilePredicateAdapter extends AbstractFilePredicate {
}
@Override
- public boolean apply(IndexedFile inputFile) {
+ public boolean apply(InputFile inputFile) {
return unoptimizedPredicate.apply(inputFile);
}
import com.google.common.annotations.VisibleForTesting;
import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.InputFile;
import java.util.ArrayList;
import java.util.Collection;
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
for (FilePredicate predicate : predicates) {
if (predicate.apply(f)) {
return true;
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.InputFile;
/**
* @since 4.2
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
return pattern.match(f);
}
package org.sonar.api.batch.fs.internal;
import org.sonar.api.batch.fs.FileSystem.Index;
-import org.sonar.api.batch.fs.IndexedFile;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.utils.PathUtils;
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
return path.equals(f.relativePath());
}
import org.sonar.api.utils.PathUtils;
public class TestInputFileBuilder {
- public static int batchId = 1;
+ private static int batchId = 1;
private final int id;
private final String relativePath;
private String hash;
private int nonBlankLines;
private int[] originalLineOffsets;
+ private boolean publish = true;
public TestInputFileBuilder(String moduleKey, String relativePath) {
this(moduleKey, relativePath, batchId++);
this.id = id;
}
+ public static int nextBatchId() {
+ return batchId++;
+ }
+
public TestInputFileBuilder setModuleBaseDir(Path moduleBaseDir) {
this.moduleBaseDir = moduleBaseDir.normalize();
return this;
return this;
}
+ public TestInputFileBuilder setPublish(boolean publish) {
+ this.publish = publish;
+ return this;
+ }
+
public TestInputFileBuilder setMetadata(Metadata metadata) {
this.setLines(metadata.lines());
this.setLastValidOffset(metadata.lastValidOffset());
public DefaultInputFile build() {
DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type, id);
indexedFile.setLanguage(language);
- DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> new Metadata(lines, nonBlankLines, hash, originalLineOffsets, lastValidOffset));
+ DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(new Metadata(lines, nonBlankLines, hash, originalLineOffsets, lastValidOffset)));
inputFile.setStatus(status);
inputFile.setCharset(charset);
+ inputFile.setPublish(publish);
return inputFile;
}
}
import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FileSystem.Index;
-import org.sonar.api.batch.fs.IndexedFile;
import org.sonar.api.batch.fs.InputFile;
class TruePredicate extends AbstractFilePredicate {
static final FilePredicate TRUE = new TruePredicate();
@Override
- public boolean apply(IndexedFile inputFile) {
+ public boolean apply(InputFile inputFile) {
return true;
}
*/
package org.sonar.api.batch.fs.internal;
-import org.sonar.api.batch.fs.IndexedFile;
import org.sonar.api.batch.fs.InputFile;
/**
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
return type == f.type();
}
import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FilePredicates;
-import org.sonar.api.batch.fs.IndexedFile;
import org.sonar.api.batch.fs.InputFile;
import java.io.File;
moduleBasePath = temp.newFolder().toPath();
}
- IndexedFile javaFile;
+ InputFile javaFile;
FilePredicates predicates;
@Before
public void before() throws IOException {
predicates = new DefaultFilePredicates(temp.newFolder().toPath());
- javaFile = new DefaultIndexedFile("foo", moduleBasePath, "src/main/java/struts/Action.java")
- .setLanguage("java");
+ javaFile = new TestInputFileBuilder("foo", "src/main/java/struts/Action.java")
+ .setModuleBaseDir(moduleBasePath)
+ .setLanguage("java")
+ .build();
}
@Test
Metadata metadata = new Metadata(42, 42, "", new int[0], 0);
DefaultIndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST, 0).setLanguage("php");
- DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> metadata)
+ DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> f.setMetadata(metadata))
.setStatus(InputFile.Status.ADDED)
.setCharset(StandardCharsets.ISO_8859_1);
Metadata metadata = new Metadata(42, 30, "", new int[0], 0);
DefaultInputFile inputFile = new DefaultInputFile(new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST, 0)
- .setLanguage("php"), f -> metadata)
+ .setLanguage("php"), f -> f.setMetadata(metadata))
.setStatus(InputFile.Status.ADDED)
.setCharset(StandardCharsets.ISO_8859_1);
@Test
public void checkValidPointer() {
Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
- DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), f -> f.setMetadata(metadata));
assertThat(file.newPointer(1, 0).line()).isEqualTo(1);
assertThat(file.newPointer(1, 0).lineOffset()).isEqualTo(0);
// Don't fail
@Test
public void checkValidPointerUsingGlobalOffset() {
Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
- DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), f -> f.setMetadata(metadata));
assertThat(file.newPointer(0).line()).isEqualTo(1);
assertThat(file.newPointer(0).lineOffset()).isEqualTo(0);
@Test
public void checkValidRange() {
Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde"));
- DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), f -> f.setMetadata(metadata));
assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 1)).start().line()).isEqualTo(1);
// Don't fail
@Test
public void selectLine() {
Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde\n\nabc"));
- DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), f -> f.setMetadata(metadata));
assertThat(file.selectLine(1).start().line()).isEqualTo(1);
assertThat(file.selectLine(1).start().lineOffset()).isEqualTo(0);
@Test
public void checkValidRangeUsingGlobalOffset() {
Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
- DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), f -> f.setMetadata(metadata));
TextRange newRange = file.newRange(10, 13);
assertThat(newRange.start().line()).isEqualTo(2);
assertThat(newRange.start().lineOffset()).isEqualTo(0);
@Test
public void testRangeOverlap() {
Metadata metadata = new Metadata(2, 2, "", new int[] {0, 10}, 15);
- DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), (f) -> metadata);
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php"), f -> f.setMetadata(metadata));
// Don't fail
assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)))).isTrue();
assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(1, 1)).overlap(file.newRange(file.newPointer(1, 0), file.newPointer(1, 2)))).isTrue();
+++ /dev/null
-package org.foo;
-
-public class ManyStatements {
-
- void foo() {
- int A1 = 0; int B = 0; int C = 0; int D = 0; int E = 0; int F = 0; int G = 0; int H = 0; int I = 0; int J = 0; int K = 0;
- int A2 = 0; int B = 0; int C = 0; int D = 0; int E = 0; int F = 0; int G = 0; int H = 0; int I = 0; int J = 0; int K = 0;
- int A1 = 0; int B = 0; int C = 0; int D = 0; int E = 0; int F = 0; int G = 0; int H = 0; int I = 0; int J = 0; int K = 0;
- }
-
-}
\ No newline at end of file
import org.sonar.scanner.scan.report.RuleNameProvider;
import org.sonar.scanner.scan.report.SourceProvider;
import org.sonar.scanner.scm.ScmConfiguration;
-import org.sonar.scanner.scm.ScmSensor;
+import org.sonar.scanner.scm.ScmPublisher;
import org.sonar.scanner.source.CodeColorizerSensor;
-import org.sonar.scanner.source.LinesSensor;
import org.sonar.scanner.source.ZeroCoverageSensor;
import org.sonar.scanner.task.ListTask;
import org.sonar.scanner.task.ScanTask;
if (!analysisMode.isIssues()) {
// SCM
components.add(ScmConfiguration.class);
- components.add(ScmSensor.class);
+ components.add(ScmPublisher.class);
- components.add(LinesSensor.class);
components.add(ZeroCoverageSensor.class);
components.add(CodeColorizerSensor.class);
}
}
- private boolean shouldKeep(Class type, Object extension, @Nullable DefaultInputModule module, @Nullable ExtensionMatcher matcher) {
+ private static boolean shouldKeep(Class type, Object extension, @Nullable DefaultInputModule module, @Nullable ExtensionMatcher matcher) {
boolean keep = (ClassUtils.isAssignable(extension.getClass(), type)
|| (org.sonar.api.batch.Sensor.class.equals(type) && ClassUtils.isAssignable(extension.getClass(), Sensor.class)))
&& (matcher == null || matcher.accept(extension));
return index.getMeasure(module.key(), metric);
}
- private String getEffectiveKey(Resource r) {
- if (r.getEffectiveKey() != null) {
- return r.getEffectiveKey();
- }
-
+ private String getComponentKey(Resource r) {
if (ResourceUtils.isProject(r) || /* For technical projects */ResourceUtils.isRootProject(r)) {
return r.getKey();
} else {
@Override
public Resource getResource(Resource resource) {
- return index.getResource(getEffectiveKey(resource));
+ return index.getResource(getComponentKey(resource));
}
@Override
public <M> M getMeasures(Resource resource, MeasuresFilter<M> filter) {
- return index.getMeasures(getEffectiveKey(resource), filter);
+ return index.getMeasures(getComponentKey(resource), filter);
}
@Override
@Override
public Measure saveMeasure(@Nullable Resource resource, Measure measure) {
Resource resourceOrProject = resourceOrProject(resource);
- return index.addMeasure(getEffectiveKey(resourceOrProject), measure);
+ return index.addMeasure(getComponentKey(resourceOrProject), measure);
}
@Override
import com.google.common.collect.Maps;
import java.util.Map;
import javax.annotation.CheckForNull;
+
+import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.component.Perspective;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.ResourceUtils;
import org.sonar.core.component.ComponentKeys;
-import org.sonar.scanner.index.DefaultIndex;
import org.sonar.scanner.scan.filesystem.InputComponentStore;
public class ScannerPerspectives implements ResourcePerspectives {
private final Map<Class<?>, PerspectiveBuilder<?>> builders = Maps.newHashMap();
- private final DefaultIndex resourceIndex;
private final InputComponentStore componentStore;
private final DefaultInputModule module;
- public ScannerPerspectives(PerspectiveBuilder[] builders, DefaultInputModule module, DefaultIndex resourceIndex, InputComponentStore componentStore) {
- this.resourceIndex = resourceIndex;
+ public ScannerPerspectives(PerspectiveBuilder[] builders, DefaultInputModule module, InputComponentStore componentStore) {
this.componentStore = componentStore;
this.module = module;
@Override
@CheckForNull
public <P extends Perspective> P as(Class<P> perspectiveClass, Resource resource) {
- Resource indexedResource = resource;
- if (resource.getEffectiveKey() == null) {
- indexedResource = resourceIndex.getResource(getEffectiveKey(resource));
- }
- if (indexedResource != null) {
+ InputComponent component = componentStore.getByKey(getComponentKey(resource));
+ if (component != null) {
PerspectiveBuilder<P> builder = builderFor(perspectiveClass);
- return builder.loadPerspective(perspectiveClass, componentStore.getByKey(indexedResource.getEffectiveKey()));
+ return builder.loadPerspective(perspectiveClass, component);
}
return null;
}
- private String getEffectiveKey(Resource r) {
- if (r.getEffectiveKey() != null) {
- return r.getEffectiveKey();
- }
-
+ private String getComponentKey(Resource r) {
if (ResourceUtils.isProject(r) || /* For technical projects */ResourceUtils.isRootProject(r)) {
return r.getKey();
} else {
import org.sonar.api.batch.fs.InputComponent;
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.test.MutableTestPlan;
import org.sonar.scanner.deprecated.perspectives.PerspectiveBuilder;
@Override
public MutableTestPlan loadPerspective(Class<MutableTestPlan> perspectiveClass, InputComponent component) {
if (component.isFile()) {
- InputFile inputFile = (InputFile) component;
+ DefaultInputFile inputFile = (DefaultInputFile) component;
if (inputFile.type() == Type.TEST) {
+ inputFile.setPublish(true);
if (!testPlanByFile.containsKey(inputFile)) {
testPlanByFile.put(inputFile, new DefaultTestPlan());
}
throw new IllegalArgumentException("Unknow input path type: " + inputComponent);
}
- r.setEffectiveKey(inputComponent.key());
return r;
}
return false;
}
- private void applyFlows(ScannerReport.Issue.Builder builder, ScannerReport.IssueLocation.Builder locationBuilder, ScannerReport.TextRange.Builder textRangeBuilder, Issue issue) {
+ private static void applyFlows(ScannerReport.Issue.Builder builder, ScannerReport.IssueLocation.Builder locationBuilder,
+ ScannerReport.TextRange.Builder textRangeBuilder, Issue issue) {
ScannerReport.Flow.Builder flowBuilder = ScannerReport.Flow.newBuilder();
for (Flow flow : issue.flows()) {
- if (!flow.locations().isEmpty()) {
- flowBuilder.clear();
- for (org.sonar.api.batch.sensor.issue.IssueLocation location : flow.locations()) {
- locationBuilder.clear();
- locationBuilder.setComponentRef(((DefaultInputComponent) location.inputComponent()).batchId());
- String message = location.message();
- if (message != null) {
- locationBuilder.setMsg(message);
- }
- TextRange textRange = location.textRange();
- if (textRange != null) {
- locationBuilder.setTextRange(toProtobufTextRange(textRangeBuilder, textRange));
- }
- flowBuilder.addLocation(locationBuilder.build());
+ if (flow.locations().isEmpty()) {
+ return;
+ }
+ flowBuilder.clear();
+ for (org.sonar.api.batch.sensor.issue.IssueLocation location : flow.locations()) {
+ locationBuilder.clear();
+ locationBuilder.setComponentRef(((DefaultInputComponent) location.inputComponent()).batchId());
+ String message = location.message();
+ if (message != null) {
+ locationBuilder.setMsg(message);
+ }
+ TextRange textRange = location.textRange();
+ if (textRange != null) {
+ locationBuilder.setTextRange(toProtobufTextRange(textRangeBuilder, textRange));
}
- builder.addFlow(flowBuilder.build());
+ flowBuilder.addLocation(locationBuilder.build());
}
+ builder.addFlow(flowBuilder.build());
}
}
*/
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;
initIssueExclusions();
sensorsExecutor.execute(sensorContext);
+
+ afterSensors();
if (module.definition().getParent() == null) {
executeOnRoot();
eventBus.fireEvent(new ProjectAnalysisEvent(module, false));
}
+ protected void afterSensors() {
+ }
+
protected abstract void executeOnRoot();
private void initIssueExclusions() {
private void cleanMemory() {
String cleanMemory = "Clean memory";
eventBus.fireEvent(new BatchStepEvent(cleanMemory, true));
- //index.clear();
+ // index.clear();
eventBus.fireEvent(new BatchStepEvent(cleanMemory, false));
}
}
import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.scanner.scan.filesystem.FileSystemLogger;
import org.sonar.scanner.scan.report.IssuesReports;
+import org.sonar.scanner.scm.ScmPublisher;
public final class IssuesPhaseExecutor extends AbstractPhaseExecutor {
import org.sonar.scanner.rule.QProfileVerifier;
import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
import org.sonar.scanner.scan.filesystem.FileSystemLogger;
+import org.sonar.scanner.scm.ScmPublisher;
public final class PublishPhaseExecutor extends AbstractPhaseExecutor {
private final EventBus eventBus;
private final ReportPublisher reportPublisher;
private final CpdExecutor cpdExecutor;
+ private final ScmPublisher scm;
public PublishPhaseExecutor(InitializersExecutor initializersExecutor, PostJobsExecutor postJobsExecutor, SensorsExecutor sensorsExecutor, SensorContext sensorContext,
EventBus eventBus, ReportPublisher reportPublisher, FileSystemLogger fsLogger, DefaultModuleFileSystem fs,
- QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader, CpdExecutor cpdExecutor) {
+ QProfileVerifier profileVerifier, IssueExclusionsLoader issueExclusionsLoader, CpdExecutor cpdExecutor, ScmPublisher scm) {
super(initializersExecutor, postJobsExecutor, sensorsExecutor, sensorContext, eventBus, fsLogger, fs, profileVerifier, issueExclusionsLoader);
this.eventBus = eventBus;
this.reportPublisher = reportPublisher;
this.cpdExecutor = cpdExecutor;
+ this.scm = scm;
}
@Override
publishReportJob();
}
+ @Override
+ protected void afterSensors() {
+ scm.publish();
+ }
+
private void computeDuplications() {
String stepName = "Computing duplications";
eventBus.fireEvent(new BatchStepEvent(stepName, true));
*/
package org.sonar.scanner.report;
+import java.util.Collection;
+
import javax.annotation.CheckForNull;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.CoreProperties;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.InputPath;
import org.sonar.api.batch.fs.internal.DefaultInputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.InputComponentTree;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.core.util.CloseableIterator;
+import org.sonar.core.util.stream.Collectors;
import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.scanner.protocol.output.ScannerReport.Component.ComponentType;
import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink;
import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink.ComponentLinkType;
+import org.sonar.scanner.protocol.output.ScannerReport.Issue;
import org.sonar.scanner.protocol.output.ScannerReportWriter;
/**
private InputComponentTree componentTree;
private InputModuleHierarchy moduleHierarchy;
+ private ScannerReportReader reader;
+ private ScannerReportWriter writer;
public ComponentsPublisher(InputModuleHierarchy moduleHierarchy, InputComponentTree inputComponentTree) {
this.moduleHierarchy = moduleHierarchy;
@Override
public void publish(ScannerReportWriter writer) {
- recursiveWriteComponent((DefaultInputComponent) moduleHierarchy.root(), writer);
+ this.reader = new ScannerReportReader(writer.getFileStructure().root());
+ this.writer = writer;
+ recursiveWriteComponent((DefaultInputComponent) moduleHierarchy.root());
}
- private void recursiveWriteComponent(DefaultInputComponent component, ScannerReportWriter writer) {
+ /**
+ * Writes the tree of components recursively, deep-first.
+ * @return true if component was written (not skipped)
+ */
+ private boolean recursiveWriteComponent(DefaultInputComponent component) {
+ Collection<InputComponent> children = componentTree.getChildren(component).stream()
+ .filter(c -> recursiveWriteComponent((DefaultInputComponent) c))
+ .collect(Collectors.toList());
+
+ if (shouldSkipComponent(component, children)) {
+ return false;
+ }
+
ScannerReport.Component.Builder builder = ScannerReport.Component.newBuilder();
// non-null fields
}
if (component.isFile()) {
- InputFile file = (InputFile) component;
+ DefaultInputFile file = (DefaultInputFile) component;
builder.setIsTest(file.type() == InputFile.Type.TEST);
builder.setLines(file.lines());
builder.setPath(path);
}
- for (InputComponent child : componentTree.getChildren(component)) {
+ for (InputComponent child : children) {
builder.addChildRef(((DefaultInputComponent) child).batchId());
}
writeLinks(component, builder);
writer.writeComponent(builder.build());
+ return true;
+ }
- for (InputComponent child : componentTree.getChildren(component)) {
- recursiveWriteComponent((DefaultInputComponent) child, writer);
+ private boolean shouldSkipComponent(DefaultInputComponent component, Collection<InputComponent> children) {
+ if (component instanceof InputDir && children.isEmpty()) {
+ try (CloseableIterator<Issue> componentIssuesIt = reader.readComponentIssues(component.batchId())) {
+ if (!componentIssuesIt.hasNext()) {
+ // no file to publish on a directory without issues -> skip it
+ return true;
+ }
+ }
+ } else if (component instanceof DefaultInputFile) {
+ // skip files not marked for publishing
+ DefaultInputFile inputFile = (DefaultInputFile) component;
+ return !inputFile.publish();
}
+ return false;
}
- private void writeVersion(DefaultInputModule module, ScannerReport.Component.Builder builder) {
+ private static void writeVersion(DefaultInputModule module, ScannerReport.Component.Builder builder) {
ProjectDefinition def = module.definition();
String version = getVersion(def);
if (version != null) {
return def.getParent() != null ? getVersion(def.getParent()) : null;
}
- private void writeLinks(InputComponent c, ScannerReport.Component.Builder builder) {
+ private static void writeLinks(InputComponent c, ScannerReport.Component.Builder builder) {
if (c instanceof InputModule) {
DefaultInputModule inputModule = (DefaultInputModule) c;
ProjectDefinition def = inputModule.definition();
}
}
- private static void setValueAccordingToType(ScannerReport.Measure.Builder builder, DefaultMeasure measure) {
+ private static void setValueAccordingToType(ScannerReport.Measure.Builder builder, DefaultMeasure<?> measure) {
Serializable value = measure.value();
Metric<?> metric = measure.metric();
if (Boolean.class.equals(metric.valueType())) {
import org.sonar.api.rules.RuleQuery;
import org.sonar.core.util.stream.Collectors;
-import static org.sonar.core.util.stream.Collectors.toList;
-
public class RuleFinderCompatibility implements RuleFinder {
private final Rules rules;
import java.util.Set;
import javax.annotation.CheckForNull;
+
import org.sonar.api.batch.fs.InputComponent;
import org.sonar.api.batch.fs.internal.InputComponentTree;
+import com.google.common.base.Preconditions;
+
public class DefaultComponentTree implements InputComponentTree {
private Map<InputComponent, InputComponent> parents = new HashMap<>();
private Map<InputComponent, Set<InputComponent>> children = new HashMap<>();
public void index(InputComponent component, InputComponent parent) {
+ Preconditions.checkNotNull(component);
+ Preconditions.checkNotNull(parent);
parents.put(component, parent);
Set<InputComponent> list = children.get(parent);
if (list == null) {
import javax.annotation.CheckForNull;
-import org.sonar.api.Startable;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.scanner.scan.filesystem.BatchIdGenerator;
+import com.google.common.base.Preconditions;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;
-public class DefaultInputModuleHierarchy implements InputModuleHierarchy, Startable {
+public class DefaultInputModuleHierarchy implements InputModuleHierarchy {
private final PathResolver pathResolver = new PathResolver();
- private final ImmutableProjectReactor projectReactor;
- private final DefaultComponentTree componentTree;
- private final BatchIdGenerator batchIdGenerator;
-
private DefaultInputModule root;
- private Map<DefaultInputModule, DefaultInputModule> parents;
- private Multimap<DefaultInputModule, DefaultInputModule> children;
-
- public DefaultInputModuleHierarchy(ImmutableProjectReactor projectReactor, DefaultComponentTree componentTree, BatchIdGenerator batchIdGenerator) {
- this.projectReactor = projectReactor;
- this.componentTree = componentTree;
- this.batchIdGenerator = batchIdGenerator;
- }
-
- @Override
- public void start() {
- doStart(projectReactor.getRoot());
- }
+ private final Map<DefaultInputModule, DefaultInputModule> parents = new HashMap<>();
+ private final Multimap<DefaultInputModule, DefaultInputModule> children = HashMultimap.create();
- void doStart(ProjectDefinition rootProjectDefinition) {
- parents = new HashMap<>();
- children = HashMultimap.create();
- root = new DefaultInputModule(rootProjectDefinition, batchIdGenerator.get());
- createChildren(root);
+ public void setRoot(DefaultInputModule root) {
+ this.root = root;
}
- private void createChildren(DefaultInputModule parent) {
- for (ProjectDefinition def : parent.definition().getSubProjects()) {
- DefaultInputModule child = new DefaultInputModule(def, batchIdGenerator.get());
- parents.put(child, parent);
- children.put(parent, child);
- componentTree.index(child, parent);
- createChildren(child);
- }
+ public void index(DefaultInputModule child, DefaultInputModule parent) {
+ Preconditions.checkNotNull(child);
+ Preconditions.checkNotNull(parent);
+ parents.put(child, parent);
+ children.put(parent, child);
}
@Override
return pathResolver.relativePath(parentBaseDir, moduleBaseDir);
}
-
- @Override
- public void stop() {
- // nothing to do
- }
}
+++ /dev/null
-/*
- * 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;
-
-import org.apache.commons.lang.StringUtils;
-import org.picocontainer.Startable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.api.config.Settings;
-import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.repository.language.Language;
-import org.sonar.scanner.repository.language.LanguagesRepository;
-
-/**
- * Verifies that the property sonar.language is valid
- */
-public class LanguageVerifier implements Startable {
-
- private static final Logger LOG = LoggerFactory.getLogger(LanguageVerifier.class);
-
- private final Settings settings;
- private final LanguagesRepository languages;
- private final DefaultFileSystem fs;
-
- public LanguageVerifier(Settings settings, LanguagesRepository languages, DefaultFileSystem fs) {
- this.settings = settings;
- this.languages = languages;
- this.fs = fs;
- }
-
- @Override
- public void start() {
- String languageKey = settings.getString(CoreProperties.PROJECT_LANGUAGE_PROPERTY);
- if (StringUtils.isNotBlank(languageKey)) {
- LOG.info("Language is forced to {}", languageKey);
- Language language = languages.get(languageKey);
- if (language == null) {
- throw MessageException.of("You must install a plugin that supports the language '" + languageKey + "'");
- }
-
- // force the registration of the language, even if there are no related source files
- fs.addLanguages(languageKey);
- }
- }
-
- @Override
- public void stop() {
- // nothing to do
- }
-}
--- /dev/null
+/*
+ * 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;
+
+import org.picocontainer.Startable;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.scanner.scan.filesystem.BatchIdGenerator;
+
+public class ModuleIndexer implements Startable {
+ private final ImmutableProjectReactor projectReactor;
+ private final DefaultComponentTree componentTree;
+ private final DefaultInputModuleHierarchy moduleHierarchy;
+ private final BatchIdGenerator batchIdGenerator;
+
+ public ModuleIndexer(ImmutableProjectReactor projectReactor, DefaultComponentTree componentTree,
+ BatchIdGenerator batchIdGenerator, DefaultInputModuleHierarchy moduleHierarchy) {
+ this.projectReactor = projectReactor;
+ this.componentTree = componentTree;
+ this.moduleHierarchy = moduleHierarchy;
+ this.batchIdGenerator = batchIdGenerator;
+ }
+
+ @Override
+ public void start() {
+ DefaultInputModule root = new DefaultInputModule(projectReactor.getRoot(), batchIdGenerator.get());
+ moduleHierarchy.setRoot(root);
+ createChildren(root);
+ }
+
+ private void createChildren(DefaultInputModule parent) {
+ for (ProjectDefinition def : parent.definition().getSubProjects()) {
+ DefaultInputModule child = new DefaultInputModule(def, batchIdGenerator.get());
+ moduleHierarchy.index(child, parent);
+ componentTree.index(child, parent);
+ createChildren(child);
+ }
+ }
+
+ @Override
+ public void stop() {
+ // nothing to do
+ }
+}
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.IndexedFileBuilderProvider;
+import org.sonar.scanner.scan.filesystem.InputFileBuilder;
+import org.sonar.scanner.scan.filesystem.LanguageDetection;
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.ModuleInputComponentStore;
import org.sonar.scanner.scan.filesystem.StatusDetectionFactory;
module,
ModuleSettings.class);
- // hack to initialize settings before ExtensionProviders
- ModuleSettings moduleSettings = getComponentByType(ModuleSettings.class);
- //module.setSettings(moduleSettings);
-
if (getComponentByType(AnalysisMode.class).isIssues()) {
add(IssuesPhaseExecutor.class,
IssuesReports.class);
new MetadataGeneratorProvider(),
FileMetadata.class,
StatusDetectionFactory.class,
- LanguageDetectionFactory.class,
+ LanguageDetection.class,
FileIndexer.class,
- new IndexedFileBuilderProvider(),
- LanguageVerifier.class,
+ InputFileBuilder.class,
FileSystemLogger.class,
DefaultModuleFileSystem.class,
ModuleFileSystemInitializer.class,
index.setCurrentProject(getComponentByType(DefaultSensorStorage.class));
getComponentByType(AbstractPhaseExecutor.class).execute(module);
-
- // Free memory since module settings are no more used
- //module.setSettings(null);
}
}
new AnalysisTempFolderProvider(),
// file system
+ ModuleIndexer.class,
InputComponentStore.class,
PathResolver.class,
DefaultInputModuleHierarchy.class,
*/
package org.sonar.scanner.scan.filesystem;
-import org.sonar.api.batch.fs.IndexedFile;
+import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.internal.AbstractFilePredicate;
/**
}
@Override
- public boolean apply(IndexedFile f) {
+ public boolean apply(InputFile f) {
return key.equals(f.key());
}
}
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.internal.DefaultIndexedFile;
import org.sonar.api.batch.fs.internal.DefaultInputDir;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
private final InputFileFilter[] filters;
private final boolean isAggregator;
private final ExclusionFilters exclusionFilters;
- private final IndexedFileBuilder indexedFileBuilder;
- private final MetadataGenerator metadataGenerator;
+ private final InputFileBuilder inputFileBuilder;
private final DefaultComponentTree componentTree;
private final DefaultInputModule module;
private final BatchIdGenerator batchIdGenerator;
private ProgressReport progressReport;
public FileIndexer(BatchIdGenerator batchIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters,
- DefaultComponentTree componentTree, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def, InputFileFilter[] filters) {
+ DefaultComponentTree componentTree, InputFileBuilder inputFileBuilder, ProjectDefinition def, InputFileFilter[] filters) {
this.batchIdGenerator = batchIdGenerator;
this.componentStore = componentStore;
this.module = module;
this.componentTree = componentTree;
- this.indexedFileBuilder = indexedFileBuilder;
- this.metadataGenerator = inputFileBuilder;
+ this.inputFileBuilder = inputFileBuilder;
this.filters = filters;
this.exclusionFilters = exclusionFilters;
this.isAggregator = !def.getSubProjects().isEmpty();
}
public FileIndexer(BatchIdGenerator batchIdGenerator, InputComponentStore componentStore, DefaultInputModule module, ExclusionFilters exclusionFilters,
- DefaultComponentTree componentTree, IndexedFileBuilder indexedFileBuilder, MetadataGenerator inputFileBuilder, ProjectDefinition def) {
- this(batchIdGenerator, componentStore, module, exclusionFilters, componentTree, indexedFileBuilder, inputFileBuilder, def, new InputFileFilter[0]);
+ DefaultComponentTree componentTree, InputFileBuilder inputFileBuilder, ProjectDefinition def) {
+ this(batchIdGenerator, componentStore, module, exclusionFilters, componentTree, inputFileBuilder, def, new InputFileFilter[0]);
}
void index(DefaultModuleFileSystem fileSystem) {
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);
- DefaultIndexedFile indexedFile = indexedFileBuilder.create(realFile, type, fileSystem.baseDirPath());
- if (indexedFile != null) {
- InputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.readMetadata(f, fileSystem.encoding()));
- if (exclusionFilters.accept(indexedFile, type) && accept(inputFile)) {
+ DefaultInputFile inputFile = inputFileBuilder.create(realFile, type, fileSystem.encoding());
+ if (inputFile != null) {
+ if (exclusionFilters.accept(inputFile, type) && accept(inputFile)) {
fileSystem.add(inputFile);
indexParentDir(fileSystem, inputFile);
- progress.markAsIndexed(indexedFile);
- LOG.debug("'{}' indexed {} with language '{}'", indexedFile.relativePath(), type == Type.TEST ? "as test " : "", indexedFile.language());
+ progress.markAsIndexed(inputFile);
+ LOG.debug("'{}' indexed {} with language '{}'", inputFile.relativePath(), type == Type.TEST ? "as test " : "", inputFile.language());
} else {
progress.increaseExcludedByPatternsCount();
}
+++ /dev/null
-/*
- * 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;
- private final BatchIdGenerator idGenerator;
-
- IndexedFileBuilder(String moduleKey, PathResolver pathResolver, Settings settings, LanguageDetection langDetection, BatchIdGenerator idGenerator) {
- this.moduleKey = moduleKey;
- this.pathResolver = pathResolver;
- this.settings = settings;
- this.langDetection = langDetection;
- this.idGenerator = idGenerator;
- }
-
- @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, idGenerator.get());
- 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;
- }
-}
+++ /dev/null
-/*
- * 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, BatchIdGenerator idGenerator) {
- return new IndexedFileBuilder(def.getKey(), pathResolver, settings, langDetectionFactory.create(), idGenerator);
- }
-
-}
--- /dev/null
+/*
+ * 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.charset.Charset;
+import java.nio.file.Path;
+
+import javax.annotation.CheckForNull;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+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.DefaultInputModule;
+import org.sonar.api.scan.filesystem.PathResolver;
+
+public class InputFileBuilder {
+ private static final Logger LOG = LoggerFactory.getLogger(InputFileBuilder.class);
+ private final String moduleKey;
+ private final Path moduleBaseDir;
+ private final PathResolver pathResolver;
+ private final LanguageDetection langDetection;
+ private final BatchIdGenerator idGenerator;
+ private final MetadataGenerator metadataGenerator;
+
+ public InputFileBuilder(DefaultInputModule module, PathResolver pathResolver, LanguageDetection langDetection, MetadataGenerator metadataGenerator,
+ BatchIdGenerator idGenerator) {
+ this.moduleKey = module.key();
+ this.moduleBaseDir = module.definition().getBaseDir().toPath();
+ this.pathResolver = pathResolver;
+ this.langDetection = langDetection;
+ this.metadataGenerator = metadataGenerator;
+ this.idGenerator = idGenerator;
+ }
+
+ @CheckForNull
+ DefaultInputFile create(Path file, InputFile.Type type, Charset defaultEncoding) {
+ 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, idGenerator.get());
+ String language = langDetection.language(indexedFile);
+ if (language == null && langDetection.forcedLanguage() != null) {
+ LOG.warn("File '{}' is ignored because it doens't belong to the forced langauge '{}'", file.toAbsolutePath(), langDetection.forcedLanguage());
+ return null;
+ }
+ indexedFile.setLanguage(language);
+ return new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(f, defaultEncoding));
+ }
+}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.ScannerSide;
import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
import org.sonar.api.batch.fs.internal.PathPattern;
import org.sonar.api.config.Settings;
/**
* Detect language of a source file based on its suffix and configured patterns.
*/
-class LanguageDetection {
+@ScannerSide
+public class LanguageDetection {
private static final Logger LOG = LoggerFactory.getLogger(LanguageDetection.class);
private final List<String> languagesToConsider = Lists.newArrayList();
private final String forcedLanguage;
- LanguageDetection(Settings settings, LanguagesRepository languages) {
+ public LanguageDetection(Settings settings, LanguagesRepository languages) {
for (Language language : languages.all()) {
String[] filePatterns = settings.getStringArray(getFileLangPatternPropKey(language.key()));
PathPattern[] pathPatterns = PathPattern.create(filePatterns);
// First try with lang patterns
if (forcedLanguage != null) {
if (!patternsByLanguage.containsKey(forcedLanguage)) {
- throw MessageException.of("No language is installed with key '" + forcedLanguage + "'. Please update property '" + CoreProperties.PROJECT_LANGUAGE_PROPERTY + "'");
+ throw MessageException.of("You must install a plugin that supports the language '" + forcedLanguage + "'");
}
+ LOG.info("Language is forced to {}", forcedLanguage);
languagesToConsider.add(forcedLanguage);
} else {
languagesToConsider.addAll(patternsByLanguage.keySet());
}
}
+ public String forcedLanguage() {
+ return forcedLanguage;
+ }
+
Map<String, PathPattern[]> patternsByLanguage() {
return patternsByLanguage;
}
+++ /dev/null
-/*
- * 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.config.Settings;
-import org.sonar.scanner.repository.language.LanguagesRepository;
-
-@ScannerSide
-public class LanguageDetectionFactory {
- private final Settings settings;
- private final LanguagesRepository languages;
-
- public LanguageDetectionFactory(Settings settings, LanguagesRepository languages) {
- this.settings = settings;
- this.languages = languages;
- }
-
- public LanguageDetection create() {
- return new LanguageDetection(settings, languages);
- }
-}
import org.slf4j.LoggerFactory;
import org.sonar.api.batch.fs.InputFile.Type;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
import org.sonar.api.batch.fs.internal.Metadata;
private final StatusDetection statusDetection;
private final FileMetadata fileMetadata;
+ private final DefaultInputModule inputModule;
- MetadataGenerator(StatusDetection statusDetection, FileMetadata fileMetadata) {
+ MetadataGenerator(DefaultInputModule inputModule, StatusDetection statusDetection, FileMetadata fileMetadata) {
+ this.inputModule = inputModule;
this.statusDetection = statusDetection;
this.fileMetadata = fileMetadata;
}
}
}
- public Metadata readMetadata(final DefaultInputFile inputFile, Charset defaultEncoding) {
+ public void setMetadata(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()));
+ inputFile.setMetadata(metadata);
+ inputFile.setStatus(statusDetection.status(inputModule.definition().getKeyWithBranch(), 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);
}
import org.picocontainer.injectors.ProviderAdapter;
import org.sonar.api.batch.ScannerSide;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
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);
+ public MetadataGenerator provide(DefaultInputModule inputModule, StatusDetectionFactory statusDetectionFactory, FileMetadata fileMetadata) {
+ return new MetadataGenerator(inputModule, statusDetectionFactory.create(), fileMetadata);
}
}
*/
package org.sonar.scanner.scan.filesystem;
+import java.util.function.Predicate;
+
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 {
+public class SameInputFilePredicate implements Predicate<InputFile> {
private static final Logger LOG = LoggerFactory.getLogger(SameInputFilePredicate.class);
private final ProjectRepositories projectRepositories;
private final String moduleKey;
}
@Override
- public boolean apply(InputFile inputFile) {
+ public boolean test(InputFile inputFile) {
FileData fileDataPerPath = projectRepositories.fileData(moduleKey, inputFile.relativePath());
if (fileDataPerPath == null) {
// ADDED
--- /dev/null
+/*
+ * 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.scm;
+
+import java.io.File;
+import java.util.LinkedList;
+import java.util.List;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.CoreProperties;
+import org.sonar.api.batch.InstantiationStrategy;
+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.fs.internal.DefaultInputModule;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.scanner.protocol.output.ScannerReport;
+import org.sonar.scanner.protocol.output.ScannerReportWriter;
+import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder;
+import org.sonar.scanner.repository.FileData;
+import org.sonar.scanner.repository.ProjectRepositories;
+import org.sonar.scanner.scan.ImmutableProjectReactor;
+import org.sonar.scanner.scan.filesystem.DefaultModuleFileSystem;
+import org.sonar.scanner.scan.filesystem.ModuleInputComponentStore;
+
+@InstantiationStrategy(InstantiationStrategy.PER_PROJECT)
+@ScannerSide
+public final class ScmPublisher {
+
+ private static final Logger LOG = Loggers.get(ScmPublisher.class);
+
+ private final DefaultInputModule inputModule;
+ private final ScmConfiguration configuration;
+ private final ProjectRepositories projectRepositories;
+ private final ModuleInputComponentStore componentStore;
+
+ private DefaultModuleFileSystem fs;
+ private ScannerReportWriter writer;
+
+ public ScmPublisher(DefaultInputModule inputModule, ScmConfiguration configuration, ProjectRepositories projectRepositories,
+ ModuleInputComponentStore componentStore, DefaultModuleFileSystem fs, ImmutableProjectReactor reactor) {
+ this.inputModule = inputModule;
+ this.configuration = configuration;
+ this.projectRepositories = projectRepositories;
+ this.componentStore = componentStore;
+ this.fs = fs;
+ File reportDir = new File(reactor.getRoot().getWorkDir(), "batch-report");
+ writer = new ScannerReportWriter(reportDir);
+ }
+
+ public void publish() {
+ if (configuration.isDisabled()) {
+ LOG.info("SCM Publisher is disabled");
+ return;
+ }
+ if (configuration.provider() == null) {
+ LOG.info("No SCM system was detected. You can use the '" + CoreProperties.SCM_PROVIDER_KEY + "' property to explicitly specify it.");
+ return;
+ }
+
+ List<InputFile> filesToBlame = collectFilesToBlame(writer);
+ if (!filesToBlame.isEmpty()) {
+ String key = configuration.provider().key();
+ LOG.info("SCM provider for this project is: " + key);
+ DefaultBlameOutput output = new DefaultBlameOutput(writer, filesToBlame);
+ try {
+ configuration.provider().blameCommand().blame(new DefaultBlameInput(fs, filesToBlame), output);
+ } catch (Exception e) {
+ output.finish(false);
+ throw e;
+ }
+ output.finish(true);
+ }
+ }
+
+ private List<InputFile> collectFilesToBlame(ScannerReportWriter writer) {
+ if (configuration.forceReloadAll()) {
+ LOG.warn("Forced reloading of SCM data for all files.");
+ }
+ List<InputFile> filesToBlame = new LinkedList<>();
+ for (InputFile f : componentStore.inputFiles()) {
+ DefaultInputFile inputFile = (DefaultInputFile) f;
+ if (!inputFile.publish()) {
+ continue;
+ }
+ if (configuration.forceReloadAll() || f.status() != Status.SAME) {
+ addIfNotEmpty(filesToBlame, f);
+ } else {
+ // File status is SAME so that mean fileData exists
+ FileData fileData = projectRepositories.fileData(inputModule.definition().getKeyWithBranch(), f.relativePath());
+ if (StringUtils.isEmpty(fileData.revision())) {
+ addIfNotEmpty(filesToBlame, f);
+ } else {
+ askToCopyDataFromPreviousAnalysis((DefaultInputFile) f, writer);
+ }
+ }
+ }
+ return filesToBlame;
+ }
+
+ private void askToCopyDataFromPreviousAnalysis(DefaultInputFile f, ScannerReportWriter writer) {
+ Builder scmBuilder = ScannerReport.Changesets.newBuilder();
+ scmBuilder.setComponentRef(f.batchId());
+ scmBuilder.setCopyFromPrevious(true);
+ writer.writeComponentChangesets(scmBuilder.build());
+ }
+
+ private static void addIfNotEmpty(List<InputFile> filesToBlame, InputFile f) {
+ if (!f.isEmpty()) {
+ filesToBlame.add(f);
+ }
+ }
+
+}
+++ /dev/null
-/*
- * 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.scm;
-
-import java.util.LinkedList;
-import java.util.List;
-import org.apache.commons.lang.StringUtils;
-import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.fs.FileSystem;
-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.sensor.Sensor;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.SensorDescriptor;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
-import org.sonar.scanner.protocol.output.ScannerReport;
-import org.sonar.scanner.protocol.output.ScannerReport.Changesets.Builder;
-import org.sonar.scanner.report.ReportPublisher;
-import org.sonar.scanner.repository.FileData;
-import org.sonar.scanner.repository.ProjectRepositories;
-
-public final class ScmSensor implements Sensor {
-
- private static final Logger LOG = Loggers.get(ScmSensor.class);
-
- private final ProjectDefinition projectDefinition;
- private final ScmConfiguration configuration;
- private final FileSystem fs;
- private final ProjectRepositories projectRepositories;
- private final ReportPublisher publishReportJob;
-
- public ScmSensor(ProjectDefinition projectDefinition, ScmConfiguration configuration,
- ProjectRepositories projectRepositories, FileSystem fs, ReportPublisher publishReportJob) {
- this.projectDefinition = projectDefinition;
- this.configuration = configuration;
- this.projectRepositories = projectRepositories;
- this.fs = fs;
- this.publishReportJob = publishReportJob;
- }
-
- @Override
- public void describe(SensorDescriptor descriptor) {
- descriptor.name("SCM Sensor");
- }
-
- @Override
- public void execute(SensorContext context) {
- if (configuration.isDisabled()) {
- LOG.info("SCM Publisher is disabled");
- return;
- }
- if (configuration.provider() == null) {
- LOG.info("No SCM system was detected. You can use the '" + CoreProperties.SCM_PROVIDER_KEY + "' property to explicitly specify it.");
- return;
- }
-
- List<InputFile> filesToBlame = collectFilesToBlame();
- if (!filesToBlame.isEmpty()) {
- String key = configuration.provider().key();
- LOG.info("SCM provider for this project is: " + key);
- DefaultBlameOutput output = new DefaultBlameOutput(publishReportJob.getWriter(), filesToBlame);
- try {
- configuration.provider().blameCommand().blame(new DefaultBlameInput(fs, filesToBlame), output);
- } catch (Exception e) {
- output.finish(false);
- throw e;
- }
- output.finish(true);
- }
- }
-
- private List<InputFile> collectFilesToBlame() {
- if (configuration.forceReloadAll()) {
- LOG.warn("Forced reloading of SCM data for all files.");
- }
- List<InputFile> filesToBlame = new LinkedList<>();
- for (InputFile f : fs.inputFiles(fs.predicates().all())) {
- if (configuration.forceReloadAll() || f.status() != Status.SAME) {
- addIfNotEmpty(filesToBlame, f);
- } else {
- // File status is SAME so that mean fileData exists
- FileData fileData = projectRepositories.fileData(projectDefinition.getKeyWithBranch(), f.relativePath());
- if (StringUtils.isEmpty(fileData.revision())) {
- addIfNotEmpty(filesToBlame, f);
- } else {
- askToCopyDataFromPreviousAnalysis((DefaultInputFile) f);
- }
- }
- }
- return filesToBlame;
- }
-
- private void askToCopyDataFromPreviousAnalysis(DefaultInputFile f) {
- Builder scmBuilder = ScannerReport.Changesets.newBuilder();
- scmBuilder.setComponentRef(f.batchId());
- scmBuilder.setCopyFromPrevious(true);
- publishReportJob.getWriter().writeComponentChangesets(scmBuilder.build());
- }
-
- private static void addIfNotEmpty(List<InputFile> filesToBlame, InputFile f) {
- if (!f.isEmpty()) {
- filesToBlame.add(f);
- }
- }
-
-}
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.batch.sensor.coverage.NewCoverage;
@Override
public void markForPublishing(InputFile inputFile) {
-
+ DefaultInputFile file = (DefaultInputFile) inputFile;
+ file.setPublish(true);
}
}
@Override
public void store(Measure newMeasure) {
+ if (newMeasure.inputComponent() instanceof DefaultInputFile) {
+ ((DefaultInputFile) newMeasure.inputComponent()).setPublish(true);
+ }
saveMeasure(newMeasure.inputComponent(), (DefaultMeasure<?>) newMeasure);
}
@Override
public void store(Issue issue) {
+ if (issue.primaryLocation().inputComponent() instanceof DefaultInputFile) {
+ ((DefaultInputFile) issue.primaryLocation().inputComponent()).setPublish(true);
+ }
moduleIssues.initAndAddIssue(issue);
}
public void store(DefaultHighlighting highlighting) {
ScannerReportWriter writer = reportPublisher.getWriter();
DefaultInputFile inputFile = (DefaultInputFile) highlighting.inputFile();
+ inputFile.setPublish(true);
int componentRef = 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());
public void store(DefaultSymbolTable symbolTable) {
ScannerReportWriter writer = reportPublisher.getWriter();
DefaultInputFile inputFile = (DefaultInputFile) symbolTable.inputFile();
+ inputFile.setPublish(true);
int componentRef = inputFile.batchId();
if (writer.hasComponentData(FileStructure.Domain.SYMBOLS, componentRef)) {
throw new UnsupportedOperationException("Trying to save symbol table twice for the same file is not supported: " + symbolTable.inputFile().absolutePath());
@Override
public void store(DefaultCoverage defaultCoverage) {
- if (coverageExclusions.isExcluded(defaultCoverage.inputFile())) {
+ DefaultInputFile inputFile = (DefaultInputFile) defaultCoverage.inputFile();
+ inputFile.setPublish(true);
+ if (coverageExclusions.isExcluded(inputFile)) {
return;
}
if (defaultCoverage.linesToCover() > 0) {
- saveCoverageMetricInternal(defaultCoverage.inputFile(), LINES_TO_COVER, new DefaultMeasure<Integer>().forMetric(LINES_TO_COVER).withValue(defaultCoverage.linesToCover()));
- saveCoverageMetricInternal(defaultCoverage.inputFile(), UNCOVERED_LINES,
+ saveCoverageMetricInternal(inputFile, LINES_TO_COVER, new DefaultMeasure<Integer>().forMetric(LINES_TO_COVER).withValue(defaultCoverage.linesToCover()));
+ saveCoverageMetricInternal(inputFile, UNCOVERED_LINES,
new DefaultMeasure<Integer>().forMetric(UNCOVERED_LINES).withValue(defaultCoverage.linesToCover() - defaultCoverage.coveredLines()));
- saveCoverageMetricInternal(defaultCoverage.inputFile(), COVERAGE_LINE_HITS_DATA,
+ saveCoverageMetricInternal(inputFile, COVERAGE_LINE_HITS_DATA,
new DefaultMeasure<String>().forMetric(COVERAGE_LINE_HITS_DATA).withValue(KeyValueFormat.format(defaultCoverage.hitsByLine())));
}
if (defaultCoverage.conditions() > 0) {
- saveCoverageMetricInternal(defaultCoverage.inputFile(), CONDITIONS_TO_COVER,
+ saveCoverageMetricInternal(inputFile, CONDITIONS_TO_COVER,
new DefaultMeasure<Integer>().forMetric(CONDITIONS_TO_COVER).withValue(defaultCoverage.conditions()));
- saveCoverageMetricInternal(defaultCoverage.inputFile(), UNCOVERED_CONDITIONS,
+ saveCoverageMetricInternal(inputFile, UNCOVERED_CONDITIONS,
new DefaultMeasure<Integer>().forMetric(UNCOVERED_CONDITIONS).withValue(defaultCoverage.conditions() - defaultCoverage.coveredConditions()));
- saveCoverageMetricInternal(defaultCoverage.inputFile(), COVERED_CONDITIONS_BY_LINE,
+ saveCoverageMetricInternal(inputFile, COVERED_CONDITIONS_BY_LINE,
new DefaultMeasure<String>().forMetric(COVERED_CONDITIONS_BY_LINE).withValue(KeyValueFormat.format(defaultCoverage.coveredConditionsByLine())));
- saveCoverageMetricInternal(defaultCoverage.inputFile(), CONDITIONS_BY_LINE,
+ saveCoverageMetricInternal(inputFile, CONDITIONS_BY_LINE,
new DefaultMeasure<String>().forMetric(CONDITIONS_BY_LINE).withValue(KeyValueFormat.format(defaultCoverage.conditionsByLine())));
}
}
@Override
public void store(DefaultCpdTokens defaultCpdTokens) {
- InputFile inputFile = defaultCpdTokens.inputFile();
+ DefaultInputFile inputFile = (DefaultInputFile) defaultCpdTokens.inputFile();
+ inputFile.setPublish(true);
PmdBlockChunker blockChunker = new PmdBlockChunker(getBlockSize(inputFile.language()));
List<Block> blocks = blockChunker.chunk(inputFile.key(), defaultCpdTokens.getTokenLines());
index.insert(inputFile, blocks);
@Override
public void store(AnalysisError analysisError) {
+ ((DefaultInputFile) analysisError.inputFile()).setPublish(true);
// no op
}
+++ /dev/null
-/*
- * 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.source;
-
-import org.sonar.api.batch.Phase;
-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.sensor.Sensor;
-import org.sonar.api.batch.sensor.SensorContext;
-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.POST)
-public final class LinesSensor implements Sensor {
-
- @Override
- public void describe(SensorDescriptor descriptor) {
- descriptor.name("Lines Sensor");
- }
-
- @Override
- public void execute(final SensorContext context) {
- FileSystem fs = context.fileSystem();
- for (InputFile f : fs.inputFiles(fs.predicates().hasType(Type.MAIN))) {
- ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
- .on(f)
- .forMetric(CoreMetrics.LINES)
- .withValue(f.lines()))
- .setFromCore()
- .save();
- if (f.language() == null) {
- // As an approximation for files with no language plugin we consider every non blank line as ncloc
- ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
- .on(f)
- .forMetric(CoreMetrics.NCLOC)
- .withValue(((DefaultInputFile) f).nonBlankLines()))
- .save();
- // No test and no coverage on those files
- ((DefaultMeasure<Integer>) context.<Integer>newMeasure()
- .on(f)
- .forMetric(CoreMetrics.LINES_TO_COVER)
- .withValue(0))
- .save();
- }
- }
- }
-
-}
File baseDir = temp.newFolder();
DefaultFileSystem fs = new DefaultFileSystem(baseDir);
- file = new TestInputFileBuilder("foo", "src/ManyStatements.java").setLanguage(JAVA).build();
+ file = new TestInputFileBuilder("foo", "src/ManyStatements.java")
+ .setModuleBaseDir(baseDir.toPath())
+ .setLanguage(JAVA).build();
fs.add(file);
File ioFile = file.file();
FileUtils.copyURLToFile(this.getClass().getResource("ManyStatements.java"), ioFile);
package org.sonar.scanner.index;
import java.io.IOException;
-import org.apache.commons.io.FileUtils;
+import java.util.Collections;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
+import org.sonar.api.CoreProperties;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.InputComponent;
+import org.sonar.api.batch.fs.InputDir;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.InputComponentTree;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.batch.measure.MetricFinder;
-import org.sonar.api.measures.Measure;
-import org.sonar.api.measures.MeasuresFilters;
import org.sonar.api.profiles.RulesProfile;
import org.sonar.api.resources.Directory;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
-import org.sonar.api.resources.Resource;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
-import org.sonar.scanner.FakeJava;
+import org.sonar.scanner.scan.filesystem.InputComponentStore;
import org.sonar.scanner.scan.measure.MeasureCache;
import org.sonar.scanner.sensor.DefaultSensorStorage;
@org.junit.Rule
public TemporaryFolder temp = new TemporaryFolder();
- DefaultIndex index = null;
- Rule rule;
- RuleFinder ruleFinder;
- Project project;
- Project moduleA;
- Project moduleB;
- Project moduleB1;
+ private DefaultIndex index = null;
+ private Rule rule;
+ private RuleFinder ruleFinder;
+ private Project project;
+ private Project moduleA;
+ private Project moduleB;
+ private Project moduleB1;
+ private InputComponentStore componentStore;
+ private InputComponentTree componentTree;
private java.io.File baseDir;
- // TODO
-/*
- *
@Before
public void createIndex() throws IOException {
ruleFinder = mock(RuleFinder.class);
-
- DefaultProjectTree projectTree = mock(DefaultProjectTree.class);
- BatchComponentCache resourceCache = new BatchComponentCache();
- index = new DefaultIndex(resourceCache, projectTree, mock(MeasureCache.class), mock(MetricFinder.class));
+ componentStore = mock(InputComponentStore.class);
+ componentTree = mock(InputComponentTree.class);
+ index = new DefaultIndex(componentStore, componentTree, mock(MeasureCache.class), mock(MetricFinder.class));
baseDir = temp.newFolder();
- project = new Project("project");
- when(projectTree.getProjectDefinition(project)).thenReturn(ProjectDefinition.create().setBaseDir(baseDir));
- moduleA = new Project("moduleA").setParent(project);
- when(projectTree.getProjectDefinition(moduleA)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleA")));
- moduleB = new Project("moduleB").setParent(project);
- when(projectTree.getProjectDefinition(moduleB)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB")));
- moduleB1 = new Project("moduleB1").setParent(moduleB);
- when(projectTree.getProjectDefinition(moduleB1)).thenReturn(ProjectDefinition.create().setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1")));
+
+ ProjectDefinition rootDef = ProjectDefinition.create().setKey("project").setBaseDir(baseDir);
+ ProjectDefinition moduleADef = ProjectDefinition.create().setKey("moduleA").setBaseDir(new java.io.File(baseDir, "moduleA"));
+ ProjectDefinition moduleBDef = ProjectDefinition.create().setKey("moduleB").setBaseDir(new java.io.File(baseDir, "moduleB"));
+ ProjectDefinition moduleB1Def = ProjectDefinition.create().setKey("moduleB1").setBaseDir(new java.io.File(baseDir, "moduleB/moduleB1"));
+
+ rootDef.addSubProject(moduleADef);
+ rootDef.addSubProject(moduleBDef);
+ moduleBDef.addSubProject(moduleB1Def);
+
+ project = new Project(rootDef);
+ moduleA = new Project(moduleADef);
+ moduleB = new Project(moduleBDef);
+ moduleB1 = new Project(moduleB1Def);
RulesProfile rulesProfile = RulesProfile.create();
rule = Rule.create("repoKey", "ruleKey", "Rule");
rule.setId(1);
rulesProfile.activateRule(rule, null);
- index.setCurrentProject(project, mock(DefaultSensorStorage.class));
- index.doStart(project);
- }
-
- @Test
- public void shouldIndexParentOfDeprecatedFiles() {
- File file = File.create("src/org/foo/Bar.java", null, false);
- assertThat(index.index(file)).isTrue();
-
- Directory reference = Directory.create("src/org/foo");
- assertThat(index.getResource(reference).getName()).isEqualTo("src/org/foo");
- assertThat(index.getChildren(reference)).hasSize(1);
- assertThat(index.getParent(reference)).isInstanceOf(Project.class);
- }
-
- @Test
- public void shouldIndexTreeOfResources() {
- Directory directory = Directory.create("src/org/foo");
- File file = File.create("src/org/foo/Bar.java", FakeJava.INSTANCE, false);
-
- assertThat(index.index(directory)).isTrue();
- assertThat(index.index(file, directory)).isTrue();
-
- File fileRef = File.create("src/org/foo/Bar.java", null, false);
- assertThat(index.getResource(fileRef).getKey()).isEqualTo("src/org/foo/Bar.java");
- assertThat(index.getResource(fileRef).getLanguage().getKey()).isEqualTo("java");
- assertThat(index.getChildren(fileRef)).isEmpty();
- assertThat(index.getParent(fileRef)).isInstanceOf(Directory.class);
+ index.setCurrentProject(mock(DefaultSensorStorage.class));
}
@Test
- public void shouldNotIndexResourceIfParentNotIndexed() {
- Directory directory = Directory.create("src/org/other");
- File file = File.create("src/org/foo/Bar.java", null, false);
+ public void shouldGetHierarchy() {
+ InputComponent component = new DefaultInputModule("module1");
+ InputFile file1 = new TestInputFileBuilder("module1", "src/org/foo/Bar.java").build();
- assertThat(index.index(file, directory)).isFalse();
+ when(componentStore.getByKey("module1")).thenReturn(component);
+ when(componentStore.getByKey("module1:src/org/foo/Bar.java")).thenReturn(file1);
+ when(componentTree.getParent(file1)).thenReturn(component);
+ when(componentTree.getChildren(component)).thenReturn(Collections.singleton(file1));
- File fileRef = File.create("src/org/foo/Bar.java", null, false);
- assertThat(index.getChildren(fileRef)).isEmpty();
- assertThat(index.getParent(fileRef)).isNull();
- }
-
- @Test
- public void shouldNotIndexResourceWhenAddingMeasure() {
- Resource dir = Directory.create("src/org/foo");
- index.addMeasure(dir, new Measure("ncloc").setValue(50.0));
+ assertThat(index.getParent("module1:src/org/foo/Bar.java").getKey()).isEqualTo("module1");
+ assertThat(index.getParent("module1")).isNull();
- assertThat(index.getMeasures(dir, MeasuresFilters.metric("ncloc"))).isNull();
+ assertThat(index.getChildren("module1")).containsOnly(File.create("src/org/foo/Bar.java"));
+ assertThat(index.getChildren("module1:src/org/foo/Bar.java")).isEmpty();
}
@Test
- public void shouldComputePathOfIndexedModules() {
- assertThat(index.getResource(project).getPath()).isNull();
- assertThat(index.getResource(moduleA).getPath()).isEqualTo("moduleA");
- assertThat(index.getResource(moduleB).getPath()).isEqualTo("moduleB");
- assertThat(index.getResource(moduleB1).getPath()).isEqualTo("moduleB1");
+ public void shouldTransformToResource() {
+ DefaultInputModule component = new DefaultInputModule(ProjectDefinition.create()
+ .setKey("module1")
+ .setProperty(CoreProperties.PROJECT_BRANCH_PROPERTY, "branch1"), 1);
+ InputFile file1 = new TestInputFileBuilder("module1", "src/org/foo/Bar.java").build();
+ InputDir dir = new DefaultInputDir("module1", "src");
+
+ assertThat(index.toResource(component)).isInstanceOf(Project.class);
+ assertThat(index.toResource(component).getKey()).isEqualTo("module1");
+ assertThat(index.toResource(component).getEffectiveKey()).isEqualTo("module1:branch1");
+
+ assertThat(index.toResource(file1)).isInstanceOf(File.class);
+ assertThat(index.toResource(file1).getKey()).isEqualTo("src/org/foo/Bar.java");
+ assertThat(index.toResource(file1).getPath()).isEqualTo("src/org/foo/Bar.java");
+
+ assertThat(index.toResource(dir)).isInstanceOf(Directory.class);
+ assertThat(index.toResource(dir).getKey()).isEqualTo("src");
+ assertThat(index.toResource(dir).getPath()).isEqualTo("src");
}
- */
}
import org.sonar.scanner.mediumtest.ScannerMediumTester;
import org.sonar.scanner.mediumtest.TaskResult;
import org.sonar.xoo.XooPlugin;
+import org.sonar.xoo.rule.XooRulesDefinition;
import static org.assertj.core.api.Assertions.assertThat;
public ScannerMediumTester tester = ScannerMediumTester.builder()
.registerPlugin("xoo", new XooPlugin())
+ .addRules(new XooRulesDefinition())
+ // active a rule just to be sure that xoo files are published
+ .addActiveRule("xoo", "xoo:OneIssuePerFile", null, "One Issue Per File", null, null, null)
.addDefaultQProfile("xoo", "Sonar Way")
.build();
assertThat(result.allMeasures().get(noConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
.containsOnly(
- tuple(CoreMetrics.LINES_KEY, 8, ""),
tuple(CoreMetrics.LINES_TO_COVER_KEY, 2, ""),
tuple(CoreMetrics.UNCOVERED_LINES_KEY, 1, ""),
tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "6=1;7=0"));
assertThat(result.allMeasures().get(withConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
.containsOnly(
- tuple(CoreMetrics.LINES_KEY, 6, ""),
tuple(CoreMetrics.LINES_TO_COVER_KEY, 1, ""),
tuple(CoreMetrics.UNCOVERED_LINES_KEY, 0, ""),
tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "3=1"),
assertThat(result.allMeasures().get(noConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
.containsOnly(
- tuple(CoreMetrics.LINES_KEY, 8, ""),
tuple(CoreMetrics.LINES_TO_COVER_KEY, 2, ""),
tuple(CoreMetrics.UNCOVERED_LINES_KEY, 0, ""),
tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "6=1;7=1"));
assertThat(result.allMeasures().get(withConditions.key())).extracting("metricKey", "intValue.value", "stringValue.value")
.containsOnly(
- tuple(CoreMetrics.LINES_KEY, 6, ""),
tuple(CoreMetrics.LINES_TO_COVER_KEY, 1, ""),
tuple(CoreMetrics.UNCOVERED_LINES_KEY, 0, ""),
tuple(CoreMetrics.COVERAGE_LINE_HITS_DATA_KEY, 0, "3=2"),
import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.xoo.XooPlugin;
import org.sonar.xoo.lang.CpdTokenizerSensor;
+import org.sonar.xoo.rule.XooRulesDefinition;
import static org.assertj.core.api.Assertions.assertThat;
public ScannerMediumTester tester = ScannerMediumTester.builder()
.registerPlugin("xoo", new XooPlugin())
.addDefaultQProfile("xoo", "Sonar Way")
+ .addRules(new XooRulesDefinition())
+ // active a rule just to be sure that xoo files are published
+ .addActiveRule("xoo", "xoo:OneIssuePerFile", null, "One Issue Per File", null, null, null)
.build();
private File baseDir;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
-import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.utils.log.LogTester;
import org.sonar.api.utils.log.LoggerLevel;
import org.sonar.scanner.mediumtest.ScannerMediumTester;
srcDir.mkdir();
}
- @Test
- public void computeMeasuresOnTempProject() throws IOException {
- File xooFile = new File(srcDir, "sample.xoo");
- File xooMeasureFile = new File(srcDir, "sample.xoo.measures");
- FileUtils.write(xooFile, "Sample xoo\ncontent");
- FileUtils.write(xooMeasureFile, "lines:20");
-
- TaskResult result = tester.newTask()
- .properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.projectName", "Foo Project")
- .put("sonar.projectVersion", "1.0-SNAPSHOT")
- .put("sonar.projectDescription", "Description of Foo Project")
- .put("sonar.sources", "src")
- .put("sonar.cpd.xoo.skip", "true")
- .build())
- .start();
-
- Map<String, List<Measure>> allMeasures = result.allMeasures();
-
- assertThat(allMeasures.get("com.foo.project")).extracting("metricKey", "stringValue.value").isEmpty();
-
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value").containsOnly(
- tuple(CoreMetrics.LINES_KEY, 2));
- }
-
- @Test
- public void computeLinesOnAllFiles() throws IOException {
- File xooFile = new File(srcDir, "sample.xoo");
- FileUtils.write(xooFile, "Sample xoo\n\ncontent");
-
- File otherFile = new File(srcDir, "sample.other");
- FileUtils.write(otherFile, "Sample other\ncontent\n");
-
- TaskResult result = tester.newTask()
- .properties(ImmutableMap.<String, String>builder()
- .put("sonar.task", "scan")
- .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
- .put("sonar.projectKey", "com.foo.project")
- .put("sonar.projectName", "Foo Project")
- .put("sonar.projectVersion", "1.0-SNAPSHOT")
- .put("sonar.projectDescription", "Description of Foo Project")
- .put("sonar.sources", "src")
- .put("sonar.import_unknown_files", "true")
- .build())
- .start();
-
- Map<String, List<Measure>> allMeasures = result.allMeasures();
-
- assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .contains(tuple("lines", 3));
- assertThat(allMeasures.get("com.foo.project:src/sample.other")).extracting("metricKey", "intValue.value")
- .contains(tuple("lines", 3), tuple("ncloc", 2));
- }
-
@Test
public void applyExclusionsOnCoverageMeasures() throws IOException {
File xooFile = new File(srcDir, "sample.xoo");
Map<String, List<Measure>> allMeasures = result.allMeasures();
assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .containsOnly(tuple("lines", 3),
- tuple("lines_to_cover", 2));
+ .containsOnly(tuple("lines_to_cover", 2));
result = tester.newTask()
.properties(ImmutableMap.<String, String>builder()
allMeasures = result.allMeasures();
assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .containsOnly(tuple("lines", 3));
+ .isEmpty();
}
@Test
Map<String, List<Measure>> allMeasures = result.allMeasures();
assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value")
- .containsOnly(tuple("lines", 3),
- tuple("lines_to_cover", 2));
+ .containsOnly(tuple("lines_to_cover", 2));
assertThat(logTester.logs(LoggerLevel.WARN))
.contains("Coverage measure for metric 'lines_to_cover' should not be saved directly by a Sensor. Plugin should be updated to use SensorContext::newCoverage instead.");
Map<String, List<Measure>> allMeasures = result.allMeasures();
assertThat(allMeasures.get("com.foo.project:src/sample.xoo")).extracting("metricKey", "intValue.value", "stringValue.value")
- .containsExactly(tuple("lines", 4, ""), tuple("ncloc_data", 0, "1=1;4=1"));
+ .containsExactly(tuple("ncloc_data", 0, "1=1;4=1"));
}
}
import org.sonar.scanner.protocol.output.ScannerReport.Component;
import org.sonar.scanner.protocol.output.ScannerReportReader;
import org.sonar.xoo.XooPlugin;
+import org.sonar.xoo.rule.XooRulesDefinition;
import static org.assertj.core.api.Assertions.assertThat;
public ScannerMediumTester tester = ScannerMediumTester.builder()
.registerPlugin("xoo", new XooPlugin())
.addDefaultQProfile("xoo", "Sonar Way")
+ .addRules(new XooRulesDefinition())
+ // active a rule just to be sure that xoo files are published
+ .addActiveRule("xoo", "xoo:OneIssuePerFile", null, "One Issue Per File", null, null, null)
.addFileData("com.foo.project", CHANGED_CONTENT_SCM_ON_SERVER_XOO, new FileData(DigestUtils.md5Hex(SAMPLE_XOO_CONTENT), null))
.addFileData("com.foo.project", SAME_CONTENT_NO_SCM_ON_SERVER_XOO, new FileData(DigestUtils.md5Hex(SAMPLE_XOO_CONTENT), null))
.addFileData("com.foo.project", SAME_CONTENT_SCM_ON_SERVER_XOO, new FileData(DigestUtils.md5Hex(SAMPLE_XOO_CONTENT), "1.1"))
@Test
public void testScmMeasure() throws IOException {
-
File baseDir = prepareProject();
tester.newTask()
assertThat(getChangesets(baseDir, NO_BLAME_SCM_ON_SERVER_XOO)).isNull();
+ // 5 .xoo files + 3 .scm files, but only 4 marked for publishing. 1 file is SAME so not included in the total
+ assertThat(logTester.logs()).containsSubsequence("8 files indexed");
assertThat(logTester.logs()).containsSubsequence("4 files to be analyzed", "3/4 files analyzed");
assertThat(logTester.logs()).containsSubsequence(MISSING_BLAME_INFORMATION_FOR_THE_FOLLOWING_FILES, " * " + noBlameScmOnServer.getPath().replaceAll("\\\\", "/"));
}
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.sonar.api.CoreProperties;
-import org.sonar.api.batch.Decorator;
import org.sonar.api.batch.Initializer;
import org.sonar.api.batch.PostJob;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.batch.events.DecoratorExecutionHandler;
-import org.sonar.api.batch.events.DecoratorsPhaseHandler;
import org.sonar.api.batch.events.InitializerExecutionHandler;
import org.sonar.api.batch.events.InitializersPhaseHandler;
import org.sonar.api.batch.events.PostJobExecutionHandler;
};
}
- private DecoratorExecutionHandler.DecoratorExecutionEvent decoratorEvent(final Decorator decorator, final boolean start) {
- return new DecoratorExecutionHandler.DecoratorExecutionEvent() {
-
- @Override
- public boolean isStart() {
- return start;
- }
-
- @Override
- public boolean isEnd() {
- return !start;
- }
-
- @Override
- public Decorator getDecorator() {
- return decorator;
- }
- };
- }
-
private PostJobExecutionHandler.PostJobExecutionEvent postJobEvent(final PostJob postJob, final boolean start) {
return new PostJobExecutionHandler.PostJobExecutionEvent() {
};
}
- private DecoratorsPhaseHandler.DecoratorsPhaseEvent decoratorsEvent(final boolean start) {
- return new DecoratorsPhaseHandler.DecoratorsPhaseEvent() {
-
- @Override
- public boolean isStart() {
- return start;
- }
-
- @Override
- public boolean isEnd() {
- return !start;
- }
-
- @Override
- public List<Decorator> getDecorators() {
- return null;
- }
- };
- }
-
private ProjectAnalysisEvent projectEvent(final Project project, final boolean start) {
return new ProjectAnalysisHandler.ProjectAnalysisEvent() {
@Override
import org.sonar.api.utils.DateUtils;
import org.sonar.scanner.ProjectAnalysisInfo;
import org.sonar.scanner.protocol.output.FileStructure;
+import org.sonar.scanner.protocol.output.ScannerReport;
import org.sonar.scanner.protocol.output.ScannerReport.Component;
import org.sonar.scanner.protocol.output.ScannerReport.ComponentLink.ComponentLinkType;
import org.sonar.scanner.report.ComponentsPublisher;
writer = new ScannerReportWriter(outputDir);
}
+ private void writeIssue(int componentId) {
+ writer.writeComponentIssues(componentId, Collections.singleton(ScannerReport.Issue.newBuilder().build()));
+ }
+
@Test
public void add_components_to_report() throws Exception {
ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 4).setLines(2).build();
tree.index(file, dir);
- DefaultInputFile fileWithoutLang = new TestInputFileBuilder("module1", "src/make", 5).setLines(10).build();
+ DefaultInputFile file2 = new TestInputFileBuilder("module1", "src/Foo2.java", 5).setPublish(false).setLines(2).build();
+ tree.index(file2, dir);
+
+ DefaultInputFile fileWithoutLang = new TestInputFileBuilder("module1", "src/make", 6).setLines(10).build();
tree.index(fileWithoutLang, dir);
- DefaultInputFile testFile = new TestInputFileBuilder("module1", "test/FooTest.java", 6).setType(Type.TEST).setLines(4).build();
+ DefaultInputFile testFile = new TestInputFileBuilder("module1", "test/FooTest.java", 7).setType(Type.TEST).setLines(4).build();
tree.index(testFile, dir);
ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree);
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isTrue();
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isTrue();
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isTrue();
+ // not marked for publishing
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isFalse();
// no such reference
- assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isFalse();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 8)).isFalse();
ScannerReportReader reader = new ScannerReportReader(outputDir);
Component rootProtobuf = reader.readComponent(1);
assertThat(module1Protobuf.getVersion()).isEqualTo("1.0");
}
+ @Test
+ public void should_skip_dir_without_published_files() {
+ ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
+ when(projectAnalysisInfo.analysisDate()).thenReturn(DateUtils.parseDate("2012-12-12"));
+
+ ProjectDefinition rootDef = ProjectDefinition.create()
+ .setKey("foo")
+ .setProperty(CoreProperties.PROJECT_VERSION_PROPERTY, "1.0")
+ .setName("Root project")
+ .setDescription("Root description");
+ DefaultInputModule root = new DefaultInputModule(rootDef, 1);
+
+ moduleHierarchy = mock(InputModuleHierarchy.class);
+ when(moduleHierarchy.root()).thenReturn(root);
+ when(moduleHierarchy.children(root)).thenReturn(Collections.emptyList());
+
+ // dir with files
+ DefaultInputDir dir = new DefaultInputDir("module1", "src", 2);
+ tree.index(dir, root);
+
+ // dir without files and issues
+ DefaultInputDir dir2 = new DefaultInputDir("module1", "src2", 3);
+ tree.index(dir2, root);
+
+ // dir without files but has issues
+ DefaultInputDir dir3 = new DefaultInputDir("module1", "src3", 4);
+ tree.index(dir3, root);
+ writeIssue(4);
+
+ DefaultInputFile file = new TestInputFileBuilder("module1", "src/Foo.java", 5).setLines(2).build();
+ tree.index(file, dir);
+
+ DefaultInputFile file2 = new TestInputFileBuilder("module1", "src2/Foo2.java", 6).setPublish(false).setLines(2).build();
+ tree.index(file2, dir2);
+
+ DefaultInputFile file3 = new TestInputFileBuilder("module1", "src2/Foo3.java", 7).setPublish(false).setLines(2).build();
+ tree.index(file3, dir3);
+
+ ComponentsPublisher publisher = new ComponentsPublisher(moduleHierarchy, tree);
+ publisher.publish(writer);
+
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 1)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 2)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 5)).isTrue();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 4)).isTrue();
+
+ // file was not marked for publishing and directory doesn't contain issues, so directory won't be included as well
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 3)).isFalse();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 6)).isFalse();
+ assertThat(writer.hasComponentData(FileStructure.Domain.COMPONENT, 7)).isFalse();
+
+ }
+
@Test
public void add_components_without_version_and_name() throws IOException {
ProjectAnalysisInfo projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
import static org.mockito.Mockito.when;
public class MeasuresPublisherTest {
-
- private static final String FILE_KEY = "foo:src/Foo.php";
-
@Rule
public ExpectedException thrown = ExpectedException.none();
private File outputDir;
private ScannerReportWriter writer;
private DefaultInputFile inputFile;
+ private DefaultInputModule InputModule;
@Before
public void prepare() throws IOException {
- inputFile = new TestInputFileBuilder("foo", "src/Foo.php").build();
+ InputModule = new DefaultInputModule("foo");
+ inputFile = new TestInputFileBuilder("foo", "src/Foo.php").setPublish(true).build();
componentCache = new InputComponentStore();
- componentCache.put(new DefaultInputModule("foo"));
+ componentCache.put(InputModule);
componentCache.put(inputFile);
measureCache = mock(MeasureCache.class);
when(measureCache.byComponentKey(anyString())).thenReturn(Collections.<DefaultMeasure<?>>emptyList());
// String value
DefaultMeasure<String> stringMeasure = new DefaultMeasure<String>().forMetric(CoreMetrics.NCLOC_LANGUAGE_DISTRIBUTION)
.withValue("foo bar");
- when(measureCache.byComponentKey(FILE_KEY)).thenReturn(asList(measure, stringMeasure));
+ when(measureCache.byComponentKey(inputFile.key())).thenReturn(asList(measure, stringMeasure));
publisher.publish(writer);
ScannerReportReader reader = new ScannerReportReader(outputDir);
- assertThat(reader.readComponentMeasures(1)).hasSize(0);
+ assertThat(reader.readComponentMeasures(InputModule.batchId())).hasSize(0);
try (CloseableIterator<ScannerReport.Measure> componentMeasures = reader.readComponentMeasures(inputFile.batchId())) {
assertThat(componentMeasures).hasSize(2);
}
@Test
public void fail_with_IAE_when_measure_has_no_value() throws Exception {
DefaultMeasure<Integer> measure = new DefaultMeasure<Integer>().forMetric(CoreMetrics.LINES_TO_COVER);
- when(measureCache.byComponentKey(FILE_KEY)).thenReturn(Collections.singletonList(measure));
+ when(measureCache.byComponentKey(inputFile.key())).thenReturn(Collections.singletonList(measure));
try {
publisher.publish(writer);
@Before
public void prepare() {
projectDef = ProjectDefinition.create().setKey("foo");
- rootModule = new DefaultInputModule(projectDef, TestInputFileBuilder.batchId++);
+ rootModule = new DefaultInputModule(projectDef, TestInputFileBuilder.nextBatchId());
projectAnalysisInfo = mock(ProjectAnalysisInfo.class);
when(projectAnalysisInfo.analysisDate()).thenReturn(new Date(1234567L));
inputModuleHierarchy = mock(InputModuleHierarchy.class);
import com.google.common.collect.ImmutableList;
import java.util.LinkedList;
import java.util.List;
-import org.apache.commons.lang.mutable.MutableBoolean;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.sonarqube.ws.QualityProfiles.SearchWsResponse.QualityProfile;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
--- /dev/null
+/*
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.fs.internal.DefaultInputComponent;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+
+public class DefaultComponentTreeTest {
+ private DefaultComponentTree tree;
+
+ @Before
+ public void setUp() {
+ tree = new DefaultComponentTree();
+ }
+
+ @Test
+ public void test() {
+ DefaultInputComponent root = new DefaultInputModule("root");
+ DefaultInputComponent mod1 = new DefaultInputModule("mod1");
+ DefaultInputComponent mod2 = new DefaultInputModule("mod2");
+ DefaultInputComponent mod3 = new DefaultInputModule("mod3");
+ DefaultInputComponent mod4 = new DefaultInputModule("mod4");
+
+ tree.index(mod1, root);
+ tree.index(mod2, mod1);
+ tree.index(mod3, root);
+ tree.index(mod4, root);
+
+ assertThat(tree.getChildren(root)).containsOnly(mod1, mod3, mod4);
+ assertThat(tree.getChildren(mod4)).isEmpty();
+ assertThat(tree.getChildren(mod1)).containsOnly(mod2);
+
+ assertThat(tree.getParent(mod4)).isEqualTo(root);
+ assertThat(tree.getParent(mod2)).isEqualTo(mod1);
+ assertThat(tree.getParent(mod1)).isEqualTo(root);
+ assertThat(tree.getParent(root)).isNull();
+ }
+}
--- /dev/null
+/*
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+
+public class DefaultInputModuleHierarchyTest {
+ private DefaultInputModuleHierarchy moduleHierarchy;
+
+ @Before
+ public void setUp() {
+ moduleHierarchy = new DefaultInputModuleHierarchy();
+ }
+
+ @Test
+ public void test() {
+ DefaultInputModule root = new DefaultInputModule("root");
+ DefaultInputModule mod1 = new DefaultInputModule("mod1");
+ DefaultInputModule mod2 = new DefaultInputModule("mod2");
+ DefaultInputModule mod3 = new DefaultInputModule("mod3");
+ DefaultInputModule mod4 = new DefaultInputModule("mod4");
+
+ moduleHierarchy.setRoot(root);
+ moduleHierarchy.index(mod1, root);
+ moduleHierarchy.index(mod2, mod1);
+ moduleHierarchy.index(mod3, root);
+ moduleHierarchy.index(mod4, root);
+
+ assertThat(moduleHierarchy.children(root)).containsOnly(mod1, mod3, mod4);
+ assertThat(moduleHierarchy.children(mod4)).isEmpty();
+ assertThat(moduleHierarchy.children(mod1)).containsOnly(mod2);
+
+ assertThat(moduleHierarchy.parent(mod4)).isEqualTo(root);
+ assertThat(moduleHierarchy.parent(mod2)).isEqualTo(mod1);
+ assertThat(moduleHierarchy.parent(mod1)).isEqualTo(root);
+ assertThat(moduleHierarchy.parent(root)).isNull();
+
+ assertThat(moduleHierarchy.root()).isEqualTo(root);
+ }
+}
+++ /dev/null
-/*
- * 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;
-
-import org.junit.Before;
-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.DefaultFileSystem;
-import org.sonar.api.config.Settings;
-import org.sonar.api.config.MapSettings;
-import org.sonar.api.resources.Languages;
-import org.sonar.api.utils.MessageException;
-import org.sonar.scanner.FakeJava;
-import org.sonar.scanner.repository.language.DefaultLanguagesRepository;
-import org.sonar.scanner.repository.language.LanguagesRepository;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class LanguageVerifierTest {
-
- @Rule
- public TemporaryFolder temp = new TemporaryFolder();
-
- @Rule
- public ExpectedException thrown = ExpectedException.none();
-
- private Settings settings = new MapSettings();
- private LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(FakeJava.INSTANCE));
- private DefaultFileSystem fs;
-
- @Before
- public void prepare() throws Exception {
- fs = new DefaultFileSystem(temp.newFolder().toPath());
- }
-
- @Test
- public void language_is_not_set() {
- LanguageVerifier verifier = new LanguageVerifier(settings, languages, fs);
- verifier.start();
-
- // no failure and no language is forced
- assertThat(fs.languages()).isEmpty();
-
- verifier.stop();
- }
-
- @Test
- public void language_is_empty() {
- settings.setProperty("sonar.language", "");
- LanguageVerifier verifier = new LanguageVerifier(settings, languages, fs);
- verifier.start();
-
- // no failure and no language is forced
- assertThat(fs.languages()).isEmpty();
-
- verifier.stop();
- }
-
- @Test
- public void language_is_valid() {
- settings.setProperty("sonar.language", "java");
-
- LanguageVerifier verifier = new LanguageVerifier(settings, languages, fs);
- verifier.start();
-
- // no failure and language is hardly registered
- assertThat(fs.languages()).contains("java");
-
- verifier.stop();
- }
-
- @Test
- public void language_is_not_valid() {
- thrown.expect(MessageException.class);
- thrown.expectMessage("You must install a plugin that supports the language 'php'");
-
- settings.setProperty("sonar.language", "php");
- LanguageVerifier verifier = new LanguageVerifier(settings, languages, fs);
- verifier.start();
- }
-}
--- /dev/null
+/*
+ * 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;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.sonar.api.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.InputModule;
+import org.sonar.scanner.scan.filesystem.BatchIdGenerator;
+
+public class ModuleIndexerTest {
+ private ModuleIndexer indexer;
+ private DefaultComponentTree tree;
+ private DefaultInputModuleHierarchy moduleHierarchy;
+ private ImmutableProjectReactor reactor;
+
+ @Before
+ public void setUp() {
+ reactor = mock(ImmutableProjectReactor.class);
+ tree = new DefaultComponentTree();
+ moduleHierarchy = new DefaultInputModuleHierarchy();
+ indexer = new ModuleIndexer(reactor, tree, new BatchIdGenerator(), moduleHierarchy);
+ }
+
+ @Test
+ public void testIndex() {
+ ProjectDefinition root = ProjectDefinition.create().setKey("root");
+ ProjectDefinition mod1 = ProjectDefinition.create().setKey("mod1");
+ ProjectDefinition mod2 = ProjectDefinition.create().setKey("mod2");
+ ProjectDefinition mod3 = ProjectDefinition.create().setKey("mod3");
+ ProjectDefinition mod4 = ProjectDefinition.create().setKey("mod4");
+
+ root.addSubProject(mod1);
+ mod1.addSubProject(mod2);
+ root.addSubProject(mod3);
+ root.addSubProject(mod4);
+
+ when(reactor.getRoot()).thenReturn(root);
+ indexer.start();
+
+ InputModule rootModule = moduleHierarchy.root();
+ assertThat(rootModule).isNotNull();
+ assertThat(moduleHierarchy.children(rootModule)).hasSize(3);
+ assertThat(tree.getChildren(rootModule)).hasSize(3);
+ }
+}
import org.junit.Test;
import org.sonar.api.batch.fs.FilePredicate;
-import org.sonar.api.batch.fs.IndexedFile;
-import org.sonar.api.batch.fs.internal.DefaultIndexedFile;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
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");
- IndexedFile indexedFile = new DefaultIndexedFile("struts", Paths.get("module"), "Action.java");
- assertThat(predicate.apply(indexedFile)).isTrue();
+ InputFile inputFile = new TestInputFileBuilder("struts", "Action.java").build();
+ assertThat(predicate.apply(inputFile)).isTrue();
- indexedFile = new DefaultIndexedFile("struts", Paths.get("module"), "Filter.java");
- assertThat(predicate.apply(indexedFile)).isFalse();
+ inputFile = new TestInputFileBuilder("struts", "Filter.java").build();
+ assertThat(predicate.apply(inputFile)).isFalse();
}
}
--- /dev/null
+/*
+ * 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.Mockito.mock;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+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.batch.bootstrap.ProjectDefinition;
+import org.sonar.api.batch.fs.InputFile.Type;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.scan.filesystem.PathResolver;
+
+public class InputFileBuilderTest {
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ private Path baseDir;
+ private InputFileBuilder builder;
+
+ @Before
+ public void setUp() throws IOException {
+ baseDir = temp.newFolder().toPath();
+ DefaultInputModule module = new DefaultInputModule(ProjectDefinition.create()
+ .setKey("module1")
+ .setBaseDir(baseDir.toFile()), 0);
+
+ PathResolver pathResolver = new PathResolver();
+ LanguageDetection langDetection = mock(LanguageDetection.class);
+ MetadataGenerator metadataGenerator = mock(MetadataGenerator.class);
+ BatchIdGenerator idGenerator = new BatchIdGenerator();
+ builder = new InputFileBuilder(module, pathResolver, langDetection, metadataGenerator, idGenerator);
+ }
+
+ @Test
+ public void testBuild() {
+ Path filePath = baseDir.resolve("src/File1.xoo");
+ DefaultInputFile inputFile = builder.create(filePath, Type.MAIN, StandardCharsets.UTF_8);
+
+ assertThat(inputFile.moduleKey()).isEqualTo("module1");
+ assertThat(inputFile.absolutePath()).isEqualTo(filePath.toString());
+ assertThat(inputFile.key()).isEqualTo("module1:src/File1.xoo");
+ assertThat(inputFile.publish()).isFalse();
+ }
+}
+++ /dev/null
-/*
- * 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.junit.Test;
-import org.sonar.api.config.MapSettings;
-import org.sonar.api.resources.Languages;
-import org.sonar.scanner.FakeJava;
-import org.sonar.scanner.repository.language.DefaultLanguagesRepository;
-import org.sonar.scanner.repository.language.LanguagesRepository;
-
-import static org.assertj.core.api.Assertions.assertThat;
-
-public class LanguageDetectionFactoryTest {
- @Test
- public void testCreate() throws Exception {
- LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(FakeJava.INSTANCE));
- LanguageDetectionFactory factory = new LanguageDetectionFactory(new MapSettings(), languages);
- LanguageDetection languageDetection = factory.create();
- assertThat(languageDetection).isNotNull();
- assertThat(languageDetection.patternsByLanguage()).hasSize(1);
- assertThat(languageDetection.patternsByLanguage().containsKey("java")).isTrue();
- }
-}
@Test
public void fail_if_invalid_language() {
thrown.expect(MessageException.class);
- thrown.expectMessage("No language is installed with key 'unknown'. Please update property 'sonar.language'");
+ thrown.expectMessage("You must install a plugin that supports the language 'unknown'");
LanguagesRepository languages = new DefaultLanguagesRepository(new Languages(new MockLanguage("java", "java"), new MockLanguage("php", "php")));
Settings settings = new MapSettings();
import org.junit.Test;
import org.mockito.Mockito;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
import static org.assertj.core.api.Assertions.assertThat;
StatusDetectionFactory statusDetectionFactory = mock(StatusDetectionFactory.class, Mockito.RETURNS_MOCKS);
MetadataGeneratorProvider factory = new MetadataGeneratorProvider();
- assertThat(factory.provide(statusDetectionFactory, new FileMetadata())).isNotNull();
+ assertThat(factory.provide(new DefaultInputModule("module"), statusDetectionFactory, new FileMetadata())).isNotNull();
}
}
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 java.nio.file.Path;
+import java.nio.file.Paths;
import org.apache.commons.io.FileUtils;
import org.junit.Assert;
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.DefaultInputModule;
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 {
private StatusDetection statusDetection;
@Mock
private DefaultModuleFileSystem fs;
- @Mock
- private FileMetadata metadata;
- private MetadataGenerator builder;
+ private FileMetadata metadata;
+ private MetadataGenerator generator;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- builder = new MetadataGenerator(statusDetection, metadata);
- // TODO
+ metadata = new FileMetadata();
+ generator = new MetadataGenerator(new DefaultInputModule("module"), statusDetection, metadata);
+ }
+
+ @Test
+ public void should_detect_charset_from_BOM() {
+ Path basedir = Paths.get("src/test/resources/org/sonar/scanner/scan/filesystem/");
+
+ assertThat(createInputFileWithMetadata(generator, basedir, "without_BOM.txt").charset())
+ .isEqualTo(StandardCharsets.US_ASCII);
+ assertThat(createInputFileWithMetadata(generator, basedir, "UTF-8.txt").charset())
+ .isEqualTo(StandardCharsets.UTF_8);
+ assertThat(createInputFileWithMetadata(generator, basedir, "UTF-16BE.txt").charset())
+ .isEqualTo(StandardCharsets.UTF_16BE);
+ assertThat(createInputFileWithMetadata(generator, basedir, "UTF-16LE.txt").charset())
+ .isEqualTo(StandardCharsets.UTF_16LE);
+ assertThat(createInputFileWithMetadata(generator, basedir, "UTF-32BE.txt").charset())
+ .isEqualTo(MetadataGenerator.UTF_32BE);
+ assertThat(createInputFileWithMetadata(generator, basedir, "UTF-32LE.txt").charset())
+ .isEqualTo(MetadataGenerator.UTF_32LE);
+
+ try {
+ createInputFileWithMetadata(generator, basedir, "non_existing");
+ Assert.fail();
+ } catch (IllegalStateException e) {
+ assertThat(e.getMessage()).endsWith("Unable to read file " + basedir.resolve("non_existing").toAbsolutePath());
+ assertThat(e.getCause()).isInstanceOf(IllegalStateException.class);
+ }
+ }
+
+ private DefaultInputFile createInputFileWithMetadata(MetadataGenerator generator, Path baseDir, String relativePath) {
+ DefaultInputFile inputFile = new TestInputFileBuilder("struts", relativePath)
+ .setModuleBaseDir(baseDir)
+ .build();
+ generator.setMetadata(inputFile, StandardCharsets.US_ASCII);
+ return inputFile;
+ }
+
+ @Test
+ public void complete_input_file() throws Exception {
+ // file system
+ Path baseDir = temp.newFolder().toPath();
+ Path srcFile = baseDir.resolve("src/main/java/foo/Bar.java");
+ FileUtils.touch(srcFile.toFile());
+ FileUtils.write(srcFile.toFile(), "single line");
+
+ // status
+ when(statusDetection.status("foo", "src/main/java/foo/Bar.java", "6c1d64c0b3555892fe7273e954f6fb5a"))
+ .thenReturn(InputFile.Status.ADDED);
+
+ InputFile inputFile = createInputFileWithMetadata(generator, baseDir, "src/main/java/foo/Bar.java");
+
+ assertThat(inputFile.type()).isEqualTo(InputFile.Type.MAIN);
+ assertThat(inputFile.file()).isEqualTo(srcFile.toFile());
+ assertThat(inputFile.absolutePath()).isEqualTo(PathUtils.sanitize(srcFile.toAbsolutePath().toString()));
+ 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 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();
- * }
- */
}
SIMPLE_DATE_FORMAT.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
when(server.getVersion()).thenReturn("3.6");
- DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts", TestInputFileBuilder.batchId++);
+ DefaultInputDir inputDir = new DefaultInputDir("struts", "src/main/java/org/apache/struts", TestInputFileBuilder.nextBatchId());
DefaultInputFile inputFile = new TestInputFileBuilder("struts", "src/main/java/org/apache/struts/Action.java").build();
inputFile.setStatus(InputFile.Status.CHANGED);
InputComponentStore fileCache = mock(InputComponentStore.class);
import org.sonar.api.config.MapSettings;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
-import org.sonar.api.resources.File;
-import org.sonar.api.resources.Resource;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.core.metric.ScannerMetrics;
import org.sonar.scanner.cpd.index.SonarCpdBlockIndex;
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");
when(measureCache.put(eq(file.key()), eq(CoreMetrics.NCLOC_KEY), argumentCaptor.capture())).thenReturn(null);
underTest.store(new DefaultMeasure()
.on(file)
public File contextProperties() {
return new File(dir, "context-props.pb");
}
+
+ public File root() {
+ return dir;
+ }
}