Compare commits

...

4 commits

Author SHA1 Message Date
9e6471c74b Added jacoco.exec generation 2023-08-10 22:06:11 -07:00
8e94bb4d60 Minor cleanup 2023-08-10 22:03:54 -07:00
1081749ae6 Added GitHub workflows 2023-08-10 21:51:07 -07:00
d5ec4bdf1b Added README 2023-08-10 21:50:24 -07:00
10 changed files with 152 additions and 39749 deletions

32
.github/workflows/bld.yml vendored Normal file
View file

@ -0,0 +1,32 @@
name: bld-ci
on: [ push, pull_request, workflow_dispatch ]
jobs:
build-bld-project:
runs-on: ubuntu-latest
strategy:
matrix:
java-version: [ 17, 20 ]
steps:
- name: Checkout source repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up JDK ${{ matrix.java-version }}
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: ${{ matrix.java-version }}
- name: Grant execute permission for bld
run: chmod +x bld
- name: Download the dependencies
run: ./bld download
- name: Run tests with bld
run: ./bld compile test

57
.github/workflows/pages.yml vendored Normal file
View file

@ -0,0 +1,57 @@
name: javadocs-pages
on:
# Runs on pushes targeting the default branch
push:
branches: ["master"]
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout source repository
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'zulu'
java-version: 17
- name: Build Javadocs
run: ./bld download clean javadoc
- name: Setup Pages
uses: actions/configure-pages@v3
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload generated Javadocs repository
path: 'build/javadoc/'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

1
.idea/misc.xml generated
View file

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="EntryPointsManager">
<entry_points version="2.0">

28
README.md Executable file
View file

@ -0,0 +1,28 @@
# [Bld](https://rife2.com/bld) Extension to Code Coverage Analysis with [JaCoCo](https://www.eclemma.org/jacoco/)
[![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause)
[![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html)
[![Release](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/releases/com/uwyn/rife2/bld-jacoco-report/maven-metadata.xml?color=blue)](https://repo.rife2.com/#/releases/com/uwyn/rife2/bld-jacoco-report)
[![Snapshot](https://flat.badgen.net/maven/v/metadata-url/repo.rife2.com/snapshots/com/uwyn/rife2/bld-jacoco-report/maven-metadata.xml?label=snapshot)](https://repo.rife2.com/#/snapshots/com/uwyn/rife2/bld-jacoco-report)
[![GitHub CI](https://github.com/rife2/bld-jacoco-report/actions/workflows/bld.yml/badge.svg)](https://github.com/rife2/bld-jacoco-report/actions/workflows/bld.yml)
To run the tests and generate the code coverage reports:
```java
@BuildCommand(summary = "Generates Jacoco Reports")
public void jacoco() throws IOException {
new JacocoReportOperation()
.fromProject(this)
.execute();
}
```
```text
./bld compile jacoco
```
- The HTML, CVS and XML reports will be automatically created in the `build/reports/jacoco/test` directory.
- The execution coverage data will be automatically recorded in the `build/jacoco/jacoco.exec` file.
Please check the [JacocoReportOperation documentation](https://rife2.github.io/bld-jacoco-report/rife/bld/extension/JacocoOperation.html#method-summary) for all available configuration options.

View file

@ -27,12 +27,11 @@ public class ExamplesBuild extends Project {
new ExamplesBuild().start(args);
}
@Override
public void test() throws Exception {
super.test();
jacoco();
}
// @Override
// public void test() throws Exception {
// super.test();
// jacoco();
// }
@BuildCommand(summary = "Generates Jacoco Reports")
public void jacoco() throws IOException {

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

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
}
}