diff --git a/.idea/libraries/bld.xml b/.idea/libraries/bld.xml index a35eaf8..f07cc1c 100644 --- a/.idea/libraries/bld.xml +++ b/.idea/libraries/bld.xml @@ -2,11 +2,11 @@ - + - + diff --git a/.vscode/settings.json b/.vscode/settings.json index 9f84d85..5dd7145 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.rife2/dist/rife2-1.6.2.jar", + "${HOME}bld-1.7.0-SNAPSHOT.jar", "lib/compile/*.jar", "lib/runtime/*.jar", "lib/test/*.jar" diff --git a/examples/.idea/libraries/bld.xml b/examples/.idea/libraries/bld.xml index 7596927..f07cc1c 100644 --- a/examples/.idea/libraries/bld.xml +++ b/examples/.idea/libraries/bld.xml @@ -2,11 +2,11 @@ - + - + diff --git a/examples/.vscode/settings.json b/examples/.vscode/settings.json index 4fdc74b..5dd7145 100644 --- a/examples/.vscode/settings.json +++ b/examples/.vscode/settings.json @@ -7,7 +7,7 @@ ], "java.configuration.updateBuildConfiguration": "automatic", "java.project.referencedLibraries": [ - "${HOME}/.rife2/dist/rife2-1.6.1.jar", + "${HOME}bld-1.7.0-SNAPSHOT.jar", "lib/compile/*.jar", "lib/runtime/*.jar", "lib/test/*.jar" diff --git a/examples/lib/bld/bld-wrapper.jar b/examples/lib/bld/bld-wrapper.jar index 0f4a21a..0c69eaa 100644 Binary files a/examples/lib/bld/bld-wrapper.jar and b/examples/lib/bld/bld-wrapper.jar differ diff --git a/examples/lib/bld/bld-wrapper.properties b/examples/lib/bld/bld-wrapper.properties index 6b13985..707f243 100644 --- a/examples/lib/bld/bld-wrapper.properties +++ b/examples/lib/bld/bld-wrapper.properties @@ -2,5 +2,5 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true bld.extension-pmd=com.uwyn.rife2:bld-jacoco-report:0.9.0-SNAPSHOT bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES -rife2.downloadLocation= -rife2.version=1.6.1 \ No newline at end of file +bld.downloadLocation= +bld.version=1.7.0 \ No newline at end of file diff --git a/examples/src/bld/java/com/example/ExamplesBuild.java b/examples/src/bld/java/com/example/ExamplesBuild.java index 8c6e5e3..ea0864a 100644 --- a/examples/src/bld/java/com/example/ExamplesBuild.java +++ b/examples/src/bld/java/com/example/ExamplesBuild.java @@ -19,8 +19,8 @@ public class ExamplesBuild extends Project { repositories = List.of(MAVEN_CENTRAL); scope(test) - .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.jupiter", "junit-jupiter", version(5, 9, 3))) + .include(dependency("org.junit.platform", "junit-platform-console-standalone", version(1, 9, 3))); } public static void main(String[] args) { diff --git a/lib/bld/bld-wrapper.jar b/lib/bld/bld-wrapper.jar index 27c4538..afa7b0c 100644 Binary files a/lib/bld/bld-wrapper.jar and b/lib/bld/bld-wrapper.jar differ diff --git a/lib/bld/bld-wrapper.properties b/lib/bld/bld-wrapper.properties index 605fa65..a435808 100644 --- a/lib/bld/bld-wrapper.properties +++ b/lib/bld/bld-wrapper.properties @@ -2,5 +2,5 @@ bld.downloadExtensionJavadoc=false bld.downloadExtensionSources=true bld.extension-pmd=com.uwyn.rife2:bld-pmd:0.9.1-SNAPSHOT bld.repositories=MAVEN_LOCAL,MAVEN_CENTRAL,RIFE2_SNAPSHOTS,RIFE2_RELEASES -rife2.downloadLocation= -rife2.version=1.6.2 \ No newline at end of file +bld.downloadLocation= +bld.version=1.7.0 \ No newline at end of file diff --git a/src/bld/java/rife/bld/extension/JacocoReportOperationBuild.java b/src/bld/java/rife/bld/extension/JacocoReportOperationBuild.java index 2195e8b..dc9acae 100644 --- a/src/bld/java/rife/bld/extension/JacocoReportOperationBuild.java +++ b/src/bld/java/rife/bld/extension/JacocoReportOperationBuild.java @@ -23,7 +23,9 @@ 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.*; @@ -41,9 +43,11 @@ 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); scope(compile) .include(dependency("org.jacoco", "jacoco", jacocoVersion).exclude("*", "org.jacoco.doc")) - .include(dependency("com.uwyn.rife2", "rife2", version(1, 6, 2))); + .include(dependency("com.uwyn.rife2", "rife2", rife2)) + .include(dependency("com.uwyn.rife2", "bld", rife2)); scope(runtime) .include(dependency("org.jacoco", "jacoco", jacocoVersion).exclude("*", "org.jacoco.doc")); scope(test) @@ -59,8 +63,8 @@ public class JacocoReportOperationBuild extends Project { .link("https://rife2.github.io/rife2/"); publishOperation() - .repository(MAVEN_LOCAL) // .repository(version.isSnapshot() ? repository("rife2-snapshot") : repository("rife2")) + .repository(MAVEN_LOCAL) .info() .groupId("com.uwyn.rife2") .artifactId("bld-jacoco-report") diff --git a/src/main/java/rife/bld/extension/JacocoReportOperation.java b/src/main/java/rife/bld/extension/JacocoReportOperation.java index 777e2a1..a191e9f 100644 --- a/src/main/java/rife/bld/extension/JacocoReportOperation.java +++ b/src/main/java/rife/bld/extension/JacocoReportOperation.java @@ -20,6 +20,8 @@ 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; @@ -30,6 +32,8 @@ import rife.bld.operations.JUnitOperation; 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; @@ -37,7 +41,6 @@ import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; -import java.util.stream.Collectors; /** @@ -50,10 +53,12 @@ public class JacocoReportOperation extends JUnitOperation { private static final Logger LOGGER = Logger.getLogger(JacocoReportOperation.class.getName()); private final List classFiles = new ArrayList<>(); private final List execFiles = new ArrayList<>(); + private final List instrumentedFiles = new ArrayList<>(); private final List 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; @@ -70,6 +75,22 @@ 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. **/ @@ -115,18 +136,10 @@ public class JacocoReportOperation extends JUnitOperation { } else { var buildJacocoReportsDir = Path.of(project.buildDirectory().getPath(), "reports", "jacoco", "test").toFile(); var buildJacocoExecDir = Path.of(project.buildDirectory().getPath(), "jacoco").toFile(); - var buildJacocoTestExec = new File(buildJacocoExecDir, "test.exec"); + var buildJacocoClassesDir = Path.of(buildJacocoExecDir.getPath(), "classes").toFile(); - if (execFiles.isEmpty()) { - execFiles.add(buildJacocoTestExec); - - //noinspection ResultOfMethodCallIgnored - buildJacocoExecDir.mkdirs(); - - javaOptions().javaAgent(new File(project.libBldDirectory(), "jacocoagent.jar"), - "destfile=" + buildJacocoTestExec + - ",includes=" + classFiles.stream().map(File::toString).collect(Collectors.joining(","))); - } + instrumenter = new Instrumenter(new OfflineInstrumentationAccessGenerator()); + instrumenter.setRemoveSignatures(true); if (sourceFiles.isEmpty()) { sourceFiles.add(project.srcDirectory()); @@ -150,6 +163,17 @@ 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)); + } + } + //noinspection ResultOfMethodCallIgnored buildJacocoReportsDir.mkdirs(); @@ -162,6 +186,7 @@ public class JacocoReportOperation extends JUnitOperation { /** * Configure the operation from a {@link BaseProject}. */ + @Override public JacocoReportOperation fromProject(BaseProject project) { this.project = project; return this; @@ -175,6 +200,39 @@ 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) {