]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-3895 export violations
authorDavid Gageot <david@gageot.net>
Wed, 31 Oct 2012 09:24:56 +0000 (10:24 +0100)
committerDavid Gageot <david@gageot.net>
Wed, 31 Oct 2012 09:41:25 +0000 (10:41 +0100)
sonar-batch/src/main/java/org/sonar/batch/bootstrap/DryRun.java
sonar-batch/src/main/java/org/sonar/batch/local/DryRunExporter.java
sonar-batch/src/test/java/org/sonar/batch/bootstrap/DryRunTest.java
sonar-batch/src/test/java/org/sonar/batch/local/DryRunExporterTest.java

index d0f6c97f9412913915edd11a49c526c3dbc2e2c6..ebebfee9b69d3b4df94c8d0806aad95c8fe65826 100644 (file)
@@ -21,24 +21,32 @@ package org.sonar.batch.bootstrap;
 
 import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchComponent;
+import org.sonar.api.Properties;
 import org.sonar.api.Property;
 import org.sonar.api.PropertyType;
 import org.sonar.api.config.Settings;
 
-@Property(key = "sonar.dryRun", defaultValue = "false", name = "Dry Run", type = PropertyType.BOOLEAN)
+@Properties({
+  @Property(key = "sonar.dryRun", defaultValue = "false", name = "Dry Run", type = PropertyType.BOOLEAN),
+  @Property(key = "sonar.dryRun.export.path", defaultValue = "dryRun.json", name = "Dry Run Results Export File", type = PropertyType.STRING)
+})
 public class DryRun implements BatchComponent {
-  private boolean enabled;
+  private final Settings settings;
 
   public DryRun(Settings settings) {
-    enabled = settings.getBoolean("sonar.dryRun");
+    this.settings = settings;
   }
 
   public boolean isEnabled() {
-    return enabled;
+    return settings.getBoolean("sonar.dryRun");
+  }
+
+  public String getExportPath() {
+    return settings.getString("sonar.dryRun.export.path");
   }
 
   public void start() {
-    if (enabled) {
+    if (isEnabled()) {
       LoggerFactory.getLogger(DryRun.class).info("Dry run");
     }
   }
index a079a4feb7c75ffb3011519013eb76bda2156de1..d146d21379e4f23541322a2f2a1f3a7459e25cb1 100644 (file)
 package org.sonar.batch.local;
 
 import com.google.common.annotations.VisibleForTesting;
-import com.google.common.base.Function;
+import com.google.common.base.Charsets;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
 import com.google.common.io.Closeables;
+import com.google.common.io.Files;
 import com.google.gson.Gson;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonObject;
 import com.google.gson.stream.JsonWriter;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.sonar.api.BatchComponent;
 import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.ProjectFileSystem;
 import org.sonar.api.resources.Resource;
 import org.sonar.api.rules.Violation;
 import org.sonar.api.utils.SonarException;
 import org.sonar.batch.bootstrap.DryRun;
 import org.sonar.batch.index.DefaultIndex;
 
-import javax.annotation.Nullable;
-
+import java.io.File;
 import java.io.IOException;
 import java.io.StringWriter;
 import java.util.Collection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * @since 3.4
@@ -51,10 +53,12 @@ public class DryRunExporter implements BatchComponent {
 
   private final DryRun dryRun;
   private final DefaultIndex sonarIndex;
+  private final ProjectFileSystem projectFileSystem;
 
-  public DryRunExporter(DryRun dryRun, DefaultIndex sonarIndex) {
+  public DryRunExporter(DryRun dryRun, DefaultIndex sonarIndex, ProjectFileSystem projectFileSystem) {
     this.dryRun = dryRun;
     this.sonarIndex = sonarIndex;
+    this.projectFileSystem = projectFileSystem;
   }
 
   public void execute(SensorContext context) {
@@ -62,10 +66,19 @@ public class DryRunExporter implements BatchComponent {
       return;
     }
 
-    LOG.info("Exporting DryRun results");
-
     String json = getResultsAsJson(sonarIndex.getResources());
-    System.out.println(json);
+    exportResults(json);
+  }
+
+  private void exportResults(String json) {
+    File exportFile = new File(projectFileSystem.getSonarWorkingDirectory(), dryRun.getExportPath());
+
+    LOG.info("Exporting DryRun results to " + exportFile.getAbsolutePath());
+    try {
+      Files.write(json, exportFile, Charsets.UTF_8);
+    } catch (IOException e) {
+      throw new SonarException("Unable to write DryRun results in file " + exportFile.getAbsolutePath());
+    }
   }
 
   @VisibleForTesting
@@ -80,9 +93,21 @@ public class DryRunExporter implements BatchComponent {
       writer.beginArray();
 
       for (Resource resource : resources) {
+        List<Map<String, Object>> resourceViolations = Lists.newArrayList();
         for (Violation violation : getViolations(resource)) {
-          gson.toJson(new ViolationToMap().apply(violation), writer);
+          resourceViolations.add(ImmutableMap.<String, Object> of(
+              "line", violation.getLineId(),
+              "message", violation.getMessage(),
+              "severity", violation.getSeverity().name(),
+              "rule_key", violation.getRule().getKey(),
+              "rule_name", violation.getRule().getName()));
         }
+
+        Map<String, Object> obj = ImmutableMap.of(
+            "resource", resource.getKey(),
+            "violations", resourceViolations);
+
+        gson.toJson(obj, Map.class, writer);
       }
 
       writer.endArray();
@@ -99,16 +124,4 @@ public class DryRunExporter implements BatchComponent {
   List<Violation> getViolations(Resource resource) {
     return sonarIndex.getViolations(resource);
   }
-
-  static class ViolationToMap implements Function<Violation, JsonElement> {
-    public JsonElement apply(@Nullable Violation violation) {
-      JsonObject json = new JsonObject();
-      if (violation != null) {
-        json.addProperty("resource", violation.getResource().getKey());
-        json.addProperty("line", violation.getLineId());
-        json.addProperty("message", violation.getMessage());
-      }
-      return json;
-    }
-  }
 }
index f0b514fff0f80b4bc18308b34c5af8d6bf3b40f2..b671debbd1a7aa5fd52ca6263270921cf9bfed36 100644 (file)
  */
 package org.sonar.batch.bootstrap;
 
+import org.junit.Before;
 import org.junit.Test;
+import org.sonar.api.config.PropertyDefinitions;
 import org.sonar.api.config.Settings;
 
 import static org.fest.assertions.Assertions.assertThat;
 
 public class DryRunTest {
-  Settings settings = new Settings();
+  DryRun dryRun;
+  Settings settings;
+
+  @Before
+  public void setUp() {
+    settings = new Settings(new PropertyDefinitions(DryRun.class));
+
+    dryRun = new DryRun(settings);
+  }
 
   @Test
   public void should_be_disabled() {
-    DryRun dryRun = new DryRun(settings);
     dryRun.start();
 
     assertThat(dryRun.isEnabled()).isFalse();
@@ -39,9 +48,24 @@ public class DryRunTest {
   public void should_enable() {
     settings.setProperty("sonar.dryRun", "true");
 
-    DryRun dryRun = new DryRun(settings);
     dryRun.start();
 
     assertThat(dryRun.isEnabled()).isTrue();
   }
+
+  @Test
+  public void should_get_default_export_path() {
+    String exportPath = dryRun.getExportPath();
+
+    assertThat(exportPath).isEqualTo("dryRun.json");
+  }
+
+  @Test
+  public void should_get_custom_export_path() {
+    settings.setProperty("sonar.dryRun.export.path", "export.json");
+
+    String exportPath = dryRun.getExportPath();
+
+    assertThat(exportPath).isEqualTo("export.json");
+  }
 }
index 3e7ab3af29dca5646bb4789dfe3c693613040f38..e6dfca20b3752daf80c79fc116e05e08ec955940 100644 (file)
@@ -23,7 +23,10 @@ import com.google.common.collect.ImmutableSet;
 import org.junit.Before;
 import org.junit.Test;
 import org.sonar.api.batch.SensorContext;
+import org.sonar.api.resources.ProjectFileSystem;
 import org.sonar.api.resources.Resource;
+import org.sonar.api.rules.Rule;
+import org.sonar.api.rules.RulePriority;
 import org.sonar.api.rules.Violation;
 import org.sonar.batch.bootstrap.DryRun;
 import org.sonar.batch.index.DefaultIndex;
@@ -44,12 +47,13 @@ public class DryRunExporterTest {
   DryRun dryRun = mock(DryRun.class);
   DefaultIndex sonarIndex = mock(DefaultIndex.class);
   SensorContext sensorContext = mock(SensorContext.class);
-  Resource resource =  JavaClass.create("KEY");
+  Resource resource = JavaClass.create("KEY");
   Violation violation = mock(Violation.class);
+  ProjectFileSystem projectFileSystem = mock(ProjectFileSystem.class);
 
   @Before
   public void setUp() {
-    dryRunExporter = spy(new DryRunExporter(dryRun, sonarIndex));
+    dryRunExporter = spy(new DryRunExporter(dryRun, sonarIndex, projectFileSystem));
   }
 
   @Test
@@ -65,10 +69,13 @@ public class DryRunExporterTest {
     when(violation.getResource()).thenReturn(resource);
     when(violation.getLineId()).thenReturn(1);
     when(violation.getMessage()).thenReturn("VIOLATION");
+    when(violation.getRule()).thenReturn(Rule.create("pmd", "RULE_KEY").setName("RULE_NAME"));
+    when(violation.getSeverity()).thenReturn(RulePriority.INFO);
     doReturn(Arrays.asList(violation)).when(dryRunExporter).getViolations(resource);
 
     String json = dryRunExporter.getResultsAsJson(ImmutableSet.of(resource));
 
-    assertThat(json).isEqualTo("[{\"resource\":\"KEY\",\"line\":1,\"message\":\"VIOLATION\"}]");
+    assertThat(json).isEqualTo(
+        "[{\"resource\":\"KEY\",\"violations\":[{\"line\":1,\"message\":\"VIOLATION\",\"severity\":\"INFO\",\"rule_key\":\"RULE_KEY\",\"rule_name\":\"RULE_NAME\"}]}]");
   }
 }