From aa31181bcf82570e8d3749e9f3a1fd6e267f8b45 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jerzy=20M=C3=BCller?= <sidus.gemini+gh@gmail.com>
Date: Mon, 9 Feb 2015 11:30:35 +0100
Subject: [PATCH] Updating report task to be on par with sbt plugin

In sbt-scoverage plugin, report task is much more detailed. This commit
updates gradle version of report task to be on par with it's sbt
counterpart.

Updated version of task brings 4 new configuration parameters:

 - coverageOutputCobertura
 - coverageOutputXML
 - coverageOutputHTML
 - coverageDebug

All could be used to enable/disable different outputs. All but last one
defaults to true. Readme is updated with this information.

Code in `ScoverageWriter.java` is re-written from sbt-scoverage and
converted to Java. It could be moved to scalac-scoverage-runtime to be
used by all plugins. It's not inlined in `SingleReportApp.java` because
it'll be used also in ScoverageAggregate task (in next PR).

If there is no test data in project report task now only issues a warning
and not crash (it's important for multi-project setups without test
code/code to test in some sub-projects).
---
 README.md                                     | 35 ++++++---
 .../org/scoverage/ScoverageExtension.groovy   |  6 ++
 .../org/scoverage/ScoverageReport.groovy      | 10 ++-
 .../groovy/org/scoverage/ScoverageWriter.java | 74 +++++++++++++++++++
 .../groovy/org/scoverage/SingleReportApp.java | 41 ++++++----
 5 files changed, 142 insertions(+), 24 deletions(-)
 create mode 100644 src/main/groovy/org/scoverage/ScoverageWriter.java

diff --git a/README.md b/README.md
index 2f438c8..bba8f53 100644
--- a/README.md
+++ b/README.md
@@ -6,6 +6,9 @@ A plugin to enable the use of Scoverage in a gradle Scala project.
 
 This has now been deployed to maven central.
 
+Using gradle-scoverage
+======================
+
 Getting started
 ---------------
 ```groovy
@@ -34,10 +37,31 @@ This creates an additional task testCoverage which will run tests against instru
 Then launch command :
 `gradle testScoverage` or `gradle checkScoverage`
 
+Available tasks
+---------------
+
+* testScoverage - Executes all tests and creates Scoverage XML report with information about code coverage
+* reportScoverage - Generates reports (see below).
+* aggregateScoverage - Aggregates reports from multiple sub-projects (see below).
+* checkScoverage - See below.
+* compileScoverageScala - Instruments code without running tests.
+
+ReportScoverage
+---------------
+
+You can configure output generated by `gradle reportScoverage` using flags:
+
+| Flag name               | Default value | Description                                     |
+| ------------------------|---------------|-------------------------------------------------|
+| coverageOutputCobertura | true          | Enables/disables cobertura.xml file generation. |
+| coverageOutputXML       | true          | Enables/disables scoverage XML output.          |
+| coverageOutputHTML      | true          | Enables/disables scoverage HTML output.         |
+| coverageDebug           | false         | Enables/disables scoverage debug output.        |
+
 Aggregating Reports
 -------------------
 
-There is now experimental support for aggregating coverage statistics across subprojects.
+There is now experimental support for aggregating coverage statistics across sub-projects.
 
 The project hosting the aggregation task **must** be configured as the sub-projects are;
 i.e. with the scoverage plugin applied and the scoverage dependencies configured.
@@ -48,15 +72,8 @@ task aggregateScoverage(type: org.scoverage.ScoverageAggregate)
 
 This will produce a report into _build_ / scoverage-aggregate
 
-Available tasks
----------
-* testScoverage - Executes all tests and creates Scoverage XML report with information about code coverage
-* reportScoverage - Generates HTML report.
-* checkScoverage - See below.
-* compileScoverageScala - Instruments code without running tests.
-
 CheckScoverage
----------
+--------------
 
 By default, when you launch `gradle checkScoverage` build fail if only 75% of project is covered by tests.
 
diff --git a/src/main/groovy/org/scoverage/ScoverageExtension.groovy b/src/main/groovy/org/scoverage/ScoverageExtension.groovy
index 240ee3c..4d4c943 100644
--- a/src/main/groovy/org/scoverage/ScoverageExtension.groovy
+++ b/src/main/groovy/org/scoverage/ScoverageExtension.groovy
@@ -48,6 +48,12 @@ class ScoverageExtension {
 
     FileCollection pluginClasspath
 
+    /** Options for enabling and disabling output */
+    boolean coverageOutputCobertura = true
+    boolean coverageOutputXML = true
+    boolean coverageOutputHTML = true
+    boolean coverageDebug = false
+
     ScoverageExtension(Project project) {
 
         project.plugins.apply(JavaPlugin.class);
diff --git a/src/main/groovy/org/scoverage/ScoverageReport.groovy b/src/main/groovy/org/scoverage/ScoverageReport.groovy
index 58061a1..ab1f1b7 100644
--- a/src/main/groovy/org/scoverage/ScoverageReport.groovy
+++ b/src/main/groovy/org/scoverage/ScoverageReport.groovy
@@ -10,7 +10,15 @@ class ScoverageReport extends JavaExec {
         extension.reportDir.mkdirs()
         setClasspath(extension.pluginClasspath)
         setMain('org.scoverage.SingleReportApp')
-        setArgs([extension.sources.absolutePath, extension.dataDir.absolutePath, extension.reportDir.absolutePath])
+        setArgs([
+            /* sourceDir = */ extension.sources.absolutePath,
+            /* dataDir = */ extension.dataDir.absolutePath,
+            /* reportDir = */ extension.reportDir.absolutePath,
+            extension.coverageOutputCobertura,
+            extension.coverageOutputXML,
+            extension.coverageOutputHTML,
+            extension.coverageDebug
+        ])
         super.exec()
     }
 }
diff --git a/src/main/groovy/org/scoverage/ScoverageWriter.java b/src/main/groovy/org/scoverage/ScoverageWriter.java
new file mode 100644
index 0000000..0d8ab2f
--- /dev/null
+++ b/src/main/groovy/org/scoverage/ScoverageWriter.java
@@ -0,0 +1,74 @@
+package org.scoverage;
+
+import scoverage.Constants;
+import scoverage.Coverage;
+import scoverage.report.CoberturaXmlWriter;
+import scoverage.report.ScoverageHtmlWriter;
+import scoverage.report.ScoverageXmlWriter;
+
+import java.io.File;
+
+/**
+ * Util for generating and saving coverage files.
+ * <p/>
+ * Copied from sbt-scoverage and converted to Java to avoid dependency to Scala.
+ */
+public class ScoverageWriter {
+
+    /**
+     * Generates all reports from given data.
+     *
+     * @param sourceDir               directory with project sources
+     * @param reportDir               directory for generate reports
+     * @param coverage                coverage data
+     * @param coverageOutputCobertura switch for Cobertura output
+     * @param coverageOutputXML       switch for Scoverage XML output
+     * @param coverageOutputHTML      switch for Scoverage HTML output
+     * @param coverageDebug           switch for Scoverage Debug output
+     */
+    public static void write(File sourceDir,
+                             File reportDir,
+                             Coverage coverage,
+                             Boolean coverageOutputCobertura,
+                             Boolean coverageOutputXML,
+                             Boolean coverageOutputHTML,
+                             Boolean coverageDebug) {
+
+        System.out.println("[scoverage] Generating scoverage reports...");
+
+        reportDir.mkdirs();
+
+        if (coverageOutputCobertura) {
+            new CoberturaXmlWriter(sourceDir, reportDir).write(coverage);
+            System.out.println("[scoverage] Written Cobertura XML report to " +
+                reportDir.getAbsolutePath() +
+                File.separator +
+                "cobertura.xml");
+        }
+
+        if (coverageOutputXML) {
+            new ScoverageXmlWriter(sourceDir, reportDir, /* debug = */ false).write(coverage);
+            System.out.println("[scoverage] Written XML report to " +
+                reportDir.getAbsolutePath() +
+                File.separator +
+                Constants.XMLReportFilename());
+            if (coverageDebug) {
+                new ScoverageXmlWriter(sourceDir, reportDir, /* debug = */ true).write(coverage);
+                System.out.println("[scoverage] Written XML report with debug information to " +
+                    reportDir.getAbsolutePath() +
+                    File.separator +
+                    Constants.XMLReportFilenameWithDebug());
+            }
+        }
+
+        if (coverageOutputHTML) {
+            new ScoverageHtmlWriter(sourceDir, reportDir).write(coverage);
+            System.out.println("[scoverage] Written HTML report to " +
+                reportDir.getAbsolutePath() +
+                File.separator +
+                "index.html");
+        }
+
+        System.out.println("[scoverage] Coverage reports completed");
+    }
+}
diff --git a/src/main/groovy/org/scoverage/SingleReportApp.java b/src/main/groovy/org/scoverage/SingleReportApp.java
index bf3a4c5..998cb83 100644
--- a/src/main/groovy/org/scoverage/SingleReportApp.java
+++ b/src/main/groovy/org/scoverage/SingleReportApp.java
@@ -5,9 +5,6 @@
 import scoverage.Coverage;
 import scoverage.IOUtils;
 import scoverage.Serializer;
-import scoverage.report.CoberturaXmlWriter;
-import scoverage.report.ScoverageHtmlWriter;
-import scoverage.report.ScoverageXmlWriter;
 
 import java.io.File;
 import java.util.Arrays;
@@ -21,20 +18,36 @@ public static void main(String... args) {
         File sourceDir = new File(args[0]);
         File dataDir = new File(args[1]);
         File reportDir = new File(args[2]);
-        reportDir.mkdirs();
+
+        Boolean coverageOutputCobertura = java.lang.Boolean.valueOf(args[3]);
+        Boolean coverageOutputXML = java.lang.Boolean.valueOf(args[4]);
+        Boolean coverageOutputHTML = java.lang.Boolean.valueOf(args[5]);
+        Boolean coverageDebug = java.lang.Boolean.valueOf(args[6]);
 
         File coverageFile = Serializer.coverageFile(dataDir);
-        File[] array = IOUtils.findMeasurementFiles(dataDir);
-        // TODO: patch scoverage core to use a consistent collection type?
-        Seq<File> measurementFiles = scala.collection.JavaConversions.asScalaBuffer(Arrays.asList(array));
 
-        Coverage coverage = Serializer.deserialize(coverageFile);
+        if (!coverageFile.exists()) {
+            System.out.println("[scoverage] Could not find coverage file, skipping...");
+        } else {
+            File[] array = IOUtils.findMeasurementFiles(dataDir);
+            // TODO: patch scoverage core to use a consistent collection type?
+            Seq<File> measurementFiles = scala.collection.JavaConversions.asScalaBuffer(Arrays.asList(array));
+
+            Coverage coverage = Serializer.deserialize(coverageFile);
+
+            Set<Object> measurements = IOUtils.invoked(measurementFiles);
+            coverage.apply(measurements);
+
+            ScoverageWriter.write(
+                sourceDir,
+                reportDir,
+                coverage,
+                coverageOutputCobertura,
+                coverageOutputXML,
+                coverageOutputHTML,
+                coverageDebug);
+        }
+    }
 
-        Set<Object> measurements = IOUtils.invoked(measurementFiles);
-        coverage.apply(measurements);
 
-        new ScoverageXmlWriter(sourceDir, reportDir, false).write(coverage);
-        new ScoverageHtmlWriter(sourceDir, reportDir).write(coverage);
-        new CoberturaXmlWriter(sourceDir, reportDir).write(coverage);
-    }
 }
\ No newline at end of file