diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index fe98c74a6..0d52de2f1 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -119,6 +119,15 @@ By default the build will use the native image server. This speeds up the build,
not being invalidated correctly in some cases. To run a build with a new instance of the server you can use
`./mvnw install -Dnative-image.new-server=true`.
+### Test Coverage
+
+Quarkus uses Jacoco to generate test coverage. If you would like to generate the report run `mvn install -Ptest-coverage`,
+then change into the `coverage-report` directory and run `mvn package`. The code coverage report will be generated in
+`target/site/jacoco/`.
+
+This currently does not work on Windows as it uses a shell script to copy all the classes and files into the code coverage
+module.
+
## The small print
This project is an open source project, please act responsibly, be nice, polite and enjoy!
diff --git a/build-parent/pom.xml b/build-parent/pom.xml
index f6e2f588c..714dbc72b 100644
--- a/build-parent/pom.xml
+++ b/build-parent/pom.xml
@@ -81,6 +81,10 @@
quay.io/keycloak/keycloak:8.0.1
4.0.13
+
+
+
+ 0.8.5
@@ -166,6 +170,7 @@
org.jboss.logmanager.LogManager
+ ${jacoco.agent.argLine}
@@ -636,5 +641,35 @@
+
+
+ test-coverage
+
+ ${jacoco.activated.agent.argLine}
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ agent
+
+ prepare-agent
+
+
+
+ io.quarkus*
+
+ jacoco.activated.agent.argLine
+
+
+
+
+
+
+
diff --git a/coverage-report/.gitignore b/coverage-report/.gitignore
new file mode 100644
index 000000000..b929015f9
--- /dev/null
+++ b/coverage-report/.gitignore
@@ -0,0 +1 @@
+src/main/java
diff --git a/coverage-report/pom.xml b/coverage-report/pom.xml
new file mode 100644
index 000000000..074a7b808
--- /dev/null
+++ b/coverage-report/pom.xml
@@ -0,0 +1,94 @@
+
+ 4.0.0
+
+ quarkus-build-parent
+ io.quarkus
+ 999-SNAPSHOT
+ ../build-parent/pom.xml
+
+ quarkus-coverage-report
+ Quarkus Test Coverage Report
+ Aggregates and compiles jacoco test coverage report.
+ This does not currently work on Windows.
+
+ pom
+
+
+ true
+
+
+
+
+
+
+ org.codehaus.mojo
+ exec-maven-plugin
+ 1.6.0
+
+
+ copy-classes-and-source
+ test-compile
+
+ exec
+
+
+
+
+ prepare.sh
+ ${project.basedir}
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ merge-reports
+ test-compile
+
+ merge
+
+
+
+
+ ${project.basedir}/../
+
+ **/target/jacoco.exec
+
+
+
+
+
+
+ compile-report
+ test
+
+ report
+
+
+
+
+
+ org.jacoco
+ jacoco-maven-plugin
+ ${jacoco.version}
+
+
+ report
+ prepare-package
+
+ report
+
+
+ Quarkus
+
+
+
+
+
+
+
+
+
diff --git a/coverage-report/prepare.sh b/coverage-report/prepare.sh
new file mode 100755
index 000000000..c3f211394
--- /dev/null
+++ b/coverage-report/prepare.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+rm -r target/classes src/main/java
+mkdir -p target/classes
+mkdir -p src/main/java
+
+for j in '../extensions' '../core' '../devtools' '../independent-projects/'
+do
+ for i in `find $j -regex .*target/classes `
+ do
+ cp -r $i/* target/classes/
+ done
+ for i in `find $j -regex .*src/main/java `
+ do
+ cp -r $i/* src/main/java/
+ done
+done
+#needed to make sure the script always suceeds
+echo "complete"
diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/options/BootstrapMavenOptions.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/options/BootstrapMavenOptions.java
index 49dca5dad..3cb6060f7 100644
--- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/options/BootstrapMavenOptions.java
+++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/resolver/maven/options/BootstrapMavenOptions.java
@@ -93,7 +93,13 @@ public class BootstrapMavenOptions {
public String[] getOptionValues(String name) {
final Object o = options.get(name);
- return o == null ? null : o instanceof String ? new String[] { o.toString() } : (String[]) o;
+ if (o == null) {
+ return null;
+ }
+ if (o instanceof String[]) {
+ return (String[]) o;
+ }
+ return new String[] { o.toString() };
}
public boolean isEmpty() {