diff options
author | Duarte Meneses <duarte.meneses@sonarsource.com> | 2016-07-08 15:59:54 +0200 |
---|---|---|
committer | Duarte Meneses <duarte.meneses@sonarsource.com> | 2016-07-11 10:53:30 +0200 |
commit | ae5a68d2050ec017ca30b9e770e3ce0a5beae806 (patch) | |
tree | 4dc2feb31a5fd10cb00d17f4eafd432534178abe /plugins | |
parent | be5552b150a28447800c588202a0cf78694bf3e3 (diff) | |
download | sonarqube-ae5a68d2050ec017ca30b9e770e3ce0a5beae806.tar.gz sonarqube-ae5a68d2050ec017ca30b9e770e3ce0a5beae806.zip |
SONAR-7876 Add an API for Sensors to report files that can't be analyzed
Diffstat (limited to 'plugins')
4 files changed, 180 insertions, 2 deletions
diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java index 870992596e7..1ff4660920f 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/XooPlugin.java @@ -32,6 +32,7 @@ import org.sonar.xoo.lang.SymbolReferencesSensor; import org.sonar.xoo.lang.SyntaxHighlightingSensor; import org.sonar.xoo.lang.XooCpdMapping; import org.sonar.xoo.lang.XooTokenizer; +import org.sonar.xoo.rule.AnalysisErrorSensor; import org.sonar.xoo.rule.ChecksSensor; import org.sonar.xoo.rule.CreateIssueByInternalKeySensor; import org.sonar.xoo.rule.CustomMessageSensor; @@ -118,6 +119,9 @@ public class XooPlugin implements Plugin { ItCoverageSensor.class, OverallCoverageSensor.class, + // Analysis errors + AnalysisErrorSensor.class, + // Tests TestExecutionSensor.class, CoveragePerTestSensor.class, diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AnalysisErrorSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AnalysisErrorSensor.java new file mode 100644 index 00000000000..126225961d4 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/AnalysisErrorSensor.java @@ -0,0 +1,95 @@ +/* + * 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.xoo.rule; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.sonar.api.batch.fs.InputFile; +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.xoo.Xoo; + +public class AnalysisErrorSensor implements Sensor { + private static final Logger LOG = Loggers.get(AnalysisErrorSensor.class); + private static final String ERROR_EXTENSION = ".error"; + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor + .name("Xoo Analysis Error Sensor") + .onlyOnLanguages(Xoo.KEY); + } + + @Override + public void execute(SensorContext context) { + for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) { + processFileError(file, context); + } + } + + private void processFileError(InputFile inputFile, SensorContext context) { + Path ioFile = inputFile.file().toPath(); + Path errorFile = ioFile.resolveSibling(ioFile.getFileName() + ERROR_EXTENSION).toAbsolutePath(); + if (Files.exists(errorFile) && Files.isRegularFile(errorFile)) { + LOG.debug("Processing " + errorFile.toString()); + try { + List<String> lines = Files.readAllLines(errorFile, context.fileSystem().encoding()); + for (String line : lines) { + if (StringUtils.isBlank(line) || line.startsWith("#")) { + continue; + } + processLine(line, inputFile, context); + } + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + } + + private void processLine(String fileLine, InputFile inputFile, SensorContext context) { + String[] textPointer = fileLine.split(","); + if (textPointer.length != 3) { + throw new IllegalStateException("Invalid format in error file"); + } + + try { + int line = Integer.parseInt(textPointer[0]); + int lineOffset = Integer.parseInt(textPointer[1]); + String msg = textPointer[2]; + + context.newAnalysisError() + .onFile(inputFile) + .at(inputFile.newPointer(line, lineOffset)) + .message(msg) + .save(); + + } catch (NumberFormatException e) { + throw new IllegalStateException("Invalid format in error file", e); + } + } + +} diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java index b9255f056d8..f4184d1b113 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/XooPluginTest.java @@ -35,10 +35,10 @@ public class XooPluginTest { public void provide_extensions_for_5_5() { Plugin.Context context = new Plugin.Context(new SonarRuntime(Version.parse("5.5"), SonarProduct.SONARQUBE, SonarQubeSide.SCANNER)); new XooPlugin().define(context); - assertThat(context.getExtensions()).hasSize(41).contains(CpdTokenizerSensor.class); + assertThat(context.getExtensions()).hasSize(42).contains(CpdTokenizerSensor.class); context = new Plugin.Context(new SonarRuntime(Version.parse("5.4"), SonarProduct.SONARLINT, null)); new XooPlugin().define(context); - assertThat(context.getExtensions()).hasSize(40).doesNotContain(CpdTokenizerSensor.class); + assertThat(context.getExtensions()).hasSize(41).doesNotContain(CpdTokenizerSensor.class); } } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java new file mode 100644 index 00000000000..8067a67acb2 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/AnalysisErrorSensorTest.java @@ -0,0 +1,79 @@ +/* + * 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.xoo.rule; + +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; + +import static org.assertj.core.api.Assertions.*; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.internal.DefaultInputFile; +import org.sonar.api.batch.fs.internal.DefaultTextPointer; +import org.sonar.api.batch.sensor.error.AnalysisError; +import org.sonar.api.batch.sensor.internal.SensorContextTester; + +public class AnalysisErrorSensorTest { + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + private AnalysisErrorSensor sensor; + private SensorContextTester context; + + @Before + public void setUp() { + sensor = new AnalysisErrorSensor(); + } + + private void createErrorFile(Path baseDir) throws IOException { + Path srcDir = baseDir.resolve("src"); + Files.createDirectories(srcDir); + Path errorFile = srcDir.resolve("foo.xoo.error"); + + List<String> errors = new ArrayList<>(); + errors.add("1,4,my error"); + + Files.write(errorFile, errors, StandardCharsets.UTF_8); + } + + @Test + public void test() throws IOException { + Path baseDir = temp.newFolder().toPath().toAbsolutePath(); + createErrorFile(baseDir); + + DefaultInputFile inputFile = new DefaultInputFile("foo", "src/foo.xoo").setLanguage("xoo"); + context = SensorContextTester.create(baseDir); + context.fileSystem().add(inputFile); + + sensor.execute(context); + assertThat(context.allAnalysisErrors()).hasSize(1); + AnalysisError error = context.allAnalysisErrors().iterator().next(); + + assertThat(error.inputFile()).isEqualTo(inputFile); + assertThat(error.location()).isEqualTo(new DefaultTextPointer(1, 4)); + assertThat(error.message()).isEqualTo("my error"); + } +} |