From 9b1ff379bf0fe1787a03fe743394dccc9a4c9eb9 Mon Sep 17 00:00:00 2001 From: Duarte Meneses Date: Mon, 30 Jan 2017 13:52:09 +0100 Subject: [PATCH] SONAR-8631 Only publish input files used by sensors --- .../main/java/org/sonar/xoo/XooPlugin.java | 2 + .../rule/OneIssuePerUnknownFileSensor.java | 56 +++++++++ .../sonar/xoo/rule/XooRulesDefinition.java | 3 + .../java/org/sonar/xoo/XooPluginTest.java | 4 +- .../xoo/rule/XooRulesDefinitionTest.java | 2 +- .../scanner/scan/filesystem/FileIndexer.java | 2 +- .../scan/filesystem/InputFileBuilder.java | 7 +- .../scanner/sensor/DefaultSensorStorage.java | 4 + .../mediumtest/fs/FileSystemMediumTest.java | 119 ++++++++++++------ 9 files changed, 158 insertions(+), 41 deletions(-) create mode 100644 plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerUnknownFileSensor.java 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 5dd494efb8e..6c0dec7a8b9 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 @@ -52,6 +52,7 @@ import org.sonar.xoo.rule.OneIssueOnDirPerFileSensor; import org.sonar.xoo.rule.OneIssuePerFileSensor; import org.sonar.xoo.rule.OneIssuePerLineSensor; import org.sonar.xoo.rule.OneIssuePerModuleSensor; +import org.sonar.xoo.rule.OneIssuePerUnknownFileSensor; import org.sonar.xoo.rule.OneVulnerabilityIssuePerModuleSensor; import org.sonar.xoo.rule.RandomAccessSensor; import org.sonar.xoo.rule.SaveDataTwiceSensor; @@ -122,6 +123,7 @@ public class XooPlugin implements Plugin { OneIssuePerFileSensor.class, OneIssuePerModuleSensor.class, OneIssueOnDirPerFileSensor.class, + OneIssuePerUnknownFileSensor.class, CreateIssueByInternalKeySensor.class, MultilineIssuesSensor.class, CustomMessageSensor.class, diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerUnknownFileSensor.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerUnknownFileSensor.java new file mode 100644 index 00000000000..e4480cf9928 --- /dev/null +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/OneIssuePerUnknownFileSensor.java @@ -0,0 +1,56 @@ +/* + * 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 org.sonar.api.batch.fs.FilePredicate; +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.batch.sensor.issue.NewIssue; +import org.sonar.api.rule.RuleKey; + +public class OneIssuePerUnknownFileSensor implements Sensor { + + public static final String RULE_KEY = "OneIssuePerUnknownFile"; + + @Override + public void describe(SensorDescriptor descriptor) { + descriptor.name("One Issue Per Unknown File"); + } + + @Override + public void execute(SensorContext context) { + RuleKey ruleKey = RuleKey.of(XooRulesDefinition.XOO_REPOSITORY, RULE_KEY); + FilePredicate unknownFilesPredicate = context.fileSystem().predicates().matchesPathPattern("**/*.unknown"); + Iterable unknownFiles = context.fileSystem().inputFiles(unknownFilesPredicate); + + unknownFiles.forEach(inputFile -> { + NewIssue newIssue = context.newIssue(); + newIssue + .forRule(ruleKey) + .at(newIssue.newLocation() + .on(inputFile) + .message("This issue is generated on each file with extension 'unknown'")) + .save(); + }); + } + +} diff --git a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java index 0940a41eec2..23ecb196b2d 100644 --- a/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java +++ b/plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/rule/XooRulesDefinition.java @@ -117,6 +117,9 @@ public class XooRulesDefinition implements RulesDefinition { repo.createRule(MultilineIssuesSensor.RULE_KEY).setName("Creates issues with ranges/multiple locations") .setHtmlDescription("Issue with range and multiple locations"); + repo.createRule(OneIssuePerUnknownFileSensor.RULE_KEY).setName("Creates issues on each file with extenstion 'unknown'") + .setHtmlDescription("This issue is generated on each file with extenstion 'unknown'"); + NewRule oneBugIssuePerLine = repo.createRule(OneBugIssuePerLineSensor.RULE_KEY).setName("One Bug Issue Per Line") .setHtmlDescription("Generate a bug issue on each line of a file. It requires the metric \"lines\".") .setType(RuleType.BUG); 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 1969b18c482..b8e8441b919 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 @@ -36,7 +36,7 @@ public class XooPluginTest { SonarRuntime runtime = SonarRuntimeImpl.forSonarLint(Version.parse("5.4")); Plugin.Context context = new Plugin.Context(runtime); new XooPlugin().define(context); - assertThat(context.getExtensions()).hasSize(42).doesNotContain(CpdTokenizerSensor.class); + assertThat(context.getExtensions()).hasSize(43).doesNotContain(CpdTokenizerSensor.class); } @Test @@ -44,6 +44,6 @@ public class XooPluginTest { SonarRuntime runtime = SonarRuntimeImpl.forSonarQube(Version.parse("5.5"), SonarQubeSide.SCANNER); Plugin.Context context = new Plugin.Context(runtime); new XooPlugin().define(context); - assertThat(context.getExtensions()).hasSize(45).contains(CpdTokenizerSensor.class); + assertThat(context.getExtensions()).hasSize(46).contains(CpdTokenizerSensor.class); } } diff --git a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java index 3f39fd0e271..e298ebbce0a 100644 --- a/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java +++ b/plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/rule/XooRulesDefinitionTest.java @@ -42,7 +42,7 @@ public class XooRulesDefinitionTest { assertThat(repo).isNotNull(); assertThat(repo.name()).isEqualTo("Xoo"); assertThat(repo.language()).isEqualTo("xoo"); - assertThat(repo.rules()).hasSize(15); + assertThat(repo.rules()).hasSize(16); RulesDefinition.Rule rule = repo.rule(OneIssuePerLineSensor.RULE_KEY); assertThat(rule.name()).isNotEmpty(); 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 c72c6ed09c0..ee90eeff8a4 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 @@ -172,7 +172,7 @@ public class FileIndexer { indexParentDir(fileSystem, inputFile); progress.markAsIndexed(inputFile); } - LOG.debug("'{}' indexed {} with language '{}'", inputFile.relativePath(), type == Type.TEST ? "as test " : "", inputFile.language()); + LOG.debug("'{}' indexed {}with language '{}'", inputFile.relativePath(), type == Type.TEST ? "as test " : "", inputFile.language()); inputFileBuilder.checkMetadata(inputFile); } else { progress.increaseExcludedByPatternsCount(); 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 4a41149f65b..d8c1747fbe1 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 @@ -70,7 +70,12 @@ public class InputFileBuilder { } indexedFile.setLanguage(language); - return new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(f, defaultEncoding)); + DefaultInputFile inputFile = new DefaultInputFile(indexedFile, f -> metadataGenerator.setMetadata(f, defaultEncoding)); + if (language != null) { + inputFile.setPublish(true); + } + + return inputFile; } void checkMetadata(DefaultInputFile inputFile) { diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java index 3ba1565e874..cce57c4dcba 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java @@ -218,6 +218,10 @@ public class DefaultSensorStorage implements SensorStorage { } public void saveMeasure(InputComponent component, DefaultMeasure measure) { + if (component.isFile()) { + ((DefaultInputFile) component).setPublish(true); + } + if (isDeprecatedMetric(measure.metric().key())) { logOnce(measure.metric().key(), "Metric '{}' is deprecated. Provided value is ignored.", measure.metric().key()); return; 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 7cfe5091725..1aaa9b7b02f 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 @@ -83,16 +83,20 @@ public class FileSystemMediumTest { tester.stop(); logs = new LogOutputRecorder(); } - - @Test - public void scanProjectWithoutProjectName() throws IOException { - builder = ImmutableMap.builder() + + private ImmutableMap.Builder createBuilder() { + return ImmutableMap.builder() .put("sonar.task", "scan") .put("sonar.verbose", "true") .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) .put("sonar.projectKey", "com.foo.project") .put("sonar.projectVersion", "1.0-SNAPSHOT") .put("sonar.projectDescription", "Description of Foo Project"); + } + + @Test + public void scanProjectWithoutProjectName() throws IOException { + builder = createBuilder(); File srcDir = new File(baseDir, "src"); srcDir.mkdir(); @@ -115,23 +119,18 @@ public class FileSystemMediumTest { InputDir dir = result.inputDir("src"); assertThat(file.type()).isEqualTo(InputFile.Type.MAIN); assertThat(file.relativePath()).isEqualTo("src/sample.xoo"); + assertThat(file.language()).isEqualTo("xoo"); assertThat(dir.relativePath()).isEqualTo("src"); - // file and dirs were not published - assertThat(file.publish()).isFalse(); - assertThat(result.getReportComponent(dir.key())).isNull(); - assertThat(result.getReportComponent(file.key())).isNull(); + // file and dirs were published, since language matched xoo + assertThat(file.publish()).isTrue(); + assertThat(result.getReportComponent(dir.key())).isNotNull(); + assertThat(result.getReportComponent(file.key())).isNotNull(); } @Test public void onlyGenerateMetadataIfNeeded() throws IOException { - builder = ImmutableMap.builder() - .put("sonar.task", "scan") - .put("sonar.verbose", "true") - .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) - .put("sonar.projectKey", "com.foo.project") - .put("sonar.projectVersion", "1.0-SNAPSHOT") - .put("sonar.projectDescription", "Description of Foo Project"); + builder = createBuilder(); File srcDir = new File(baseDir, "src"); srcDir.mkdir(); @@ -139,8 +138,8 @@ public class FileSystemMediumTest { File xooFile = new File(srcDir, "sample.xoo"); FileUtils.write(xooFile, "Sample xoo\ncontent"); - File unknownFile = new File(srcDir, "sample.unknown"); - FileUtils.write(unknownFile, "Sample xoo\ncontent"); + File javaFile = new File(srcDir, "sample.java"); + FileUtils.write(javaFile, "Sample xoo\ncontent"); tester.newTask() .properties(builder @@ -150,19 +149,13 @@ public class FileSystemMediumTest { assertThat(logs.getAllAsString()).contains("2 files indexed"); assertThat(logs.getAllAsString()).contains("'src/sample.xoo' generated metadata"); - assertThat(logs.getAllAsString()).doesNotContain("'src/sample.unknown' generated metadata"); + assertThat(logs.getAllAsString()).doesNotContain("'src/sample.java' generated metadata"); } @Test public void preloadFileMetadata() throws IOException { - builder = ImmutableMap.builder() - .put("sonar.task", "scan") - .put("sonar.verbose", "true") - .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) - .put("sonar.projectKey", "com.foo.project") - .put("sonar.projectVersion", "1.0-SNAPSHOT") - .put("sonar.preloadFileMetadata", "true") - .put("sonar.projectDescription", "Description of Foo Project"); + builder = createBuilder() + .put("sonar.preloadFileMetadata", "true"); File srcDir = new File(baseDir, "src"); srcDir.mkdir(); @@ -170,8 +163,8 @@ public class FileSystemMediumTest { File xooFile = new File(srcDir, "sample.xoo"); FileUtils.write(xooFile, "Sample xoo\ncontent"); - File unknownFile = new File(srcDir, "sample.unknown"); - FileUtils.write(unknownFile, "Sample xoo\ncontent"); + File javaFile = new File(srcDir, "sample.java"); + FileUtils.write(javaFile, "Sample xoo\ncontent"); tester.newTask() .properties(builder @@ -181,7 +174,68 @@ public class FileSystemMediumTest { assertThat(logs.getAllAsString()).contains("2 files indexed"); assertThat(logs.getAllAsString()).contains("'src/sample.xoo' generated metadata"); + assertThat(logs.getAllAsString()).contains("'src/sample.java' generated metadata"); + } + + @Test + public void dontPublishFilesWithoutDetectedLanguage() throws IOException { + builder = createBuilder(); + + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.xoo"); + FileUtils.write(xooFile, "Sample xoo\ncontent"); + + File javaFile = new File(srcDir, "sample.java"); + FileUtils.write(javaFile, "Sample xoo\ncontent"); + + TaskResult result = tester.newTask() + .properties(builder + .put("sonar.sources", "src") + .build()) + .start(); + + assertThat(logs.getAllAsString()).contains("2 files indexed"); + assertThat(logs.getAllAsString()).contains("'src/sample.xoo' generated metadata"); + assertThat(logs.getAllAsString()).doesNotContain("'src/sample.java' generated metadata"); + DefaultInputFile javaInputFile = (DefaultInputFile) result.inputFile("src/sample.java"); + assertThat(result.getReportComponent(javaInputFile.key())).isNull(); + } + + @Test + public void createIssueOnAnyFile() throws IOException { + LogOutputRecorder logs = new LogOutputRecorder(); + ScannerMediumTester tester2 = ScannerMediumTester.builder() + .registerPlugin("xoo", new XooPlugin()) + .addDefaultQProfile("xoo", "Sonar Way") + .addRules(new XooRulesDefinition()) + .setLogOutput(logs) + .addActiveRule("xoo", "OneIssuePerUnknownFile", null, "OneIssuePerUnknownFile", "MAJOR", null, "xoo") + .build(); + tester2.start(); + + builder = createBuilder(); + + File srcDir = new File(baseDir, "src"); + srcDir.mkdir(); + + File xooFile = new File(srcDir, "sample.unknown"); + FileUtils.write(xooFile, "Sample xoo\ncontent"); + + TaskResult result = tester2.newTask() + .properties(builder + .put("sonar.sources", "src") + .build()) + .start(); + + assertThat(logs.getAllAsString()).contains("1 file indexed"); + assertThat(logs.getAllAsString()).contains("'src/sample.unknown' indexed with language 'null'"); assertThat(logs.getAllAsString()).contains("'src/sample.unknown' generated metadata"); + DefaultInputFile javaInputFile = (DefaultInputFile) result.inputFile("src/sample.unknown"); + assertThat(result.getReportComponent(javaInputFile.key())).isNotNull(); + + tester2.stop(); } @Test @@ -194,13 +248,7 @@ public class FileSystemMediumTest { .build(); tester2.start(); - builder = ImmutableMap.builder() - .put("sonar.task", "scan") - .put("sonar.verbose", "true") - .put("sonar.projectBaseDir", baseDir.getAbsolutePath()) - .put("sonar.projectKey", "com.foo.project") - .put("sonar.projectVersion", "1.0-SNAPSHOT") - .put("sonar.projectDescription", "Description of Foo Project"); + builder = createBuilder(); File srcDir = new File(baseDir, "src"); srcDir.mkdir(); @@ -420,7 +468,6 @@ public class FileSystemMediumTest { TaskResult result = tester.newTask() .properties(builder .put("sonar.sources", "src") - .put("sonar.import_unknown_files", "true") .build()) .start(); -- 2.39.5