diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2020-04-13 10:18:20 -0500 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2020-04-17 20:03:43 +0000 |
commit | 2ba726630087bb0baae61e05e1c20943ec9e6931 (patch) | |
tree | 73d132bc2aecc9f611b1e35d943d5b106aff0944 /sonar-plugin-api-impl | |
parent | e014a2b976e733f33f369b868dbdf475b06650fe (diff) | |
download | sonarqube-2ba726630087bb0baae61e05e1c20943ec9e6931.tar.gz sonarqube-2ba726630087bb0baae61e05e1c20943ec9e6931.zip |
SONAR-13206 Show warning if scanner fails to detect files' encoding
Diffstat (limited to 'sonar-plugin-api-impl')
5 files changed, 46 insertions, 26 deletions
diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java index 8e9cdb11bf6..751af8b7ef4 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/FileMetadata.java @@ -34,6 +34,7 @@ import org.sonar.api.batch.fs.internal.charhandler.FileHashComputer; import org.sonar.api.batch.fs.internal.charhandler.LineCounter; import org.sonar.api.batch.fs.internal.charhandler.LineHashComputer; import org.sonar.api.batch.fs.internal.charhandler.LineOffsetCounter; +import org.sonar.api.notifications.AnalysisWarnings; /** * Computes hash of files. Ends of Lines are ignored, so files with @@ -43,13 +44,18 @@ import org.sonar.api.batch.fs.internal.charhandler.LineOffsetCounter; public class FileMetadata { private static final char LINE_FEED = '\n'; private static final char CARRIAGE_RETURN = '\r'; + private final AnalysisWarnings analysisWarnings; + + public FileMetadata(AnalysisWarnings analysisWarnings) { + this.analysisWarnings = analysisWarnings; + } /** * Compute hash of a file ignoring line ends differences. * Maximum performance is needed. */ public Metadata readMetadata(InputStream stream, Charset encoding, String filePath, @Nullable CharHandler otherHandler) { - LineCounter lineCounter = new LineCounter(filePath, encoding); + LineCounter lineCounter = new LineCounter(analysisWarnings, filePath, encoding); FileHashComputer fileHashComputer = new FileHashComputer(filePath); LineOffsetCounter lineOffsetCounter = new LineOffsetCounter(); @@ -73,7 +79,7 @@ public class FileMetadata { * For testing purpose */ public Metadata readMetadata(Reader reader) { - LineCounter lineCounter = new LineCounter("fromString", StandardCharsets.UTF_16); + LineCounter lineCounter = new LineCounter(analysisWarnings, "fromString", StandardCharsets.UTF_16); FileHashComputer fileHashComputer = new FileHashComputer("fromString"); LineOffsetCounter lineOffsetCounter = new LineOffsetCounter(); CharHandler[] handlers = {lineCounter, fileHashComputer, lineOffsetCounter}; diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java index b0e9d79c3e8..cd5ff8ed3de 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/TestInputFileBuilder.java @@ -31,6 +31,7 @@ import javax.annotation.CheckForNull; import javax.annotation.Nullable; import org.sonar.api.batch.bootstrap.ProjectDefinition; import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.PathUtils; /** @@ -207,7 +208,8 @@ public class TestInputFileBuilder { } public TestInputFileBuilder initMetadata(String content) { - return setMetadata(new FileMetadata().readMetadata(new StringReader(content))); + AnalysisWarnings analysisWarnings = (warning) -> {}; + return setMetadata(new FileMetadata(analysisWarnings).readMetadata(new StringReader(content))); } public DefaultInputFile build() { diff --git a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineCounter.java b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineCounter.java index 95a4426cae3..cb3e7c563eb 100644 --- a/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineCounter.java +++ b/sonar-plugin-api-impl/src/main/java/org/sonar/api/batch/fs/internal/charhandler/LineCounter.java @@ -21,20 +21,24 @@ package org.sonar.api.batch.fs.internal.charhandler; import java.nio.charset.Charset; import org.sonar.api.CoreProperties; +import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; public class LineCounter extends CharHandler { private static final Logger LOG = Loggers.get(LineCounter.class); - + + private final AnalysisWarnings analysisWarnings; + private final String filePath; + private final Charset encoding; + private int lines = 1; private int nonBlankLines = 0; private boolean blankLine = true; boolean alreadyLoggedInvalidCharacter = false; - private final String filePath; - private final Charset encoding; - public LineCounter(String filePath, Charset encoding) { + public LineCounter(AnalysisWarnings analysisWarnings, String filePath, Charset encoding) { + this.analysisWarnings = analysisWarnings; this.filePath = filePath; this.encoding = encoding; } @@ -42,6 +46,7 @@ public class LineCounter extends CharHandler { @Override public void handleAll(char c) { if (!alreadyLoggedInvalidCharacter && c == '\ufffd') { + analysisWarnings.addUnique("There are problems with file encoding in the source code. Please check the scanner logs for more details."); LOG.warn("Invalid character encountered in file {} at line {} for encoding {}. Please fix file content or configure the encoding to be used using property '{}'.", filePath, lines, encoding, CoreProperties.ENCODING_PROPERTY); alreadyLoggedInvalidCharacter = true; diff --git a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputFileTest.java b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputFileTest.java index ca123ca3977..888b7ea81c7 100644 --- a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputFileTest.java +++ b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/DefaultInputFileTest.java @@ -45,6 +45,7 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.FileMetadata; import org.sonar.api.batch.fs.internal.Metadata; import org.sonar.api.batch.fs.internal.SensorStrategy; +import org.sonar.api.notifications.AnalysisWarnings; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @@ -246,7 +247,7 @@ public class DefaultInputFileTest { @Test public void checkValidRange() { - Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde")); + Metadata metadata = new FileMetadata(mock(AnalysisWarnings.class)).readMetadata(new StringReader("bla bla a\nabcde")); 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); @@ -272,7 +273,7 @@ public class DefaultInputFileTest { @Test public void selectLine() { - Metadata metadata = new FileMetadata().readMetadata(new StringReader("bla bla a\nabcde\n\nabc")); + Metadata metadata = new FileMetadata(mock(AnalysisWarnings.class)).readMetadata(new StringReader("bla bla a\nabcde\n\nabc")); 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); diff --git a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/FileMetadataTest.java b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/FileMetadataTest.java index ac4fb28818b..00642518985 100644 --- a/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/FileMetadataTest.java +++ b/sonar-plugin-api-impl/src/test/java/org/sonar/api/batch/fs/internal/fs/FileMetadataTest.java @@ -34,12 +34,15 @@ import org.sonar.api.batch.fs.internal.DefaultInputFile; import org.sonar.api.batch.fs.internal.FileMetadata; import org.sonar.api.batch.fs.internal.Metadata; import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.utils.log.LogTester; import org.sonar.api.utils.log.LoggerLevel; import static org.apache.commons.codec.digest.DigestUtils.md5Hex; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.fail; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; public class FileMetadataTest { @@ -52,12 +55,14 @@ public class FileMetadataTest { @Rule public LogTester logTester = new LogTester(); + private AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class); + @Test public void empty_file() throws Exception { File tempFile = temp.newFile(); FileUtils.touch(tempFile); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(1); assertThat(metadata.nonBlankLines()).isEqualTo(0); assertThat(metadata.hash()).isNotEmpty(); @@ -71,7 +76,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\r\nbar\r\nbaz", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(3); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); @@ -85,7 +90,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "marker´s\n", Charset.forName("cp1252")); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(2); assertThat(metadata.hash()).isEqualTo(md5Hex("marker\ufffds\n")); assertThat(metadata.originalLineStartOffsets()).containsOnly(0, 9); @@ -96,7 +101,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(4); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n")); @@ -107,7 +112,7 @@ public class FileMetadataTest { public void non_ascii_utf_16() throws Exception { File tempFile = temp.newFile(); FileUtils.write(tempFile, "föo\r\nbàr\r\n\u1D11Ebaßz\r\n", StandardCharsets.UTF_16, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_16, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_16, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(4); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("föo\nbàr\n\u1D11Ebaßz\n".getBytes(StandardCharsets.UTF_8))); @@ -119,7 +124,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\nbaz", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(3); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); @@ -133,7 +138,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\nbaz\n", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(4); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); @@ -146,7 +151,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\rbar\rbaz", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(3); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); @@ -159,7 +164,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\rbar\rbaz\r", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(4); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); @@ -172,7 +177,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\r\nbaz\n", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(4); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz\n")); @@ -185,7 +190,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\n\n\nbar", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(4); assertThat(metadata.nonBlankLines()).isEqualTo(2); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\n\n\nbar")); @@ -198,7 +203,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "foo\nbar\r\nbaz", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(3); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("foo\nbar\nbaz")); @@ -211,7 +216,7 @@ public class FileMetadataTest { File tempFile = temp.newFile(); FileUtils.write(tempFile, "\nfoo\nbar\r\nbaz", StandardCharsets.UTF_8, true); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(tempFile), StandardCharsets.UTF_8, tempFile.getName()); assertThat(metadata.lines()).isEqualTo(4); assertThat(metadata.nonBlankLines()).isEqualTo(3); assertThat(metadata.hash()).isEqualTo(md5Hex("\nfoo\nbar\nbaz")); @@ -285,9 +290,9 @@ public class FileMetadataTest { File file2 = temp.newFile(); FileUtils.write(file2, "foo\nbar", StandardCharsets.UTF_8, true); - String hash1 = new FileMetadata().readMetadata(new FileInputStream(file1), StandardCharsets.UTF_8, file1.getName()).hash(); - String hash1a = new FileMetadata().readMetadata(new FileInputStream(file1a), StandardCharsets.UTF_8, file1a.getName()).hash(); - String hash2 = new FileMetadata().readMetadata(new FileInputStream(file2), StandardCharsets.UTF_8, file2.getName()).hash(); + String hash1 = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(file1), StandardCharsets.UTF_8, file1.getName()).hash(); + String hash1a = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(file1a), StandardCharsets.UTF_8, file1a.getName()).hash(); + String hash2 = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(file2), StandardCharsets.UTF_8, file2.getName()).hash(); assertThat(hash1).isEqualTo(hash1a); assertThat(hash1).isNotEqualTo(hash2); @@ -297,13 +302,14 @@ public class FileMetadataTest { public void binary_file_with_unmappable_character() throws Exception { File woff = new File(this.getClass().getResource("glyphicons-halflings-regular.woff").toURI()); - Metadata metadata = new FileMetadata().readMetadata(new FileInputStream(woff), StandardCharsets.UTF_8, woff.getAbsolutePath()); + Metadata metadata = new FileMetadata(analysisWarnings).readMetadata(new FileInputStream(woff), StandardCharsets.UTF_8, woff.getAbsolutePath()); assertThat(metadata.lines()).isEqualTo(135); assertThat(metadata.nonBlankLines()).isEqualTo(133); assertThat(metadata.hash()).isNotEmpty(); assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains("Invalid character encountered in file"); + verify(analysisWarnings).addUnique("There are problems with file encoding in the source code. Please check the scanner logs for more details."); assertThat(logTester.logs(LoggerLevel.WARN).get(0)).contains( "glyphicons-halflings-regular.woff at line 1 for encoding UTF-8. Please fix file content or configure the encoding to be used using property 'sonar.sourceEncoding'."); } |