aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJulien HENRY <julien.henry@sonarsource.com>2017-08-01 14:43:55 +0200
committerJulien HENRY <julien.henry@sonarsource.com>2017-08-04 14:58:16 +0200
commite6b28c1ba4e7627f4599590ddfcc21875843ce87 (patch)
tree76d3344308689e5f448ba160f3f4bd90649344cf
parentef26b6a20f4a813079538b60f97dba53dc4108c1 (diff)
downloadsonarqube-e6b28c1ba4e7627f4599590ddfcc21875843ce87.tar.gz
sonarqube-e6b28c1ba4e7627f4599590ddfcc21875843ce87.zip
Store project relative path inside DefaultIndexedFile
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java5
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java38
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/SensorStrategy.java (renamed from sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorStrategy.java)2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java2
-rw-r--r--sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java66
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java2
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java7
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java16
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java5
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java11
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java19
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/CoverageExclusionsTest.java1
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java2
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java6
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java24
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java2
17 files changed, 135 insertions, 75 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java
index 92253347869..951f8d8ecff 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/InputFile.java
@@ -26,6 +26,7 @@ import java.nio.charset.Charset;
import java.nio.file.Path;
import javax.annotation.CheckForNull;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
+import org.sonar.api.batch.sensor.SensorDescriptor;
/**
* This layer over {@link java.io.File} adds information for code analyzers.
@@ -54,8 +55,8 @@ public interface InputFile extends IndexedFile {
}
/**
- * Path relative to module base directory. Path is unique and identifies file
- * within given <code>{@link FileSystem}</code>. File separator is the forward
+ * Relative path to module (for normal Sensors) or project (for {@link SensorDescriptor#global() global} Sensors) base directory.
+ * File separator is the forward
* slash ('/'), even on Microsoft Windows.
* <br>
* Returns <code>src/main/java/com/Foo.java</code> if module base dir is
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java
index a91ab8ad2aa..0d07003dce5 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultIndexedFile.java
@@ -37,37 +37,37 @@ import org.sonar.api.utils.PathUtils;
*/
@Immutable
public class DefaultIndexedFile extends DefaultInputComponent implements IndexedFile {
- private final String relativePath;
+ private final String projectRelativePath;
+ private final String moduleRelativePath;
private final String moduleKey;
- private final Path moduleBaseDir;
private final String language;
private final Type type;
- private final Path path;
+ private final Path absolutePath;
+ private final SensorStrategy sensorStrategy;
/**
* Testing purposes only!
*/
- public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath, @Nullable String language) {
- this(moduleKey, moduleBaseDir, relativePath, language, TestInputFileBuilder.nextBatchId());
+ public DefaultIndexedFile(String moduleKey, Path baseDir, String relativePath, @Nullable String language) {
+ this(baseDir.resolve(relativePath), moduleKey, PathUtils.sanitize(relativePath), PathUtils.sanitize(relativePath), Type.MAIN, language, TestInputFileBuilder.nextBatchId(),
+ new SensorStrategy());
}
- public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath, @Nullable String language, int batchId) {
- this(moduleKey, moduleBaseDir, relativePath, Type.MAIN, language, batchId);
- }
-
- public DefaultIndexedFile(String moduleKey, Path moduleBaseDir, String relativePath, Type type, @Nullable String language, int batchId) {
+ public DefaultIndexedFile(Path absolutePath, String moduleKey, String projectRelativePath, String moduleRelativePath, Type type, @Nullable String language, int batchId,
+ SensorStrategy sensorStrategy) {
super(batchId);
this.moduleKey = moduleKey;
- this.relativePath = PathUtils.sanitize(relativePath);
- this.moduleBaseDir = moduleBaseDir.normalize();
+ this.projectRelativePath = projectRelativePath;
+ this.moduleRelativePath = moduleRelativePath;
this.type = type;
this.language = language;
- this.path = this.moduleBaseDir.resolve(this.relativePath);
+ this.sensorStrategy = sensorStrategy;
+ this.absolutePath = absolutePath;
}
@Override
public String relativePath() {
- return relativePath;
+ return sensorStrategy.isGlobal() ? projectRelativePath : moduleRelativePath;
}
@Override
@@ -82,7 +82,7 @@ public class DefaultIndexedFile extends DefaultInputComponent implements Indexed
@Override
public Path path() {
- return path;
+ return absolutePath;
}
@Override
@@ -106,7 +106,7 @@ public class DefaultIndexedFile extends DefaultInputComponent implements Indexed
*/
@Override
public String key() {
- return new StringBuilder().append(moduleKey).append(":").append(relativePath).toString();
+ return new StringBuilder().append(moduleKey).append(":").append(moduleRelativePath).toString();
}
public String moduleKey() {
@@ -124,17 +124,17 @@ public class DefaultIndexedFile extends DefaultInputComponent implements Indexed
}
DefaultIndexedFile that = (DefaultIndexedFile) o;
- return moduleKey.equals(that.moduleKey) && relativePath.equals(that.relativePath);
+ return projectRelativePath.equals(that.projectRelativePath);
}
@Override
public int hashCode() {
- return moduleKey.hashCode() + relativePath.hashCode() * 13;
+ return projectRelativePath.hashCode();
}
@Override
public String toString() {
- return "[moduleKey=" + moduleKey + ", relative=" + relativePath + ", basedir=" + moduleBaseDir + "]";
+ return projectRelativePath;
}
@Override
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorStrategy.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/SensorStrategy.java
index ebdba341751..5e8b34eb86b 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/SensorStrategy.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/SensorStrategy.java
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.scanner.sensor;
+package org.sonar.api.batch.fs.internal;
/**
* A shared, mutable object in the module container.
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java
index df2bc17d5fa..671790bdf43 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java
@@ -192,7 +192,7 @@ public class TestInputFileBuilder {
}
public DefaultInputFile build() {
- DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type, language, id);
+ DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleBaseDir.resolve(relativePath), moduleKey, relativePath, relativePath, type, language, id, new SensorStrategy());
DefaultInputFile inputFile = new DefaultInputFile(indexedFile,
f -> f.setMetadata(new Metadata(lines, nonBlankLines, hash, originalLineOffsets, lastValidOffset)),
contents);
diff --git a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
index cf66115c695..7d699d5bf39 100644
--- a/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
+++ b/sonar-plugin-api/src/test/java/org/sonar/api/batch/fs/internal/DefaultInputFileTest.java
@@ -34,6 +34,7 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.stream.Collectors;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
@@ -46,36 +47,52 @@ import static org.mockito.Mockito.mock;
public class DefaultInputFileTest {
+ private static final String PROJECT_RELATIVE_PATH = "module1/src/Foo.php";
+ private static final String MODULE_RELATIVE_PATH = "src/Foo.php";
+
@Rule
public TemporaryFolder temp = new TemporaryFolder();
+ private DefaultIndexedFile indexedFile;
+
+ private Path baseDir;
+ private SensorStrategy sensorStrategy;
+
+ @Before
+ public void prepare() throws IOException {
+ baseDir = temp.newFolder().toPath();
+ sensorStrategy = new SensorStrategy();
+ indexedFile = new DefaultIndexedFile(baseDir.resolve(PROJECT_RELATIVE_PATH), "ABCDE", PROJECT_RELATIVE_PATH, MODULE_RELATIVE_PATH, InputFile.Type.TEST, "php", 0,
+ sensorStrategy);
+ }
+
@Test
public void test() throws Exception {
- Path baseDir = temp.newFolder().toPath();
Metadata metadata = new Metadata(42, 42, "", new int[0], 0);
- DefaultIndexedFile indexedFile = new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST, "php", 0);
DefaultInputFile inputFile = new DefaultInputFile(indexedFile, (f) -> f.setMetadata(metadata))
.setStatus(InputFile.Status.ADDED)
.setCharset(StandardCharsets.ISO_8859_1);
- assertThat(inputFile.relativePath()).isEqualTo("src/Foo.php");
+ assertThat(inputFile.relativePath()).isEqualTo(MODULE_RELATIVE_PATH);
assertThat(new File(inputFile.relativePath())).isRelative();
assertThat(inputFile.absolutePath()).endsWith("Foo.php");
assertThat(inputFile.filename()).isEqualTo("Foo.php");
- assertThat(inputFile.uri()).hasPath(baseDir.resolve("src/Foo.php").toUri().getPath());
+ assertThat(inputFile.uri()).hasPath(baseDir.resolve(PROJECT_RELATIVE_PATH).toUri().getPath());
assertThat(new File(inputFile.absolutePath())).isAbsolute();
assertThat(inputFile.language()).isEqualTo("php");
assertThat(inputFile.status()).isEqualTo(InputFile.Status.ADDED);
assertThat(inputFile.type()).isEqualTo(InputFile.Type.TEST);
assertThat(inputFile.lines()).isEqualTo(42);
assertThat(inputFile.charset()).isEqualTo(StandardCharsets.ISO_8859_1);
+
+ sensorStrategy.setGlobal(true);
+ assertThat(inputFile.relativePath()).isEqualTo(PROJECT_RELATIVE_PATH);
}
@Test
public void test_content() throws IOException {
- Path baseDir = temp.newFolder().toPath();
- Path testFile = baseDir.resolve("src").resolve("Foo.php");
+ Path testFile = baseDir.resolve(PROJECT_RELATIVE_PATH);
Files.createDirectories(testFile.getParent());
String content = "test é string";
Files.write(testFile, content.getBytes(StandardCharsets.ISO_8859_1));
@@ -84,7 +101,7 @@ public class DefaultInputFileTest {
Metadata metadata = new Metadata(42, 30, "", new int[0], 0);
- DefaultInputFile inputFile = new DefaultInputFile(new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST, "php", 0), f -> f.setMetadata(metadata))
+ DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata))
.setStatus(InputFile.Status.ADDED)
.setCharset(StandardCharsets.ISO_8859_1);
@@ -98,8 +115,7 @@ public class DefaultInputFileTest {
@Test
public void test_content_exclude_bom() throws IOException {
- Path baseDir = temp.newFolder().toPath();
- Path testFile = baseDir.resolve("src").resolve("Foo.php");
+ Path testFile = baseDir.resolve(PROJECT_RELATIVE_PATH);
Files.createDirectories(testFile.getParent());
try (BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(testFile.toFile()), StandardCharsets.UTF_8))) {
out.write('\ufeff');
@@ -111,7 +127,7 @@ public class DefaultInputFileTest {
Metadata metadata = new Metadata(42, 30, "", new int[0], 0);
- DefaultInputFile inputFile = new DefaultInputFile(new DefaultIndexedFile("ABCDE", baseDir, "src/Foo.php", InputFile.Type.TEST, "php", 0), f -> f.setMetadata(metadata))
+ DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> f.setMetadata(metadata))
.setStatus(InputFile.Status.ADDED)
.setCharset(StandardCharsets.UTF_8);
@@ -125,8 +141,8 @@ public class DefaultInputFileTest {
@Test
public void test_equals_and_hashcode() throws Exception {
- DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php", null), (f) -> mock(Metadata.class));
- DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php", null), (f) -> mock(Metadata.class));
+ DefaultInputFile f1 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class));
+ DefaultInputFile f1a = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class));
DefaultInputFile f2 = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Bar.php", null), (f) -> mock(Metadata.class));
assertThat(f1).isEqualTo(f1);
@@ -141,14 +157,14 @@ public class DefaultInputFileTest {
@Test
public void test_toString() throws Exception {
- DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), "src/Foo.php", null), (f) -> mock(Metadata.class));
- assertThat(file.toString()).isEqualTo("[moduleKey=ABCDE, relative=src/Foo.php, basedir=module]");
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), (f) -> mock(Metadata.class));
+ assertThat(file.toString()).isEqualTo(MODULE_RELATIVE_PATH);
}
@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", null), f -> f.setMetadata(metadata));
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
assertThat(file.newPointer(1, 0).line()).isEqualTo(1);
assertThat(file.newPointer(1, 0).lineOffset()).isEqualTo(0);
// Don't fail
@@ -166,7 +182,7 @@ public class DefaultInputFileTest {
file.newPointer(3, 1);
fail();
} catch (Exception e) {
- assertThat(e).hasMessage("3 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 2 line(s)");
+ assertThat(e).hasMessage("3 is not a valid line for pointer. File src/Foo.php has 2 line(s)");
}
try {
file.newPointer(1, -1);
@@ -178,14 +194,14 @@ public class DefaultInputFileTest {
file.newPointer(1, 10);
fail();
} catch (Exception e) {
- assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 9 character(s) at line 1");
+ assertThat(e).hasMessage("10 is not a valid line offset for pointer. File src/Foo.php has 9 character(s) at line 1");
}
}
@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", null), f -> f.setMetadata(metadata));
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
assertThat(file.newPointer(0).line()).isEqualTo(1);
assertThat(file.newPointer(0).lineOffset()).isEqualTo(0);
@@ -209,14 +225,14 @@ public class DefaultInputFileTest {
file.newPointer(16);
fail();
} catch (Exception e) {
- assertThat(e).hasMessage("16 is not a valid offset for file [moduleKey=ABCDE, relative=src/Foo.php, basedir=module]. Max offset is 15");
+ assertThat(e).hasMessage("16 is not a valid offset for file src/Foo.php. Max offset is 15");
}
}
@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", null), f -> f.setMetadata(metadata));
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
assertThat(file.newRange(file.newPointer(1, 0), file.newPointer(2, 1)).start().line()).isEqualTo(1);
// Don't fail
@@ -235,14 +251,14 @@ public class DefaultInputFileTest {
file.newRange(file.newPointer(1, 0), file.newPointer(1, 10));
fail();
} catch (Exception e) {
- assertThat(e).hasMessage("10 is not a valid line offset for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 9 character(s) at line 1");
+ assertThat(e).hasMessage("10 is not a valid line offset for pointer. File src/Foo.php has 9 character(s) at line 1");
}
}
@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", null), f -> f.setMetadata(metadata));
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
assertThat(file.selectLine(1).start().line()).isEqualTo(1);
assertThat(file.selectLine(1).start().lineOffset()).isEqualTo(0);
@@ -259,14 +275,14 @@ public class DefaultInputFileTest {
file.selectLine(5);
fail();
} catch (Exception e) {
- assertThat(e).hasMessage("5 is not a valid line for pointer. File [moduleKey=ABCDE, relative=src/Foo.php, basedir=module] has 4 line(s)");
+ assertThat(e).hasMessage("5 is not a valid line for pointer. File src/Foo.php has 4 line(s)");
}
}
@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", null), f -> f.setMetadata(metadata));
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), f -> f.setMetadata(metadata));
TextRange newRange = file.newRange(10, 13);
assertThat(newRange.start().line()).isEqualTo(2);
assertThat(newRange.start().lineOffset()).isEqualTo(0);
@@ -277,7 +293,7 @@ public class DefaultInputFileTest {
@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", null), f -> f.setMetadata(metadata));
+ DefaultInputFile file = new DefaultInputFile(new DefaultIndexedFile("ABCDE", Paths.get("module"), MODULE_RELATIVE_PATH, null), 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();
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java
index 88158bfb065..78a596dcd92 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/phases/SensorsExecutor.java
@@ -28,10 +28,10 @@ import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.batch.fs.internal.SensorStrategy;
import org.sonar.api.resources.Project;
import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary;
import org.sonar.scanner.events.EventBus;
-import org.sonar.scanner.sensor.SensorStrategy;
@ScannerSide
public class SensorsExecutor {
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
index b949f802e61..b9c7d779257 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/ModuleScanContainer.java
@@ -25,6 +25,7 @@ import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.InstantiationStrategy;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.fs.internal.SensorStrategy;
import org.sonar.api.batch.rule.CheckFactory;
import org.sonar.api.resources.Project;
import org.sonar.api.scan.filesystem.FileExclusions;
@@ -70,7 +71,6 @@ import org.sonar.scanner.scan.filesystem.StatusDetectionFactory;
import org.sonar.scanner.scan.report.IssuesReports;
import org.sonar.scanner.sensor.DefaultSensorStorage;
import org.sonar.scanner.sensor.SensorOptimizer;
-import org.sonar.scanner.sensor.SensorStrategy;
import org.sonar.scanner.source.HighlightableBuilder;
import org.sonar.scanner.source.SymbolizableBuilder;
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
index b120e1fd7a8..4b78ce2f6c6 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/FileIndexer.java
@@ -163,8 +163,7 @@ public class FileIndexer {
private Void indexFile(Path sourceFile, InputFile.Type type, Progress progress) throws IOException {
// get case of real file without resolving link
Path realAbsoluteFile = sourceFile.toRealPath(LinkOption.NOFOLLOW_LINKS).toAbsolutePath().normalize();
- String relativePathStr = PathResolver.relativePath(module.getBaseDir(), realAbsoluteFile);
- if (relativePathStr == null) {
+ if (!realAbsoluteFile.startsWith(module.getBaseDir())) {
LOG.warn("File '{}' is ignored. It is not located in module basedir '{}'.", realAbsoluteFile.toAbsolutePath(), module.getBaseDir());
return null;
}
@@ -178,7 +177,7 @@ public class FileIndexer {
LOG.warn("File '{}' is ignored because it doesn't belong to the forced language '{}'", realAbsoluteFile.toAbsolutePath(), langDetection.forcedLanguage());
return null;
}
- DefaultInputFile inputFile = inputFileBuilder.create(type, relativePathStr, language);
+ DefaultInputFile inputFile = inputFileBuilder.create(type, realAbsoluteFile, language);
if (!accept(inputFile)) {
progress.increaseExcludedByPatternsCount();
return null;
@@ -188,7 +187,7 @@ public class FileIndexer {
indexFileAndParentDir(inputFile, parentRelativePath);
progress.markAsIndexed(inputFile);
}
- LOG.debug("'{}' indexed {}with language '{}'", relativePathStr, type == Type.TEST ? "as test " : "", inputFile.language());
+ LOG.debug("'{}' indexed {}with language '{}'", relativePath, type == Type.TEST ? "as test " : "", inputFile.language());
inputFileBuilder.checkMetadata(inputFile);
return null;
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java
index d8980917519..aee7714e9fc 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/InputFileBuilder.java
@@ -25,7 +25,10 @@ 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.InputModuleHierarchy;
+import org.sonar.api.batch.fs.internal.SensorStrategy;
import org.sonar.api.config.Configuration;
+import org.sonar.api.utils.PathUtils;
public class InputFileBuilder {
public static final String PRELOAD_FILE_METADATA_KEY = "sonar.preloadFileMetadata";
@@ -35,9 +38,13 @@ public class InputFileBuilder {
private final MetadataGenerator metadataGenerator;
private final boolean preloadMetadata;
private final ModuleFileSystemInitializer moduleFileSystemInitializer;
+ private final Path projectBaseDir;
+ private final SensorStrategy sensorStrategy;
public InputFileBuilder(DefaultInputModule module, MetadataGenerator metadataGenerator,
- BatchIdGenerator idGenerator, Configuration settings, ModuleFileSystemInitializer moduleFileSystemInitializer) {
+ BatchIdGenerator idGenerator, Configuration settings, ModuleFileSystemInitializer moduleFileSystemInitializer, InputModuleHierarchy hierarchy, SensorStrategy sensorStrategy) {
+ this.sensorStrategy = sensorStrategy;
+ this.projectBaseDir = hierarchy.root().getBaseDir();
this.moduleFileSystemInitializer = moduleFileSystemInitializer;
this.moduleKey = module.key();
this.moduleBaseDir = module.getBaseDir();
@@ -46,8 +53,11 @@ public class InputFileBuilder {
this.preloadMetadata = settings.getBoolean(PRELOAD_FILE_METADATA_KEY).orElse(false);
}
- DefaultInputFile create(InputFile.Type type, String relativePath, @Nullable String language) {
- DefaultIndexedFile indexedFile = new DefaultIndexedFile(moduleKey, moduleBaseDir, relativePath, type, language, idGenerator.get());
+ DefaultInputFile create(InputFile.Type type, Path absolutePath, @Nullable String language) {
+ DefaultIndexedFile indexedFile = new DefaultIndexedFile(absolutePath, moduleKey,
+ PathUtils.sanitize(projectBaseDir.relativize(absolutePath).toString()),
+ PathUtils.sanitize(moduleBaseDir.relativize(absolutePath).toString()),
+ type, language, idGenerator.get(), sensorStrategy);
DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(f, moduleFileSystemInitializer.defaultEncoding()));
if (language != null) {
inputFile.setPublished(true);
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java
index cca6b49fb14..56c926c83e4 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStore.java
@@ -25,7 +25,7 @@ import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
-import org.sonar.scanner.sensor.SensorStrategy;
+import org.sonar.api.batch.fs.internal.SensorStrategy;
@ScannerSide
public class ModuleInputComponentStore extends DefaultFileSystem.Cache {
@@ -91,7 +91,8 @@ public class ModuleInputComponentStore extends DefaultFileSystem.Cache {
return inputComponentStore.getFilesByName(filename);
}
- @Override public Iterable<InputFile> getFilesByExtension(String extension) {
+ @Override
+ public Iterable<InputFile> getFilesByExtension(String extension) {
return inputComponentStore.getFilesByExtension(extension);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java
index c7774c750e9..111ddeebfc5 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/cpd/CpdSettingsTest.java
@@ -19,19 +19,18 @@
*/
package org.sonar.scanner.cpd;
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import java.util.Optional;
-
import org.junit.Before;
import org.junit.Test;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
import org.sonar.api.config.Configuration;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
public class CpdSettingsTest {
private CpdSettings cpdSettings;
private Configuration configuration;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java
index a61330e3657..5f2add6955a 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/fs/FileSystemMediumTest.java
@@ -712,4 +712,23 @@ public class FileSystemMediumTest {
assertThat(result.inputFiles()).hasSize(1);
}
+
+ @Test
+ public void detectDuplicatedFilesInDifferentModules() throws IOException {
+ File srcDir = new File(baseDir, "module1/src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ FileUtils.write(xooFile, "Sample xoo\ncontent");
+
+ TaskResult result = tester.newTask()
+ .properties(builder
+ .put("sonar.sources", "module1/src")
+ .put("sonar.modules", "module1")
+ .put("module1.sonar.sources", "src")
+ .build())
+ .execute();
+
+ assertThat(result.inputFiles()).hasSize(1);
+ }
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/CoverageExclusionsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/CoverageExclusionsTest.java
index 166964fcdc7..a6d208b35bb 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/CoverageExclusionsTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/CoverageExclusionsTest.java
@@ -26,7 +26,6 @@ import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.config.PropertyDefinitions;
import org.sonar.api.config.internal.MapSettings;
import org.sonar.core.config.ExclusionProperties;
-import org.sonar.scanner.phases.CoverageExclusions;
import static org.assertj.core.api.Assertions.assertThat;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java
index 2a68b02aa16..d56d2be32ed 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/phases/SensorsExecutorTest.java
@@ -30,11 +30,11 @@ import org.sonar.api.batch.SensorContext;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.InputModuleHierarchy;
+import org.sonar.api.batch.fs.internal.SensorStrategy;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
import org.sonar.api.resources.Project;
import org.sonar.scanner.bootstrap.ScannerExtensionDictionnary;
import org.sonar.scanner.events.EventBus;
-import org.sonar.scanner.sensor.SensorStrategy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java
index 24fa9205c37..1b59e69bd18 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/ProjectReactorValidatorTest.java
@@ -19,9 +19,6 @@
*/
package org.sonar.scanner.scan;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -32,6 +29,9 @@ import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.utils.MessageException;
import org.sonar.scanner.analysis.DefaultAnalysisMode;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
public class ProjectReactorValidatorTest {
@Rule
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java
index a4c6a32b6dd..6611f15302b 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/InputFileBuilderTest.java
@@ -30,7 +30,9 @@ 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.batch.fs.internal.SensorStrategy;
import org.sonar.api.config.internal.MapSettings;
+import org.sonar.scanner.scan.DefaultInputModuleHierarchy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -44,13 +46,19 @@ public class InputFileBuilderTest {
private Path workDir;
private InputFileBuilder builder;
+ private SensorStrategy sensorStrategy;
+
@Before
public void setUp() throws IOException {
baseDir = temp.newFolder().toPath();
workDir = temp.newFolder().toPath();
- DefaultInputModule module = new DefaultInputModule(ProjectDefinition.create()
+ DefaultInputModule root = new DefaultInputModule(ProjectDefinition.create()
.setBaseDir(baseDir.toFile())
.setWorkDir(workDir.toFile())
+ .setKey("root"), 0);
+ DefaultInputModule module = new DefaultInputModule(ProjectDefinition.create()
+ .setBaseDir(baseDir.resolve("module1").toFile())
+ .setWorkDir(workDir.toFile())
.setKey("module1"), 0);
MetadataGenerator metadataGenerator = mock(MetadataGenerator.class);
@@ -58,17 +66,25 @@ public class InputFileBuilderTest {
MapSettings settings = new MapSettings();
ModuleFileSystemInitializer moduleFileSystemInitializer = mock(ModuleFileSystemInitializer.class);
when(moduleFileSystemInitializer.defaultEncoding()).thenReturn(StandardCharsets.UTF_8);
- builder = new InputFileBuilder(module, metadataGenerator, idGenerator, settings.asConfig(), moduleFileSystemInitializer);
+ sensorStrategy = new SensorStrategy();
+ builder = new InputFileBuilder(module, metadataGenerator, idGenerator, settings.asConfig(), moduleFileSystemInitializer, new DefaultInputModuleHierarchy(root),
+ sensorStrategy);
}
@Test
public void testBuild() {
- Path filePath = baseDir.resolve("src/File1.xoo");
- DefaultInputFile inputFile = builder.create(Type.MAIN, "src/File1.xoo", null);
+ Path filePath = baseDir.resolve("module1/src/File1.xoo");
+ DefaultInputFile inputFile = builder.create(Type.MAIN, filePath, null);
assertThat(inputFile.moduleKey()).isEqualTo("module1");
assertThat(inputFile.absolutePath()).isEqualTo(filePath.toString().replaceAll("\\\\", "/"));
+ assertThat(inputFile.relativePath()).isEqualTo("src/File1.xoo");
+ assertThat(inputFile.path()).isEqualTo(filePath);
assertThat(inputFile.key()).isEqualTo("module1:src/File1.xoo");
assertThat(inputFile.isPublished()).isFalse();
+
+ sensorStrategy.setGlobal(true);
+
+ assertThat(inputFile.relativePath()).isEqualTo("module1/src/File1.xoo");
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java
index 4d2e97d0c23..ff1f957bccf 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/scan/filesystem/ModuleInputComponentStoreTest.java
@@ -27,8 +27,8 @@ import org.junit.rules.TemporaryFolder;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputModule;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
+import org.sonar.api.batch.fs.internal.SensorStrategy;
import org.sonar.api.batch.fs.internal.TestInputFileBuilder;
-import org.sonar.scanner.sensor.SensorStrategy;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.any;