Skip to content

Commit c842cc8

Browse files
committed
First commit. Should be functional.
0 parents  commit c842cc8

File tree

9 files changed

+960
-0
lines changed

9 files changed

+960
-0
lines changed

LICENSE.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2024 Guillaume Mary
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
JaCoCo Java Code Coverage Library reviewed for Maven multi-module aggregation
2+
=============================================================================
3+
4+
# Why
5+
As discussed [here](https://github.com/jacoco/jacoco/issues/974), creating an aggregation of Jacoco reports can be painful when dealing with a multi-modules Maven project, since it requires to create a module dedicated to it and add reported modules as a dependency of it. Although [a proposition](https://github.com/jacoco/jacoco/pull/1251) was made, it is not in Jacoco Team roadmap. So this project is made to fix it.
6+
7+
# How to use
8+
Replace your jacoco-maven-plugin report-aggregate execution...
9+
```xml
10+
<executions>
11+
<execution>
12+
<id>report-aggregate</id>
13+
<goals>
14+
<goal>report-aggregate</goal>
15+
</goals>
16+
<phase>verify</phase>
17+
</execution>
18+
</executions>
19+
```
20+
... by the one of this project
21+
```xml
22+
<plugin>
23+
<groupId>org.codefilarete</groupId>
24+
<artifactId>jacoco-aggregate-submodule</artifactId>
25+
<version>${}</version>
26+
<executions>
27+
<execution>
28+
<id>report-aggregate</id>
29+
<goals>
30+
<goal>report-aggregate</goal>
31+
</goals>
32+
<phase>verify</phase>
33+
</execution>
34+
</executions>
35+
</plugin>
36+
```
37+
38+
This module doesn't handle all features made by Jacoco plugin : it handles only aggregation for submodules so you have to keep all other goals you have in your pom.xml which may finally look like :
39+
```xml
40+
<plugin>
41+
<groupId>org.jacoco</groupId>
42+
<artifactId>jacoco-maven-plugin</artifactId>
43+
<version>${jacoco.version}</version>
44+
<executions>
45+
<execution>
46+
<id>prepare-agent</id>
47+
<goals>
48+
<goal>prepare-agent</goal>
49+
</goals>
50+
</execution>
51+
<execution>
52+
<id>report</id>
53+
<goals>
54+
<goal>report</goal>
55+
</goals>
56+
</execution>
57+
<!-- the following is replaced by Codefilarete plugin below -->
58+
<!--<execution>-->
59+
<!--<id>report-aggregate</id>-->
60+
<!--<goals>-->
61+
<!--<goal>report-aggregate</goal>-->
62+
<!--</goals>-->
63+
<!--<phase>verify</phase>-->
64+
<!--</execution>-->
65+
</executions>
66+
</plugin>
67+
<plugin>
68+
<groupId>org.codefilarete</groupId>
69+
<artifactId>jacoco-aggregate-submodule</artifactId>
70+
<version>${codefilarete.jacoco.version}</version>
71+
<executions>
72+
<execution>
73+
<id>report-aggregate</id>
74+
<goals>
75+
<goal>report-aggregate</goal>
76+
</goals>
77+
<phase>verify</phase>
78+
</execution>
79+
</executions>
80+
</plugin>
81+
```
82+
83+
# Disclaimer
84+
- I didn't find out how final aggregated report was saved, I've just kept original Mojo philosophy and ... it works ! see [ReportAggregateMojo.java](src/main/java/org/codefilarete/maven/jacoco/ReportAggregateMojo.java)
85+
- There are no tests for this plugin since it's a hard work
86+
- It is build with Java 8. Hope it will work with all superior version.
87+
88+
# Reference
89+
- Original file making the aggregation : https://github.com/jacoco/jacoco/blob/master/jacoco-maven-plugin/src/org/jacoco/maven/ReportAggregateMojo.java
90+
- Sonar way scanner expected to read and publish Jacoco files : https://github.com/SonarSource/sonar-scanner-commons/blob/master/api/src/main/java/org/sonarsource/scanner/api/EmbeddedScanner.java
91+
- A merging goal from Jacoco : https://github.com/jacoco/jacoco/blob/master/jacoco-maven-plugin/src/org/jacoco/maven/MergeMojo.java

pom.xml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
7+
<groupId>org.codefilarete</groupId>
8+
<artifactId>jacoco-aggregate-submodule</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
11+
<properties>
12+
<maven.compiler.source>8</maven.compiler.source>
13+
<maven.compiler.target>8</maven.compiler.target>
14+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15+
</properties>
16+
17+
<packaging>maven-plugin</packaging>
18+
19+
<prerequisites>
20+
<maven>3.0</maven>
21+
</prerequisites>
22+
23+
<dependencies>
24+
<dependency>
25+
<groupId>org.jacoco</groupId>
26+
<artifactId>jacoco-maven-plugin</artifactId>
27+
<version>0.8.11</version>
28+
</dependency>
29+
30+
<dependency>
31+
<groupId>org.apache.maven</groupId>
32+
<artifactId>maven-plugin-api</artifactId>
33+
<version>${project.prerequisites.maven}</version>
34+
<scope>provided</scope>
35+
</dependency>
36+
<dependency>
37+
<groupId>org.apache.maven</groupId>
38+
<artifactId>maven-core</artifactId>
39+
<version>${project.prerequisites.maven}</version>
40+
<scope>provided</scope>
41+
</dependency>
42+
<dependency>
43+
<groupId>org.apache.maven.reporting</groupId>
44+
<artifactId>maven-reporting-api</artifactId>
45+
<version>${project.prerequisites.maven}</version>
46+
</dependency>
47+
<dependency>
48+
<groupId>org.apache.maven.plugin-tools</groupId>
49+
<artifactId>maven-plugin-annotations</artifactId>
50+
<version>${project.prerequisites.maven}</version>
51+
<!-- annotations are needed only to build the plugin: -->
52+
<scope>provided</scope>
53+
</dependency>
54+
</dependencies>
55+
56+
<build>
57+
<plugins>
58+
<!-- This plugin (overall its version) is to fix some errors happening at build time like -->
59+
<!-- org.apache.maven.plugins:maven-plugin-plugin:3.2:descriptor failed: Index 9578 out of bounds for length -->
60+
<plugin>
61+
<groupId>org.apache.maven.plugins</groupId>
62+
<artifactId>maven-plugin-plugin</artifactId>
63+
<version>3.6.0</version>
64+
</plugin>
65+
</plugins>
66+
</build>
67+
</project>
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package org.codefilarete.maven.jacoco;
2+
3+
import java.io.File;
4+
import java.io.IOException;
5+
import java.util.List;
6+
import java.util.Locale;
7+
8+
import org.apache.maven.doxia.sink.SinkFactory;
9+
import org.apache.maven.plugin.AbstractMojo;
10+
import org.apache.maven.plugin.MojoExecutionException;
11+
import org.apache.maven.plugins.annotations.Parameter;
12+
import org.apache.maven.project.MavenProject;
13+
import org.apache.maven.reporting.MavenMultiPageReport;
14+
import org.apache.maven.reporting.MavenReportException;
15+
import org.jacoco.report.IReportGroupVisitor;
16+
import org.jacoco.report.IReportVisitor;
17+
18+
/**
19+
* Base class for creating a code coverage report for tests of a single project
20+
* in multiple formats (HTML, XML, and CSV).
21+
*/
22+
public abstract class AbstractReportMojo extends AbstractMojo implements MavenMultiPageReport {
23+
24+
/**
25+
* Encoding of the generated reports.
26+
*/
27+
@Parameter(property = "project.reporting.outputEncoding", defaultValue = "UTF-8")
28+
String outputEncoding;
29+
30+
/**
31+
* A list of report formats to generate. Supported formats are HTML, XML and
32+
* CSV. Defaults to all formats if no values are given.
33+
*
34+
* @since 0.8.7
35+
*/
36+
@Parameter(defaultValue = "HTML,XML,CSV")
37+
List<ReportFormat> formats;
38+
39+
/**
40+
* Name of the root node HTML report pages.
41+
*
42+
* @since 0.7.7
43+
*/
44+
@Parameter(defaultValue = "${project.name}")
45+
String title;
46+
47+
/**
48+
* Footer text used in HTML report pages.
49+
*
50+
* @since 0.7.7
51+
*/
52+
@Parameter
53+
String footer;
54+
55+
/**
56+
* Encoding of the source files.
57+
*/
58+
@Parameter(property = "project.build.sourceEncoding", defaultValue = "UTF-8")
59+
String sourceEncoding;
60+
61+
/**
62+
* A list of class files to include in the report. May use wildcard
63+
* characters (* and ?). When not specified everything will be included.
64+
*/
65+
@Parameter
66+
List<String> includes;
67+
68+
/**
69+
* A list of class files to exclude from the report. May use wildcard
70+
* characters (* and ?). When not specified nothing will be excluded.
71+
*/
72+
@Parameter
73+
List<String> excludes;
74+
75+
/**
76+
* Flag used to suppress execution.
77+
*/
78+
@Parameter(property = "jacoco.skip", defaultValue = "false")
79+
boolean skip;
80+
81+
/**
82+
* Maven project.
83+
*/
84+
@Parameter(property = "project", readonly = true)
85+
MavenProject project;
86+
87+
public String getDescription(final Locale locale) {
88+
return getName(locale) + " Coverage Report.";
89+
}
90+
91+
public boolean isExternalReport() {
92+
return true;
93+
}
94+
95+
public String getCategoryName() {
96+
return CATEGORY_PROJECT_REPORTS;
97+
}
98+
99+
/**
100+
* Returns the list of class files to include in the report.
101+
*
102+
* @return class files to include, may contain wildcard characters
103+
*/
104+
List<String> getIncludes() {
105+
return includes;
106+
}
107+
108+
/**
109+
* Returns the list of class files to exclude from the report.
110+
*
111+
* @return class files to exclude, may contain wildcard characters
112+
*/
113+
List<String> getExcludes() {
114+
return excludes;
115+
}
116+
117+
public boolean canGenerateReport() {
118+
if (skip) {
119+
getLog().info("Skipping JaCoCo execution because property jacoco.skip is set.");
120+
return false;
121+
}
122+
return true;
123+
}
124+
125+
abstract File getOutputDirectory();
126+
127+
public void generate(
128+
@SuppressWarnings("deprecation") final org.codehaus.doxia.sink.Sink sink,
129+
final Locale locale) throws MavenReportException {
130+
generate(sink, null, locale);
131+
}
132+
133+
public void generate(final org.apache.maven.doxia.sink.Sink sink,
134+
final SinkFactory sinkFactory, final Locale locale)
135+
throws MavenReportException {
136+
if (!canGenerateReport()) {
137+
return;
138+
}
139+
executeReport(locale);
140+
}
141+
142+
/**
143+
* This method is called when the report generation is invoked directly as a
144+
* standalone Mojo.
145+
*/
146+
public void execute() throws MojoExecutionException {
147+
if (!canGenerateReport()) {
148+
return;
149+
}
150+
try {
151+
executeReport(Locale.getDefault());
152+
} catch (final MavenReportException e) {
153+
throw new MojoExecutionException("An error has occurred in "
154+
+ getName(Locale.ENGLISH) + " report generation.", e);
155+
}
156+
}
157+
158+
private void executeReport(final Locale locale)
159+
throws MavenReportException {
160+
try {
161+
final ReportSupport support = new ReportSupport(getLog());
162+
loadExecutionData(support);
163+
addFormatters(support, locale);
164+
final IReportVisitor visitor = support.initRootVisitor();
165+
createReport(visitor, support);
166+
visitor.visitEnd();
167+
} catch (final IOException e) {
168+
throw new MavenReportException(
169+
"Error while creating report: " + e.getMessage(), e);
170+
}
171+
}
172+
173+
private void addFormatters(final ReportSupport support, final Locale locale)
174+
throws IOException {
175+
getOutputDirectory().mkdirs();
176+
for (final ReportFormat f : formats) {
177+
support.addVisitor(f.createVisitor(this, locale));
178+
}
179+
}
180+
181+
abstract void loadExecutionData(final ReportSupport support)
182+
throws IOException;
183+
184+
abstract void createReport(final IReportGroupVisitor visitor,
185+
final ReportSupport support) throws IOException;
186+
187+
}

0 commit comments

Comments
 (0)