Added configuration options similar to the JaCoCo CLI
This commit is contained in:
parent
57b0fa5b55
commit
224c5e6616
3 changed files with 121 additions and 39 deletions
|
@ -42,10 +42,10 @@ public class JacocoReportOperationBuild extends Project {
|
||||||
|
|
||||||
var jacocoVersion = new VersionNumber(0, 8, 10);
|
var jacocoVersion = new VersionNumber(0, 8, 10);
|
||||||
scope(compile)
|
scope(compile)
|
||||||
.include(dependency("org.jacoco", "jacoco", jacocoVersion))
|
.include(dependency("org.jacoco", "jacoco", jacocoVersion).exclude("*", "org.jacoco.doc"))
|
||||||
.include(dependency("com.uwyn.rife2", "rife2", version(1, 6, 1)));
|
.include(dependency("com.uwyn.rife2", "rife2", version(1, 6, 1)));
|
||||||
scope(runtime)
|
scope(runtime)
|
||||||
.include(dependency("org.jacoco", "jacoco", jacocoVersion));
|
.include(dependency("org.jacoco", "jacoco", jacocoVersion).exclude("*", "org.jacoco.doc"));
|
||||||
scope(test)
|
scope(test)
|
||||||
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 9, 2)))
|
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 9, 2)))
|
||||||
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 9, 2)))
|
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 9, 2)))
|
||||||
|
|
|
@ -16,16 +16,27 @@
|
||||||
|
|
||||||
package rife.bld.extension;
|
package rife.bld.extension;
|
||||||
|
|
||||||
|
import org.jacoco.core.analysis.Analyzer;
|
||||||
|
import org.jacoco.core.analysis.CoverageBuilder;
|
||||||
|
import org.jacoco.core.analysis.IBundleCoverage;
|
||||||
|
import org.jacoco.core.data.ExecutionDataStore;
|
||||||
|
import org.jacoco.core.tools.ExecFileLoader;
|
||||||
|
import org.jacoco.report.*;
|
||||||
|
import org.jacoco.report.csv.CSVFormatter;
|
||||||
|
import org.jacoco.report.html.HTMLFormatter;
|
||||||
|
import org.jacoco.report.xml.XMLFormatter;
|
||||||
import rife.bld.BaseProject;
|
import rife.bld.BaseProject;
|
||||||
import rife.bld.operations.AbstractOperation;
|
import rife.bld.operations.AbstractOperation;
|
||||||
import rife.tools.FileUtils;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates <a href="https://www.jacoco.org/jacoco">JaCoCo</a> reports.
|
* Generates <a href="https://www.jacoco.org/jacoco">JaCoCo</a> reports.
|
||||||
|
@ -41,16 +52,26 @@ public class JacocoReportOperation extends AbstractOperation<JacocoReportOperati
|
||||||
private File csv;
|
private File csv;
|
||||||
private String encoding;
|
private String encoding;
|
||||||
private File html;
|
private File html;
|
||||||
private String name;
|
private String name = "JaCoCo Coverage Report";
|
||||||
private BaseProject project;
|
private BaseProject project;
|
||||||
private boolean quiet = false;
|
private boolean quiet;
|
||||||
private int tabWidth = 4;
|
private int tabWidth = 4;
|
||||||
private File xml;
|
private File xml;
|
||||||
|
|
||||||
|
private IBundleCoverage analyze(ExecutionDataStore data) throws IOException {
|
||||||
|
var builder = new CoverageBuilder();
|
||||||
|
var analyzer = new Analyzer(data, builder);
|
||||||
|
for (var f : classFiles) {
|
||||||
|
LOGGER.info(f.getAbsolutePath());
|
||||||
|
analyzer.analyzeAll(f);
|
||||||
|
}
|
||||||
|
return builder.getBundle(name);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the locations of Java class files.
|
* Set the locations of Java class files.
|
||||||
**/
|
**/
|
||||||
public JacocoReportOperation classFiles(ArrayList<File> classFiles) {
|
public JacocoReportOperation classFiles(List<File> classFiles) {
|
||||||
this.classFiles.addAll(classFiles);
|
this.classFiles.addAll(classFiles);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -74,7 +95,7 @@ public class JacocoReportOperation extends AbstractOperation<JacocoReportOperati
|
||||||
/**
|
/**
|
||||||
* Sets a list of JaCoCo *.exec files to read.
|
* Sets a list of JaCoCo *.exec files to read.
|
||||||
**/
|
**/
|
||||||
public JacocoReportOperation execFiles(ArrayList<File> execFiles) {
|
public JacocoReportOperation execFiles(List<File> execFiles) {
|
||||||
this.execFiles.addAll(execFiles);
|
this.execFiles.addAll(execFiles);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -92,27 +113,37 @@ public class JacocoReportOperation extends AbstractOperation<JacocoReportOperati
|
||||||
LOGGER.severe("A project must be specified.");
|
LOGGER.severe("A project must be specified.");
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (execFiles.isEmpty()) {
|
var buildJacocoReportsDir = Path.of(project.buildDirectory().getPath(), "reports", "jacoco", "test").toFile();
|
||||||
if (LOGGER.isLoggable(Level.WARNING)) {
|
|
||||||
LOGGER.warning("No execution data files provided.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sourceFiles.isEmpty()) {
|
if (sourceFiles.isEmpty()) {
|
||||||
sourceFiles.addAll(project.mainSourceFiles());
|
sourceFiles.add(project.srcDirectory());
|
||||||
sourceFiles.addAll(project.testSourceFiles());
|
//sourceFiles.add(project.srcTestDirectory());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classFiles.isEmpty()) {
|
if (classFiles.isEmpty()) {
|
||||||
classFiles.addAll(getClassFiles(project.buildMainDirectory()));
|
classFiles.add(project.buildMainDirectory());
|
||||||
classFiles.addAll(getClassFiles(project.buildTestDirectory()));
|
classFiles.add(project.buildTestDirectory());
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<File> getClassFiles(File directory) {
|
if (html == null) {
|
||||||
return FileUtils.getFileList(directory, Pattern.compile("^.*\\.class$"), null)
|
html = new File(buildJacocoReportsDir, "html");
|
||||||
.stream().map(f -> new File(directory, f)).toList();
|
}
|
||||||
|
|
||||||
|
if (xml == null) {
|
||||||
|
xml = new File(buildJacocoReportsDir, "jacocoTestReport.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csv == null) {
|
||||||
|
csv = new File(buildJacocoReportsDir, "jacocoTestReport.csv");
|
||||||
|
}
|
||||||
|
|
||||||
|
//noinspection ResultOfMethodCallIgnored
|
||||||
|
buildJacocoReportsDir.mkdirs();
|
||||||
|
|
||||||
|
var loader = loadExecFiles();
|
||||||
|
var bundle = analyze(loader.getExecutionDataStore());
|
||||||
|
writeReports(bundle, loader);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -123,10 +154,6 @@ public class JacocoReportOperation extends AbstractOperation<JacocoReportOperati
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return "Hello World!";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the location of the HTML report.
|
* Sets the location of the HTML report.
|
||||||
*/
|
*/
|
||||||
|
@ -135,6 +162,22 @@ public class JacocoReportOperation extends AbstractOperation<JacocoReportOperati
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ExecFileLoader loadExecFiles() throws IOException {
|
||||||
|
var loader = new ExecFileLoader();
|
||||||
|
if (execFiles.isEmpty() && LOGGER.isLoggable(Level.WARNING) && !quiet) {
|
||||||
|
LOGGER.warning("No execution data files provided.");
|
||||||
|
} else {
|
||||||
|
for (var f : execFiles) {
|
||||||
|
if (LOGGER.isLoggable(Level.INFO) && !quiet) {
|
||||||
|
LOGGER.log(Level.INFO, "Loading execution data file: {0}",
|
||||||
|
f.getAbsolutePath());
|
||||||
|
}
|
||||||
|
loader.load(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return loader;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name used for the report.
|
* Sets the name used for the report.
|
||||||
*/
|
*/
|
||||||
|
@ -151,22 +194,65 @@ public class JacocoReportOperation extends AbstractOperation<JacocoReportOperati
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private IReportVisitor reportVisitor() throws IOException {
|
||||||
|
List<IReportVisitor> visitors = new ArrayList<>();
|
||||||
|
|
||||||
|
if (xml != null) {
|
||||||
|
var formatter = new XMLFormatter();
|
||||||
|
visitors.add(formatter.createVisitor(Files.newOutputStream(xml.toPath())));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (csv != null) {
|
||||||
|
var formatter = new CSVFormatter();
|
||||||
|
visitors.add(formatter.createVisitor(Files.newOutputStream(csv.toPath())));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (html != null) {
|
||||||
|
var formatter = new HTMLFormatter();
|
||||||
|
visitors.add(formatter.createVisitor(new FileMultiReportOutput(html)));
|
||||||
|
}
|
||||||
|
|
||||||
|
return new MultiReportVisitor(visitors);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the locations of the source files.
|
* Sets the locations of the source files.
|
||||||
**/
|
**/
|
||||||
public JacocoReportOperation sourceFiles(ArrayList<File> sourceFiles) {
|
public JacocoReportOperation sourceFiles(List<File> sourceFiles) {
|
||||||
this.sourceFiles.addAll(sourceFiles);
|
this.sourceFiles.addAll(sourceFiles);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
|
||||||
|
private ISourceFileLocator sourceLocator() {
|
||||||
|
var multi = new MultiSourceFileLocator(tabWidth);
|
||||||
|
for (var f : sourceFiles) {
|
||||||
|
multi.add(new DirectorySourceFileLocator(f, encoding, tabWidth));
|
||||||
|
}
|
||||||
|
return multi;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the tab stop width for the source pages. Default is {@code 4}.
|
* Sets the tab stop width for the source pages. Default is {@code 4}.
|
||||||
*/
|
*/
|
||||||
public JacocoReportOperation tabWidth(int tabWitdh) {
|
public JacocoReportOperation tabWidth(int tabWidth) {
|
||||||
this.tabWidth = tabWitdh;
|
this.tabWidth = tabWidth;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void writeReports(IBundleCoverage bundle, ExecFileLoader loader)
|
||||||
|
throws IOException {
|
||||||
|
if (LOGGER.isLoggable(Level.INFO) && !quiet) {
|
||||||
|
LOGGER.log(Level.INFO, "Analyzing {0} classes.",
|
||||||
|
bundle.getClassCounter().getTotalCount());
|
||||||
|
}
|
||||||
|
IReportVisitor visitor = reportVisitor();
|
||||||
|
visitor.visitInfo(loader.getSessionInfoStore().getInfos(),
|
||||||
|
loader.getExecutionDataStore().getContents());
|
||||||
|
visitor.visitBundle(bundle, sourceLocator());
|
||||||
|
visitor.visitEnd();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the location of the XML report.
|
* Sets the location of the XML report.
|
||||||
*/
|
*/
|
||||||
|
@ -174,4 +260,5 @@ public class JacocoReportOperation extends AbstractOperation<JacocoReportOperati
|
||||||
this.xml = xml;
|
this.xml = xml;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -16,16 +16,11 @@
|
||||||
|
|
||||||
package rife.bld.extension;
|
package rife.bld.extension;
|
||||||
|
|
||||||
public class JacocoReportOperationTest {
|
import org.junit.jupiter.api.Test;
|
||||||
void verifyHello() {
|
|
||||||
if (!"Hello World!".equals(new JacocoReportOperation().getMessage())) {
|
class JacocoReportOperationTest {
|
||||||
throw new AssertionError();
|
@Test
|
||||||
} else {
|
void executeTest() {
|
||||||
System.out.println("Succeeded");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) {
|
|
||||||
new JacocoReportOperationTest().verifyHello();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue