]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11509 Ignore module and folder level measures in Sensor API
authorJulien HENRY <julien.henry@sonarsource.com>
Wed, 28 Nov 2018 11:10:44 +0000 (12:10 +0100)
committersonartech <sonartech@sonarsource.com>
Wed, 16 Jan 2019 08:43:03 +0000 (09:43 +0100)
plugins/sonar-xoo-plugin/src/main/java/org/sonar/xoo/lang/MeasureSensor.java
plugins/sonar-xoo-plugin/src/test/java/org/sonar/xoo/lang/MeasureSensorTest.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/AbstractProjectOrModule.java
sonar-plugin-api/src/main/java/org/sonar/api/batch/fs/internal/DefaultInputModule.java
sonar-scanner-engine/src/main/java/org/sonar/scanner/sensor/DefaultSensorStorage.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/mediumtest/measures/MeasuresMediumTest.java
sonar-scanner-engine/src/test/java/org/sonar/scanner/sensor/DefaultSensorStorageTest.java

index 18d801397c47ab4bbb305fd5a428e63177b8e291..0a839a7692d384450643857e00b0d63e5a160c8c 100644 (file)
@@ -26,6 +26,7 @@ import java.util.List;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.lang.StringUtils;
 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.measure.MetricFinder;
 import org.sonar.api.batch.sensor.Sensor;
@@ -119,6 +120,11 @@ public class MeasureSensor implements Sensor {
       File ioFile = file.file();
       File measureFile = new File(ioFile.getParentFile(), ioFile.getName() + MEASURES_EXTENSION);
       processFileMeasures(file, measureFile, context);
+
+      InputDir inputDir = context.fileSystem().inputDir(ioFile.getParentFile());
+      if (inputDir != null) {
+        processFileMeasures(inputDir, new File(ioFile.getParentFile(), "folder" + MEASURES_EXTENSION), context);
+      }
     }
     processFileMeasures(context.module(), new File(context.fileSystem().baseDir(), "module" + MEASURES_EXTENSION), context);
   }
index 4415a058c2350d06687d3628d2f1e77f5776d06e..7ed38d42e0ec80005726c7e24c7ed98cdb3110f9 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.xoo.lang;
 
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import org.apache.commons.io.FileUtils;
 import org.junit.Before;
 import org.junit.Rule;
@@ -76,7 +77,7 @@ public class MeasureSensorTest {
   @Test
   public void testExecution() throws IOException {
     File measures = new File(baseDir, "src/foo.xoo.measures");
-    FileUtils.write(measures, "ncloc:12\nbranch_coverage:5.3\nsqale_index:300\nbool:true\n\n#comment");
+    FileUtils.write(measures, "ncloc:12\nbranch_coverage:5.3\nsqale_index:300\nbool:true\n\n#comment", StandardCharsets.UTF_8);
     InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
     context.fileSystem().add(inputFile);
 
@@ -96,6 +97,26 @@ public class MeasureSensorTest {
     assertThat(context.measure("foo:src/foo.xoo", booleanMetric).value()).isTrue();
   }
 
+  @Test
+  public void testExecutionForFoldersMeasures_no_measures() throws IOException {
+    File measures = new File(baseDir, "src/folder.measures");
+    FileUtils.write(measures, "ncloc:12\nbranch_coverage:5.3\nsqale_index:300\nbool:true\n\n#comment", StandardCharsets.UTF_8);
+    InputFile inputFile = new TestInputFileBuilder("foo", "src/foo.xoo").setLanguage("xoo").setModuleBaseDir(baseDir.toPath()).build();
+    context.fileSystem().add(inputFile);
+
+    Metric<Boolean> booleanMetric = new Metric.Builder("bool", "Bool", Metric.ValueType.BOOL)
+      .create();
+
+    when(metricFinder.<Integer>findByKey("ncloc")).thenReturn(CoreMetrics.NCLOC);
+    when(metricFinder.<Double>findByKey("branch_coverage")).thenReturn(CoreMetrics.BRANCH_COVERAGE);
+    when(metricFinder.<Long>findByKey("sqale_index")).thenReturn(CoreMetrics.TECHNICAL_DEBT);
+    when(metricFinder.<Boolean>findByKey("bool")).thenReturn(booleanMetric);
+
+    sensor.execute(context);
+
+    assertThat(context.measure("foo:src", CoreMetrics.NCLOC)).isNull();
+  }
+
   @Test
   public void failIfMetricNotFound() throws IOException {
     File measures = new File(baseDir, "src/foo.xoo.measures");
index 86acd4cb64bb980fd8132bc8527741387e5ae1f4..db4deac109a6d1189425f09d184c84cd9f0be9ae 100644 (file)
@@ -32,14 +32,10 @@ import javax.annotation.concurrent.Immutable;
 import org.apache.commons.lang.StringUtils;
 import org.sonar.api.CoreProperties;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
 
 @Immutable
 public abstract class AbstractProjectOrModule extends DefaultInputComponent {
 
-  private static final Logger LOG = Loggers.get(AbstractProjectOrModule.class);
-
   private final Path baseDir;
   private final Path workDir;
   private final String name;
index 3fe625798c4490ac4e31d7daf133d41c5b36da8b..06213be6abb52acfc66141d6e4fc2ebba6f889f7 100644 (file)
@@ -27,15 +27,12 @@ import javax.annotation.concurrent.Immutable;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.InputModule;
 import org.sonar.api.scan.filesystem.PathResolver;
-import org.sonar.api.utils.log.Logger;
-import org.sonar.api.utils.log.Loggers;
 
 import static org.sonar.api.config.internal.MultivalueProperty.parseAsCsv;
 
 @Immutable
 public class DefaultInputModule extends AbstractProjectOrModule implements InputModule {
 
-  private static final Logger LOG = Loggers.get(DefaultInputModule.class);
   private final List<Path> sourceDirsOrFiles;
   private final List<Path> testDirsOrFiles;
 
index e4f447fffd8264f2d25c2fc3331ba3bb23f82715..bda3121b6ca216b7340ff1cb461690630fdf0173 100644 (file)
@@ -31,9 +31,11 @@ import java.util.stream.Collectors;
 import java.util.stream.Stream;
 import javax.annotation.Nullable;
 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.TextRange;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.measure.Metric;
 import org.sonar.api.batch.measure.MetricFinder;
 import org.sonar.api.batch.sensor.code.internal.DefaultSignificantCode;
@@ -231,10 +233,6 @@ public class DefaultSensorStorage implements SensorStorage {
 
   @Override
   public void store(Measure newMeasure) {
-    if (newMeasure.inputComponent() instanceof DefaultInputFile) {
-      DefaultInputFile defaultInputFile = (DefaultInputFile) newMeasure.inputComponent();
-      defaultInputFile.setPublished(true);
-    }
     saveMeasure(newMeasure.inputComponent(), (DefaultMeasure<?>) newMeasure);
   }
 
@@ -250,6 +248,11 @@ public class DefaultSensorStorage implements SensorStorage {
       defaultInputFile.setPublished(true);
     }
 
+    if (component instanceof InputDir || (component instanceof DefaultInputModule && ((DefaultInputModule) component).definition().getParent() != null)) {
+      logOnce(measure.metric().key(), "Storing measures on folders or modules is deprecated. Provided value of metric '{}' is ignored.", measure.metric().key());
+      return;
+    }
+
     if (DEPRECATED_METRICS_KEYS.contains(measure.metric().key())) {
       logOnce(measure.metric().key(), "Metric '{}' is deprecated. Provided value is ignored.", measure.metric().key());
       return;
@@ -261,7 +264,7 @@ public class DefaultSensorStorage implements SensorStorage {
     }
 
     if (!measure.isFromCore() && NEWLY_CORE_METRICS_KEYS.contains(measure.metric().key())) {
-      logOnce(measure.metric().key(), "Metric '{}' is an internal metric computed by SonarQube. Provided value is ignored.", measure.metric().key());
+      logOnce(measure.metric().key(), "Metric '{}' is an internal metric computed by SonarQube/SonarCloud. Provided value is ignored.", measure.metric().key());
       return;
     }
 
index 657abfc75347b4b8f95b81f251acfb32a20877c8..395dff17b10663b0b09331cb9348d4ee92a80c62 100644 (file)
@@ -22,6 +22,7 @@ package org.sonar.scanner.mediumtest.measures;
 import com.google.common.collect.ImmutableMap;
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.StandardCharsets;
 import java.util.List;
 import java.util.Map;
 import org.apache.commons.io.FileUtils;
@@ -66,19 +67,15 @@ public class MeasuresMediumTest {
   @Test
   public void applyExclusionsOnCoverageMeasures() throws IOException {
     File xooFile = new File(srcDir, "sample.xoo");
-    FileUtils.write(xooFile, "Sample xoo\n\ncontent");
+    FileUtils.write(xooFile, "Sample xoo\n\ncontent", StandardCharsets.UTF_8);
 
     File measures = new File(srcDir, "sample.xoo.measures");
-    FileUtils.write(measures, "lines_to_cover:2");
+    FileUtils.write(measures, "lines_to_cover:2", StandardCharsets.UTF_8);
 
     AnalysisResult result = tester.newAnalysis()
       .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")
         .build())
       .execute();
@@ -90,12 +87,8 @@ public class MeasuresMediumTest {
 
     result = tester.newAnalysis()
       .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.coverage.exclusions", "src/sample.xoo")
         .build())
@@ -109,19 +102,15 @@ public class MeasuresMediumTest {
   @Test
   public void deprecatedCoverageMeasuresAreConverted() throws IOException {
     File xooFile = new File(srcDir, "sample.xoo");
-    FileUtils.write(xooFile, "Sample xoo\n\ncontent");
+    FileUtils.write(xooFile, "Sample xoo\n\ncontent", StandardCharsets.UTF_8);
 
     File measures = new File(srcDir, "sample.xoo.measures");
-    FileUtils.write(measures, "it_lines_to_cover:2");
+    FileUtils.write(measures, "it_lines_to_cover:2", StandardCharsets.UTF_8);
 
     AnalysisResult result = tester.newAnalysis()
       .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")
         .build())
       .execute();
@@ -138,20 +127,16 @@ public class MeasuresMediumTest {
   @Test
   public void failIfTryingToSaveServerSideMeasure() throws IOException {
     File xooFile = new File(srcDir, "sample.xoo");
-    FileUtils.write(xooFile, "Sample xoo\n\ncontent");
+    FileUtils.write(xooFile, "Sample xoo\n\ncontent", StandardCharsets.UTF_8);
 
     File measures = new File(srcDir, "sample.xoo.measures");
-    FileUtils.write(measures, "new_lines:2");
+    FileUtils.write(measures, "new_lines:2", StandardCharsets.UTF_8);
 
     try {
       tester.newAnalysis()
         .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")
           .build())
         .execute();
@@ -166,19 +151,15 @@ public class MeasuresMediumTest {
   @Test
   public void lineMeasures() throws IOException {
     File xooFile = new File(srcDir, "sample.xoo");
-    FileUtils.write(xooFile, "Sample xoo\n\n\ncontent");
+    FileUtils.write(xooFile, "Sample xoo\n\n\ncontent", StandardCharsets.UTF_8);
 
     File lineMeasures = new File(srcDir, "sample.xoo.linemeasures");
-    FileUtils.write(lineMeasures, "ncloc_data:1=1;2=0;4=1");
+    FileUtils.write(lineMeasures, "ncloc_data:1=1;2=0;4=1", StandardCharsets.UTF_8);
 
     AnalysisResult result = tester.newAnalysis()
       .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")
         .build())
       .execute();
@@ -192,19 +173,15 @@ public class MeasuresMediumTest {
   @Test
   public void projectLevelMeasures() throws IOException {
     File xooFile = new File(srcDir, "sample.xoo");
-    FileUtils.write(xooFile, "Sample xoo\n\n\ncontent");
+    FileUtils.write(xooFile, "Sample xoo\n\n\ncontent", StandardCharsets.UTF_8);
 
     File projectMeasures = new File(baseDir, "module.measures");
-    FileUtils.write(projectMeasures, "tests:10");
+    FileUtils.write(projectMeasures, "tests:10", StandardCharsets.UTF_8);
 
     AnalysisResult result = tester.newAnalysis()
       .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")
         .build())
       .execute();
@@ -216,4 +193,50 @@ public class MeasuresMediumTest {
       .containsExactly(tuple("tests", 10, ""));
   }
 
+  @Test
+  public void warnWhenSavingFolderMeasure() throws IOException {
+    File xooFile = new File(srcDir, "sample.xoo");
+    FileUtils.write(xooFile, "Sample xoo\n\n\ncontent", StandardCharsets.UTF_8);
+
+    File folderMeasures = new File(srcDir, "folder.measures");
+    FileUtils.write(folderMeasures, "tests:10", StandardCharsets.UTF_8);
+
+    AnalysisResult result = tester.newAnalysis()
+      .properties(ImmutableMap.<String, String>builder()
+        .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+        .put("sonar.projectKey", "com.foo.project")
+        .put("sonar.sources", "src")
+        .build())
+      .execute();
+
+
+    assertThat(logTester.logs(LoggerLevel.WARN)).contains("Storing measures on folders or modules is deprecated. Provided value of metric 'tests' is ignored.");
+  }
+
+  @Test
+  public void warnWhenSavingModuleMeasure() throws IOException {
+    File moduleDir = new File(baseDir, "moduleA");
+    moduleDir.mkdirs();
+
+    srcDir = new File(moduleDir, "src");
+
+    File xooFile = new File(srcDir, "sample.xoo");
+    FileUtils.write(xooFile, "Sample xoo\n\n\ncontent", StandardCharsets.UTF_8);
+
+    File moduleMeasures = new File(moduleDir, "module.measures");
+    FileUtils.write(moduleMeasures, "tests:10", StandardCharsets.UTF_8);
+
+    AnalysisResult result = tester.newAnalysis()
+      .properties(ImmutableMap.<String, String>builder()
+        .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+        .put("sonar.projectKey", "com.foo.project")
+        .put("sonar.modules", "moduleA")
+        .put("sonar.sources", "src")
+        .build())
+      .execute();
+
+
+    assertThat(logTester.logs(LoggerLevel.WARN)).contains("Storing measures on folders or modules is deprecated. Provided value of metric 'tests' is ignored.");
+  }
+
 }
index 16a2911245a819838f749e065eb8c9382b8cf3d3..9da8aaa35354f48dd4564658147a31891b3bf4c0 100644 (file)
@@ -30,6 +30,7 @@ import org.junit.rules.TemporaryFolder;
 import org.mockito.ArgumentCaptor;
 import org.sonar.api.batch.bootstrap.ProjectDefinition;
 import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputDir;
 import org.sonar.api.batch.fs.internal.DefaultInputFile;
 import org.sonar.api.batch.fs.internal.DefaultInputModule;
 import org.sonar.api.batch.fs.internal.DefaultInputProject;
@@ -63,6 +64,7 @@ import static org.assertj.core.data.MapEntry.entry;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
 import static org.mockito.Mockito.verifyZeroInteractions;
 import static org.mockito.Mockito.when;
 
@@ -123,6 +125,29 @@ public class DefaultSensorStorageTest {
       .withValue(10));
   }
 
+  @Test
+  public void shouldIgnoreMeasuresOnFolders() {
+    underTest.store(new DefaultMeasure()
+      .on(new DefaultInputDir("foo", "bar"))
+      .forMetric(CoreMetrics.LINES)
+      .withValue(10));
+
+    verifyNoMoreInteractions(measureCache);
+  }
+
+  @Test
+  public void shouldIgnoreMeasuresOnModules() throws IOException {
+    ProjectDefinition module = ProjectDefinition.create().setBaseDir(temp.newFolder()).setWorkDir(temp.newFolder());
+    ProjectDefinition root = ProjectDefinition.create().addSubProject(module);
+
+    underTest.store(new DefaultMeasure()
+      .on(new DefaultInputModule(module))
+      .forMetric(CoreMetrics.LINES)
+      .withValue(10));
+
+    verifyNoMoreInteractions(measureCache);
+  }
+
   @Test
   public void should_save_issue() {
     InputFile file = new TestInputFileBuilder("foo", "src/Foo.php").build();