Added jacoco.exec generation

This commit is contained in:
Erik C. Thauvin 2023-08-10 22:06:11 -07:00
parent 8e94bb4d60
commit 9e6471c74b
4 changed files with 30 additions and 87 deletions

View file

@ -23,9 +23,7 @@ import rife.bld.publish.PublishDeveloper;
import rife.bld.publish.PublishLicense;
import rife.bld.publish.PublishScm;
import java.io.File;
import java.util.List;
import java.util.stream.Collectors;
import static rife.bld.dependencies.Repository.*;
import static rife.bld.dependencies.Scope.*;
@ -43,7 +41,7 @@ public class JacocoReportOperationBuild extends Project {
repositories = List.of(MAVEN_CENTRAL, RIFE2_RELEASES);
var jacocoVersion = new VersionNumber(0, 8, 10);
var rife2 = version(1,7,0);
var rife2 = version(1, 7, 0);
scope(compile)
.include(dependency("org.jacoco", "jacoco", jacocoVersion).exclude("*", "org.jacoco.doc"))
.include(dependency("com.uwyn.rife2", "rife2", rife2))
@ -51,8 +49,8 @@ public class JacocoReportOperationBuild extends Project {
scope(runtime)
.include(dependency("org.jacoco", "jacoco", jacocoVersion).exclude("*", "org.jacoco.doc"));
scope(test)
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 9, 3)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 9, 3)))
.include(dependency("org.junit.jupiter", "junit-jupiter", version(5, 10, 0)))
.include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 10, 0)))
.include(dependency("org.assertj:assertj-joda-time:2.2.0"));
testOperation().mainClass("rife.bld.extension.JacocoReportOperationTest");
@ -63,8 +61,8 @@ public class JacocoReportOperationBuild extends Project {
.link("https://rife2.github.io/rife2/");
publishOperation()
// .repository(version.isSnapshot() ? repository("rife2-snapshot") : repository("rife2"))
.repository(MAVEN_LOCAL)
.repository(version.isSnapshot() ? repository("rife2-snapshot") : repository("rife2"))
// .repository(MAVEN_LOCAL)
.info()
.groupId("com.uwyn.rife2")
.artifactId("bld-jacoco-report")
@ -93,5 +91,4 @@ public class JacocoReportOperationBuild extends Project {
.ruleSets("config/pmd.xml")
.execute();
}
}

View file

@ -16,24 +16,22 @@
package rife.bld.extension;
import org.jacoco.core.JaCoCo;
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.instr.Instrumenter;
import org.jacoco.core.runtime.OfflineInstrumentationAccessGenerator;
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.operations.JUnitOperation;
import rife.bld.operations.AbstractOperation;
import rife.bld.operations.exceptions.ExitStatusException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
@ -49,16 +47,14 @@ import java.util.logging.Logger;
* @author <a href="https://erik.thauvin.net/">Erik C. Thauvin</a>
* @since 1.0
*/
public class JacocoReportOperation extends JUnitOperation {
public class JacocoReportOperation extends AbstractOperation<JacocoReportOperation> {
private static final Logger LOGGER = Logger.getLogger(JacocoReportOperation.class.getName());
private final List<File> classFiles = new ArrayList<>();
private final List<File> execFiles = new ArrayList<>();
private final List<File> instrumentedFiles = new ArrayList<>();
private final List<File> sourceFiles = new ArrayList<>();
private File csv;
private String encoding;
private File html;
private Instrumenter instrumenter;
private String name = "JaCoCo Coverage Report";
private BaseProject project;
private boolean quiet;
@ -75,22 +71,6 @@ public class JacocoReportOperation extends JUnitOperation {
return builder.getBundle(name);
}
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private void buildInstrumentedFiles(File dest) throws IOException {
var total = 0;
for (var f : classFiles) {
if (f.isFile()) {
total += instrument(f, new File(dest, f.getName()));
} else {
total += instrumentRecursive(f, dest);
}
}
if (LOGGER.isLoggable(Level.INFO) && !quiet) {
LOGGER.log(Level.INFO, "{0} classes instrumented to {1}.",
new Object[]{total, dest.getAbsolutePath()});
}
}
/**
* Sets the locations of Java class files.
**/
@ -117,7 +97,7 @@ public class JacocoReportOperation extends JUnitOperation {
/**
* Sets the locations of the JaCoCo *.exec files to read.
**/
*/
public JacocoReportOperation execFiles(File... execFiles) {
this.execFiles.addAll(Arrays.stream(execFiles).toList());
return this;
@ -125,21 +105,29 @@ public class JacocoReportOperation extends JUnitOperation {
/**
* Performs the operation execution that can be wrapped by the {@code #executeOnce} call.
*
* @since 1.5.10
*/
@Override
public void execute() throws IOException {
if (project == null && LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.severe("A project must be specified.");
if ((project == null) && LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.severe("A project and version must be specified.");
} else {
var buildJacocoReportsDir = Path.of(project.buildDirectory().getPath(), "reports", "jacoco", "test").toFile();
var buildJacocoExecDir = Path.of(project.buildDirectory().getPath(), "jacoco").toFile();
var buildJacocoClassesDir = Path.of(buildJacocoExecDir.getPath(), "classes").toFile();
var buildJacocoExec = Path.of(buildJacocoExecDir.getPath(), "jacoco.exec").toFile();
instrumenter = new Instrumenter(new OfflineInstrumentationAccessGenerator());
instrumenter.setRemoveSignatures(true);
// project.testOperation().fromProject(project).javaOptions().javaAgent(
// Path.of(project.libBldDirectory().getPath(), "org.jacoco.agent-"
// + JaCoCo.VERSION.substring(0, JaCoCo.VERSION.lastIndexOf('.')) + "-runtime.jar").toFile(),
// "destfile=" + Path.of(buildJacocoExecDir.getPath(), "jacoco.exec"));
project.testOperation().fromProject(project).javaOptions().add("-javaagent:" +
Path.of(project.libBldDirectory().getPath(), "org.jacoco.agent-"
+ JaCoCo.VERSION.substring(0, JaCoCo.VERSION.lastIndexOf('.')) + "-runtime.jar")
+ "=destfile=" + Path.of(buildJacocoExecDir.getPath(), "jacoco.exec"));
try {
project.testOperation().execute();
} catch (InterruptedException | ExitStatusException e) {
throw new IOException(e);
}
if (sourceFiles.isEmpty()) {
sourceFiles.add(project.srcDirectory());
@ -163,15 +151,8 @@ public class JacocoReportOperation extends JUnitOperation {
csv = new File(buildJacocoReportsDir, "jacocoTestReport.csv");
}
if (execFiles.isEmpty()) {
//noinspection ResultOfMethodCallIgnored
buildJacocoClassesDir.mkdirs();
buildInstrumentedFiles(buildJacocoClassesDir);
var files = buildJacocoClassesDir.listFiles();
if (files != null) {
instrumentedFiles.addAll(Arrays.asList(files));
}
if (execFiles.isEmpty() && (buildJacocoExec.exists())) {
execFiles.add(buildJacocoExec);
}
//noinspection ResultOfMethodCallIgnored
@ -186,7 +167,6 @@ public class JacocoReportOperation extends JUnitOperation {
/**
* Configure the operation from a {@link BaseProject}.
*/
@Override
public JacocoReportOperation fromProject(BaseProject project) {
this.project = project;
return this;
@ -200,39 +180,6 @@ public class JacocoReportOperation extends JUnitOperation {
return this;
}
private int instrument(final File src, final File dest) throws IOException {
//noinspection ResultOfMethodCallIgnored
dest.getParentFile().mkdirs();
try (InputStream input = Files.newInputStream(src.toPath())) {
try (OutputStream output = Files.newOutputStream(dest.toPath())) {
return instrumenter.instrumentAll(input, output,
src.getAbsolutePath());
}
} catch (final IOException e) {
//noinspection ResultOfMethodCallIgnored
dest.delete();
throw e;
}
}
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private int instrumentRecursive(final File src, final File dest)
throws IOException {
var total = 0;
if (src.isDirectory()) {
var listFiles = src.listFiles();
if (listFiles != null) {
for (var child : listFiles) {
total += instrumentRecursive(child,
new File(dest, child.getName()));
}
}
} else {
total += instrument(src, dest);
}
return total;
}
private ExecFileLoader loadExecFiles() throws IOException {
var loader = new ExecFileLoader();
if (execFiles.isEmpty() && LOGGER.isLoggable(Level.WARNING) && !quiet) {
@ -294,7 +241,6 @@ public class JacocoReportOperation extends JUnitOperation {
return this;
}
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private ISourceFileLocator sourceLocator() {
var multi = new MultiSourceFileLocator(tabWidth);

View file

@ -17,10 +17,11 @@
package rife.bld.extension;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
class JacocoReportOperationTest {
@Test
void executeTest() {
assertThat(true).isTrue(); // TODO
}
}