From 52660cb517bf6f9102c8ac2d31d0c56e03f82092 Mon Sep 17 00:00:00 2001 From: Juergen Schmid Date: Sun, 9 Sep 2018 18:16:59 +0200 Subject: [PATCH 1/7] Add BndManifestPlugin support for every task which extends Jar --- .../gradle/osgi/BndManifestPlugin.java | 66 ++++++++++--------- .../gradle/osgi/BndManifestPluginTest.java | 42 +++++++++++- 2 files changed, 75 insertions(+), 33 deletions(-) diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java index a96185e39..516236207 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java @@ -22,10 +22,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.text.SimpleDateFormat; -import java.util.Arrays; -import java.util.Date; -import java.util.Map; -import java.util.Set; +import java.util.*; import java.util.function.Function; import org.gradle.api.Project; @@ -34,6 +31,7 @@ import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetOutput; +import org.gradle.api.tasks.TaskCollection; import org.gradle.api.tasks.bundling.Jar; import aQute.bnd.osgi.Builder; @@ -97,36 +95,41 @@ public class BndManifestPlugin extends ProjectPlugin { protected void applyOnce(Project proj) { ProjectPlugin.getPlugin(proj, JavaPlugin.class); BndManifestExtension extension = proj.getExtensions().create(BndManifestExtension.NAME, BndManifestExtension.class); - Jar jarTask = (Jar) proj.getTasks().getByName(JavaPlugin.JAR_TASK_NAME); - // at the end of the jar, modify the manifest, and possibly write it to `osgiBndManifest { bndManifestcopyTo }`. - jarTask.doLast(unused -> { - Errors.rethrow().run(() -> { - byte[] manifest = getManifestContent(jarTask, extension).getBytes(StandardCharsets.UTF_8); - // modify the jar - Map> toModify = ImmutableMap.of("META-INF/MANIFEST.MF", in -> manifest); - ZipMisc.modify(jarTask.getArchivePath(), toModify, Predicates.alwaysFalse()); - // write manifest to the output resources directory - Throwing.Consumer writeManifest = path -> { - if (Files.exists(path)) { - if (Arrays.equals(Files.readAllBytes(path), manifest)) { - return; + + proj.getGradle().getTaskGraph().whenReady( taskGraph -> { + + // use all tasks which extends Jar + TaskCollection jarTasks = proj.getTasks().withType(Jar.class); + // at the end of the jar, modify the manifest, and possibly write it to `osgiBndManifest { bndManifestcopyTo }`. + jarTasks.forEach(jarTask -> jarTask.doLast(unused -> { + Errors.rethrow().run(() -> { + byte[] manifest = getManifestContent(jarTask, extension).getBytes(StandardCharsets.UTF_8); + // modify the jar + Map> toModify = ImmutableMap.of("META-INF/MANIFEST.MF", in -> manifest); + ZipMisc.modify(jarTask.getArchivePath(), toModify, Predicates.alwaysFalse()); + // write manifest to the output resources directory + Throwing.Consumer writeManifest = path -> { + if (Files.exists(path)) { + if (Arrays.equals(Files.readAllBytes(path), manifest)) { + return; + } } + Files.createDirectories(path.getParent()); + Files.write(path, manifest); + }; + writeManifest.accept(outputManifest(jarTask)); + // and the jarTask, maybe + if (extension.copyTo != null) { + writeManifest.accept(jarTask.getProject().file(extension.copyTo).toPath()); } - Files.createDirectories(path.getParent()); - Files.write(path, manifest); - }; - writeManifest.accept(outputManifest(jarTask)); - // and the jarTask, maybe - if (extension.copyTo != null) { - writeManifest.accept(jarTask.getProject().file(extension.copyTo).toPath()); - } - }); + }); + })); }); proj.afterEvaluate(project -> { // find the file that the user would like us to copy to (if any) if (extension.copyTo != null) { - jarTask.getOutputs().file(extension.copyTo); + proj.getTasks().withType(Jar.class).forEach(jarTask -> jarTask.getOutputs().file(extension.copyTo)); } }); } @@ -173,15 +176,14 @@ private static String takeBndAction(Project project, Jar jarTask, Throwing.Funct JavaPluginConvention javaConvention = project.getConvention().getPlugin(JavaPluginConvention.class); SourceSetOutput main = javaConvention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput(); // delete empty folders so that bnd doesn't make Export-Package entries for them - StringBuilder includeresource = new StringBuilder(); + Set includeresource = new HashSet<>(); deleteEmptyFoldersIfExists(main.getResourcesDir()); - includeresource.append(fix(main.getResourcesDir())); + includeresource.add(fix(main.getResourcesDir())); for (File file : main.getClassesDirs()) { deleteEmptyFoldersIfExists(file); - includeresource.append(","); - includeresource.append(fix(file)); + includeresource.add(fix(file)); } - builder.set(Constants.INCLUDERESOURCE, includeresource.toString()); + builder.set(Constants.INCLUDERESOURCE, String.join(",", includeresource)); // set the version if (builder.getBundleVersion() == null) { diff --git a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java index c9b29b888..f4dcd8b7f 100644 --- a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java +++ b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java @@ -74,7 +74,47 @@ public void assertMerging() throws IOException { testCase("osgiBndManifest { mergeWithExisting true }", expectedMerge); } + @Test + public void assertCustomJarTasks() throws IOException { + write("src/main/resources/META-INF/MANIFEST.MF", + "Manifest-Version: 1.0", + "Bundle-ManifestVersion: 2", + "Bundle-Name: Mock", + "Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.mock; singleton:=true", + "Bundle-Version: 1.0.0.qualifier", + "Bundle-ActivationPolicy: lazy", + "Require-Bundle: org.eclipse.core.runtime"); + String expectedMerge = StringPrinter.buildStringFromLines( + "Manifest-Version: 1.0", + "Bundle-ActivationPolicy: lazy", + "Bundle-ManifestVersion: 2", + "Bundle-SymbolicName: test", + "Bundle-Version: 0.0.0.ERRORSETVERSION", + "Export-Package: test;uses:=\"com.diffplug.common.base\";version=\"0.0.0\"", + "Import-Package: com.diffplug.common.base;version=\"[3.4,4)\"", + "Require-Bundle: org.eclipse.core.runtime", + "Require-Capability: osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\""); + String buildScript = StringPrinter.buildStringFromLines( + "task customJar(type: Jar) {", + " with jar", + " manifest.attributes(", + " '-exportcontents': 'test.*',", + " '-removeheaders': 'Bnd-LastModified,Bundle-Name,Created-By,Tool,Private-Package',", + " 'Bundle-SymbolicName': 'test'", + " )", + " classifier 'custom'", + "}", + "osgiBndManifest { mergeWithExisting true }" + ); + + testCase(buildScript, expectedMerge, "customJar"); + } + private void testCase(String buildscriptAddendum, String expectedManifest) throws IOException { + testCase(buildscriptAddendum, expectedManifest, "jar"); + } + + private void testCase(String buildscriptAddendum, String expectedManifest, String task) throws IOException { write("build.gradle", "plugins {", " id 'java'", @@ -98,7 +138,7 @@ private void testCase(String buildscriptAddendum, String expectedManifest) throw " return new StringPrinter(str -> {});", " }", "}"); - gradleRunner().withArguments("jar", "--stacktrace").build(); + gradleRunner().withArguments(task, "--stacktrace", "-i").withDebug(true).build(); // make sure the jar contains the proper manifest File libsDir = file("build/libs"); From 6c4d2aab556be92e62ce24787bf80dd185c5ecb1 Mon Sep 17 00:00:00 2001 From: Juergen Schmid Date: Sun, 9 Sep 2018 18:21:25 +0200 Subject: [PATCH 2/7] spotlessApply --- .../gradle/osgi/BndManifestPlugin.java | 2 +- .../gradle/osgi/BndManifestPluginTest.java | 49 +++++++++---------- 2 files changed, 25 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java index 516236207..51270c379 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java @@ -96,7 +96,7 @@ protected void applyOnce(Project proj) { ProjectPlugin.getPlugin(proj, JavaPlugin.class); BndManifestExtension extension = proj.getExtensions().create(BndManifestExtension.NAME, BndManifestExtension.class); - proj.getGradle().getTaskGraph().whenReady( taskGraph -> { + proj.getGradle().getTaskGraph().whenReady(taskGraph -> { // use all tasks which extends Jar TaskCollection jarTasks = proj.getTasks().withType(Jar.class); diff --git a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java index f4dcd8b7f..b2158ddf9 100644 --- a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java +++ b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java @@ -74,27 +74,27 @@ public void assertMerging() throws IOException { testCase("osgiBndManifest { mergeWithExisting true }", expectedMerge); } - @Test - public void assertCustomJarTasks() throws IOException { - write("src/main/resources/META-INF/MANIFEST.MF", - "Manifest-Version: 1.0", - "Bundle-ManifestVersion: 2", - "Bundle-Name: Mock", - "Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.mock; singleton:=true", - "Bundle-Version: 1.0.0.qualifier", - "Bundle-ActivationPolicy: lazy", - "Require-Bundle: org.eclipse.core.runtime"); - String expectedMerge = StringPrinter.buildStringFromLines( - "Manifest-Version: 1.0", - "Bundle-ActivationPolicy: lazy", - "Bundle-ManifestVersion: 2", - "Bundle-SymbolicName: test", - "Bundle-Version: 0.0.0.ERRORSETVERSION", - "Export-Package: test;uses:=\"com.diffplug.common.base\";version=\"0.0.0\"", - "Import-Package: com.diffplug.common.base;version=\"[3.4,4)\"", - "Require-Bundle: org.eclipse.core.runtime", - "Require-Capability: osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\""); - String buildScript = StringPrinter.buildStringFromLines( + @Test + public void assertCustomJarTasks() throws IOException { + write("src/main/resources/META-INF/MANIFEST.MF", + "Manifest-Version: 1.0", + "Bundle-ManifestVersion: 2", + "Bundle-Name: Mock", + "Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.mock; singleton:=true", + "Bundle-Version: 1.0.0.qualifier", + "Bundle-ActivationPolicy: lazy", + "Require-Bundle: org.eclipse.core.runtime"); + String expectedMerge = StringPrinter.buildStringFromLines( + "Manifest-Version: 1.0", + "Bundle-ActivationPolicy: lazy", + "Bundle-ManifestVersion: 2", + "Bundle-SymbolicName: test", + "Bundle-Version: 0.0.0.ERRORSETVERSION", + "Export-Package: test;uses:=\"com.diffplug.common.base\";version=\"0.0.0\"", + "Import-Package: com.diffplug.common.base;version=\"[3.4,4)\"", + "Require-Bundle: org.eclipse.core.runtime", + "Require-Capability: osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\""); + String buildScript = StringPrinter.buildStringFromLines( "task customJar(type: Jar) {", " with jar", " manifest.attributes(", @@ -104,11 +104,10 @@ public void assertCustomJarTasks() throws IOException { " )", " classifier 'custom'", "}", - "osgiBndManifest { mergeWithExisting true }" - ); + "osgiBndManifest { mergeWithExisting true }"); - testCase(buildScript, expectedMerge, "customJar"); - } + testCase(buildScript, expectedMerge, "customJar"); + } private void testCase(String buildscriptAddendum, String expectedManifest) throws IOException { testCase(buildscriptAddendum, expectedManifest, "jar"); From 259303929cae0961e390c68d36b44a5a961191c3 Mon Sep 17 00:00:00 2001 From: Juergen Schmid Date: Sun, 9 Sep 2018 18:36:26 +0200 Subject: [PATCH 3/7] add release info --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 2385aa226..dced31327 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -3,6 +3,7 @@ ### Version 3.17.0-SNAPSHOT - TBD ([javadoc](http://diffplug.github.io/goomph/javadoc/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/gradle/goomph/)) - Generated manifest is now put into the output resources directory, to make sure that it's available at runtime for development. +- Add BndManifest support for every Jar task [(#79)](https://github.com/diffplug/goomph/pull/79) ### Version 3.16.0 - August 1st 2018 ([javadoc](http://diffplug.github.io/goomph/javadoc/3.16.0/), [jcenter](https://bintray.com/diffplug/opensource/goomph/3.16.0/view)) From 9fc4b77a378f21cc57d670cb61f62411a339a288 Mon Sep 17 00:00:00 2001 From: Juergen Schmid Date: Sun, 23 Sep 2018 15:42:32 +0200 Subject: [PATCH 4/7] - preserve default behavior - added configuration properties to configure additional tasks - added a copyFromTask property --- .../gradle/osgi/BndManifestExtension.java | 29 +++++ .../gradle/osgi/BndManifestPlugin.java | 111 ++++++++++-------- .../gradle/osgi/BndManifestPluginTest.java | 5 +- 3 files changed, 94 insertions(+), 51 deletions(-) diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java index 10687b945..9886bd459 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java @@ -15,8 +15,18 @@ */ package com.diffplug.gradle.osgi; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.util.GUtil; + +import java.util.*; +import java.util.stream.Collectors; + /** Determines where the manifest is written out by {@link BndManifestPlugin}. */ public class BndManifestExtension { + public String copyFromTask = JavaPlugin.JAR_TASK_NAME; + + public void copyFromTask(String copyFromTask) { this.copyFromTask = copyFromTask; } + public Object copyTo = null; public void copyTo(Object copyTo) { @@ -29,5 +39,24 @@ public void mergeWithExisting(boolean mergeWithExisting) { this.mergeWithExisting = mergeWithExisting; } + public Set includeTasks = new HashSet<>(Collections.singletonList(JavaPlugin.JAR_TASK_NAME)); + + public void includeTask(Object task) { + includeTasks.add(task); + } + + public void includeTasks(Object... tasks) { + Collections.addAll(includeTasks, tasks); + } + + public void setIncludeTasks(Iterable includeTasks) { + this.includeTasks.clear(); + GUtil.addToCollection(this.includeTasks, includeTasks); + } + + private String print(){ + return this.includeTasks.stream().map(o -> (String)o).collect(Collectors.joining(", ")); + } + static final String NAME = "osgiBndManifest"; } diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java index 51270c379..04f52b26f 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java @@ -25,22 +25,19 @@ import java.util.*; import java.util.function.Function; +import com.diffplug.common.base.*; import org.gradle.api.Project; +import org.gradle.api.Task; import org.gradle.api.java.archives.Attributes; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.SourceSetOutput; -import org.gradle.api.tasks.TaskCollection; import org.gradle.api.tasks.bundling.Jar; import aQute.bnd.osgi.Builder; import aQute.bnd.osgi.Constants; -import com.diffplug.common.base.Errors; -import com.diffplug.common.base.Predicates; -import com.diffplug.common.base.StringPrinter; -import com.diffplug.common.base.Throwing; import com.diffplug.common.collect.ImmutableMap; import com.diffplug.gradle.FileMisc; import com.diffplug.gradle.ProjectPlugin; @@ -48,11 +45,11 @@ /** * Generates a manifest using purely bnd, and outputs it for IDE consumption. - * + * * Generating manifests by hand is a recipe for mistakes. Bnd does a fantastic * job generating all this stuff for you, but there's a lot of wiring required * to tie bnd into both Eclipse PDE and Gradle. Which is what Goomph is for! - * + * * ```groovy * apply plugin: 'com.diffplug.gradle.osgi.bndmanifest' * // Pass headers and bnd directives: http://www.aqute.biz/Bnd/Format @@ -74,65 +71,73 @@ * // By default, the existing manifest is completely ignored. * // The line below will cause the existing manifest's fields * // to be merged with the fields set by bnd. - * mergeWithExisting true + * mergeWithExisting true * } * ``` - * + * * Besides passing raw headers and bnd directives, this plugin also takes the following actions: - * + * * * Passes the project version to bnd if {@code Bundle-Version} hasn't been set explicitly. * * Replaces `-SNAPSHOT` in the version with `.IyyyyMMddkkmm` (to-the-minute timestamp). * * Passes the {@code runtime} configuration's classpath to bnd for manifest calculation. * * Instructs bnd to respect the result of the {@code processResources} task. - * + * * Many thanks to JRuyi and Agemo Cui for their excellent * [osgibnd-gradle-plugin](https://github.com/jruyi/osgibnd-gradle-plugin). * This plugin follows the template set by their plugin, but with fewer automagic * features and tighter integrations with IDEs and gradle's resources pipeline. */ public class BndManifestPlugin extends ProjectPlugin { - @Override - protected void applyOnce(Project proj) { - ProjectPlugin.getPlugin(proj, JavaPlugin.class); - BndManifestExtension extension = proj.getExtensions().create(BndManifestExtension.NAME, BndManifestExtension.class); - - proj.getGradle().getTaskGraph().whenReady(taskGraph -> { - - // use all tasks which extends Jar - TaskCollection jarTasks = proj.getTasks().withType(Jar.class); - // at the end of the jar, modify the manifest, and possibly write it to `osgiBndManifest { bndManifestcopyTo }`. - jarTasks.forEach(jarTask -> jarTask.doLast(unused -> { - Errors.rethrow().run(() -> { - byte[] manifest = getManifestContent(jarTask, extension).getBytes(StandardCharsets.UTF_8); - // modify the jar - Map> toModify = ImmutableMap.of("META-INF/MANIFEST.MF", in -> manifest); - ZipMisc.modify(jarTask.getArchivePath(), toModify, Predicates.alwaysFalse()); - // write manifest to the output resources directory - Throwing.Consumer writeManifest = path -> { - if (Files.exists(path)) { - if (Arrays.equals(Files.readAllBytes(path), manifest)) { - return; + @Override + protected void applyOnce(Project proj) { + ProjectPlugin.getPlugin(proj, JavaPlugin.class); + BndManifestExtension extension = proj.getExtensions().create(BndManifestExtension.NAME, BndManifestExtension.class); + + proj.afterEvaluate(project -> { + + // copyFromTask must be configured if copyTo is used + Preconditions.checkArgument(extension.copyTo == null || extension.copyFromTask != null, + "copyFromTask can not be null if copyTo is set. Please provide a source task."); + + final Jar copyFromTask = (extension.copyFromTask == null) ? null : getAsJar(proj, extension.copyFromTask); + + extension.includeTasks.forEach(name -> { + + Jar jarTask = getAsJar(proj, (String) name); + + // at the end of the jar, modify the manifest + jarTask.doLast(unused -> { + Errors.rethrow().run(() -> { + byte[] manifest = getManifestContent(jarTask, extension).getBytes(StandardCharsets.UTF_8); + // modify the jar + Map> toModify = ImmutableMap.of("META-INF/MANIFEST.MF", in -> manifest); + ZipMisc.modify(jarTask.getArchivePath(), toModify, Predicates.alwaysFalse()); + // write manifest to the output resources directory + Throwing.Consumer writeManifest = path -> { + if (Files.exists(path)) { + if (Arrays.equals(Files.readAllBytes(path), manifest)) { + return; + } } + Files.createDirectories(path.getParent()); + Files.write(path, manifest); + }; + writeManifest.accept(outputManifest(jarTask)); + + // and maybe write it to `osgiBndManifest { copyTo }`. + if (extension.copyTo != null && jarTask.equals(copyFromTask)) { + writeManifest.accept(jarTask.getProject().file(extension.copyTo).toPath()); } - Files.createDirectories(path.getParent()); - Files.write(path, manifest); - }; - writeManifest.accept(outputManifest(jarTask)); - // and the jarTask, maybe - if (extension.copyTo != null) { - writeManifest.accept(jarTask.getProject().file(extension.copyTo).toPath()); - } + }); }); - })); - }); + }); - proj.afterEvaluate(project -> { - // find the file that the user would like us to copy to (if any) - if (extension.copyTo != null) { - proj.getTasks().withType(Jar.class).forEach(jarTask -> jarTask.getOutputs().file(extension.copyTo)); - } - }); - } + // find the file that the user would like us to copy to (if any) + if (extension.copyTo != null && copyFromTask != null) { + copyFromTask.getOutputs().file(extension.copyTo); + } + }); + } private static Path outputManifest(Jar jarTask) { JavaPluginConvention javaConvention = jarTask.getProject().getConvention().getPlugin(JavaPluginConvention.class); @@ -145,7 +150,7 @@ private static String getManifestContent(Jar jarTask, BndManifestExtension exten if (!extension.mergeWithExisting) { Files.deleteIfExists(outputManifest(jarTask)); } - // take the bnd action + // take the bnd action return BndManifestPlugin.takeBndAction(jarTask.getProject(), jarTask, jar -> { return StringPrinter.buildString(printer -> { try (OutputStream output = printer.toOutputStream(StandardCharsets.UTF_8)) { @@ -217,4 +222,10 @@ private static String dateQualifier() { SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddkkmm"); return dateFormat.format(new Date()); } + + private static Jar getAsJar(Project project, String taskName) { + Task task = project.getTasks().getByName(taskName); + Preconditions.checkArgument(task instanceof Jar, "Task " + taskName + " must be a Jar derived task for generating BndManifest"); + return (Jar)task; + } } diff --git a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java index b2158ddf9..314cedeaa 100644 --- a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java +++ b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java @@ -104,7 +104,10 @@ public void assertCustomJarTasks() throws IOException { " )", " classifier 'custom'", "}", - "osgiBndManifest { mergeWithExisting true }"); + "osgiBndManifest { ", + "mergeWithExisting true", + "includeTask 'customJar'", + "}"); testCase(buildScript, expectedMerge, "customJar"); } From 3d471bf872e5bf72685278f18652ceee260bc2e9 Mon Sep 17 00:00:00 2001 From: Juergen Schmid Date: Sun, 23 Sep 2018 15:57:43 +0200 Subject: [PATCH 5/7] allow copyFromTask only if is within includeTasks --- src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java index 04f52b26f..c560e0a56 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java @@ -101,6 +101,9 @@ protected void applyOnce(Project proj) { final Jar copyFromTask = (extension.copyFromTask == null) ? null : getAsJar(proj, extension.copyFromTask); + Preconditions.checkArgument(extension.copyFromTask == null || extension.includeTasks.contains(extension.copyFromTask), + "copyFromTask must reside within includeTask"); + extension.includeTasks.forEach(name -> { Jar jarTask = getAsJar(proj, (String) name); From 577394b8650253076845485f2fed842c5953c4ed Mon Sep 17 00:00:00 2001 From: Juergen Schmid Date: Sun, 23 Sep 2018 16:05:02 +0200 Subject: [PATCH 6/7] applied spotless --- .../gradle/osgi/BndManifestExtension.java | 14 +++++---- .../gradle/osgi/BndManifestPlugin.java | 30 +++++++++---------- .../gradle/osgi/BndManifestPluginTest.java | 4 +-- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java index 9886bd459..0e1ec9d97 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java @@ -15,17 +15,19 @@ */ package com.diffplug.gradle.osgi; -import org.gradle.api.plugins.JavaPlugin; -import org.gradle.util.GUtil; - import java.util.*; import java.util.stream.Collectors; +import org.gradle.api.plugins.JavaPlugin; +import org.gradle.util.GUtil; + /** Determines where the manifest is written out by {@link BndManifestPlugin}. */ public class BndManifestExtension { public String copyFromTask = JavaPlugin.JAR_TASK_NAME; - public void copyFromTask(String copyFromTask) { this.copyFromTask = copyFromTask; } + public void copyFromTask(String copyFromTask) { + this.copyFromTask = copyFromTask; + } public Object copyTo = null; @@ -54,8 +56,8 @@ public void setIncludeTasks(Iterable includeTasks) { GUtil.addToCollection(this.includeTasks, includeTasks); } - private String print(){ - return this.includeTasks.stream().map(o -> (String)o).collect(Collectors.joining(", ")); + private String print() { + return this.includeTasks.stream().map(o -> (String) o).collect(Collectors.joining(", ")); } static final String NAME = "osgiBndManifest"; diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java index c560e0a56..1e03ec229 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java @@ -25,7 +25,6 @@ import java.util.*; import java.util.function.Function; -import com.diffplug.common.base.*; import org.gradle.api.Project; import org.gradle.api.Task; import org.gradle.api.java.archives.Attributes; @@ -38,6 +37,7 @@ import aQute.bnd.osgi.Builder; import aQute.bnd.osgi.Constants; +import com.diffplug.common.base.*; import com.diffplug.common.collect.ImmutableMap; import com.diffplug.gradle.FileMisc; import com.diffplug.gradle.ProjectPlugin; @@ -88,12 +88,12 @@ * features and tighter integrations with IDEs and gradle's resources pipeline. */ public class BndManifestPlugin extends ProjectPlugin { - @Override - protected void applyOnce(Project proj) { - ProjectPlugin.getPlugin(proj, JavaPlugin.class); - BndManifestExtension extension = proj.getExtensions().create(BndManifestExtension.NAME, BndManifestExtension.class); + @Override + protected void applyOnce(Project proj) { + ProjectPlugin.getPlugin(proj, JavaPlugin.class); + BndManifestExtension extension = proj.getExtensions().create(BndManifestExtension.NAME, BndManifestExtension.class); - proj.afterEvaluate(project -> { + proj.afterEvaluate(project -> { // copyFromTask must be configured if copyTo is used Preconditions.checkArgument(extension.copyTo == null || extension.copyFromTask != null, @@ -102,7 +102,7 @@ protected void applyOnce(Project proj) { final Jar copyFromTask = (extension.copyFromTask == null) ? null : getAsJar(proj, extension.copyFromTask); Preconditions.checkArgument(extension.copyFromTask == null || extension.includeTasks.contains(extension.copyFromTask), - "copyFromTask must reside within includeTask"); + "copyFromTask must reside within includeTask"); extension.includeTasks.forEach(name -> { @@ -135,12 +135,12 @@ protected void applyOnce(Project proj) { }); }); - // find the file that the user would like us to copy to (if any) - if (extension.copyTo != null && copyFromTask != null) { - copyFromTask.getOutputs().file(extension.copyTo); - } - }); - } + // find the file that the user would like us to copy to (if any) + if (extension.copyTo != null && copyFromTask != null) { + copyFromTask.getOutputs().file(extension.copyTo); + } + }); + } private static Path outputManifest(Jar jarTask) { JavaPluginConvention javaConvention = jarTask.getProject().getConvention().getPlugin(JavaPluginConvention.class); @@ -228,7 +228,7 @@ private static String dateQualifier() { private static Jar getAsJar(Project project, String taskName) { Task task = project.getTasks().getByName(taskName); - Preconditions.checkArgument(task instanceof Jar, "Task " + taskName + " must be a Jar derived task for generating BndManifest"); - return (Jar)task; + Preconditions.checkArgument(task instanceof Jar, "Task " + taskName + " must be a Jar derived task for generating BndManifest"); + return (Jar) task; } } diff --git a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java index 40b39d450..3013e9612 100644 --- a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java +++ b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java @@ -105,8 +105,8 @@ public void assertCustomJarTasks() throws IOException { " classifier 'custom'", "}", "osgiBndManifest { ", - "mergeWithExisting true", - "includeTask 'customJar'", + "mergeWithExisting true", + "includeTask 'customJar'", "}"); testCase(buildScript, expectedMerge, "customJar"); From 507798e75afe3d7d9c64d40e65d7bed7b6d5e4f8 Mon Sep 17 00:00:00 2001 From: Juergen Schmid Date: Wed, 3 Oct 2018 16:59:35 +0200 Subject: [PATCH 7/7] added tests for including jar task fixed review findings --- .../gradle/osgi/BndManifestExtension.java | 5 -- .../gradle/osgi/BndManifestPlugin.java | 2 +- .../gradle/osgi/BndManifestPluginTest.java | 69 +++++++++++++++++-- 3 files changed, 66 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java index 0e1ec9d97..8ba819022 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestExtension.java @@ -16,7 +16,6 @@ package com.diffplug.gradle.osgi; import java.util.*; -import java.util.stream.Collectors; import org.gradle.api.plugins.JavaPlugin; import org.gradle.util.GUtil; @@ -56,9 +55,5 @@ public void setIncludeTasks(Iterable includeTasks) { GUtil.addToCollection(this.includeTasks, includeTasks); } - private String print() { - return this.includeTasks.stream().map(o -> (String) o).collect(Collectors.joining(", ")); - } - static final String NAME = "osgiBndManifest"; } diff --git a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java index 1e03ec229..766765d16 100644 --- a/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java +++ b/src/main/java/com/diffplug/gradle/osgi/BndManifestPlugin.java @@ -184,7 +184,7 @@ private static String takeBndAction(Project project, Jar jarTask, Throwing.Funct JavaPluginConvention javaConvention = project.getConvention().getPlugin(JavaPluginConvention.class); SourceSetOutput main = javaConvention.getSourceSets().getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput(); // delete empty folders so that bnd doesn't make Export-Package entries for them - Set includeresource = new HashSet<>(); + Set includeresource = new LinkedHashSet<>(); deleteEmptyFoldersIfExists(main.getResourcesDir()); includeresource.add(fix(main.getResourcesDir())); for (File file : main.getClassesDirs()) { diff --git a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java index 3013e9612..e4a344309 100644 --- a/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java +++ b/src/test/java/com/diffplug/gradle/osgi/BndManifestPluginTest.java @@ -75,7 +75,7 @@ public void assertMerging() throws IOException { } @Test - public void assertCustomJarTasks() throws IOException { + public void assertCustomJarTask() throws IOException { write("src/main/resources/META-INF/MANIFEST.MF", "Manifest-Version: 1.0", "Bundle-ManifestVersion: 2", @@ -105,13 +105,74 @@ public void assertCustomJarTasks() throws IOException { " classifier 'custom'", "}", "osgiBndManifest { ", - "mergeWithExisting true", - "includeTask 'customJar'", + " mergeWithExisting true", + " includeTask 'customJar'", "}"); testCase(buildScript, expectedMerge, "customJar"); } + @Test + public void assertCustomJarOnly() throws IOException { + write("src/main/resources/META-INF/MANIFEST.MF", + "Manifest-Version: 1.0", + "Bundle-ManifestVersion: 2", + "Bundle-Name: Mock", + "Bundle-SymbolicName: org.eclipse.e4.demo.e4photo.flickr.mock; singleton:=true", + "Bundle-Version: 1.0.0.qualifier", + "Bundle-ActivationPolicy: lazy", + "Require-Bundle: org.eclipse.core.runtime"); + + String expected = StringPrinter.buildStringFromLines( + "Manifest-Version: 1.0", + "Bundle-ActivationPolicy: lazy", + "Bundle-ManifestVersion: 2", + "Bundle-SymbolicName: test", + "Bundle-Version: 0.0.0.ERRORSETVERSION", + "Export-Package: test;uses:=\"com.diffplug.common.base\";version=\"0.0.0\"", + "Import-Package: com.diffplug.common.base;version=\"[3.4,4)\"", + "Require-Bundle: org.eclipse.core.runtime", + "Require-Capability: osgi.ee;filter:=\"(&(osgi.ee=JavaSE)(version=1.8))\""); + + String buildscriptAddendum = StringPrinter.buildStringFromLines( + "task customJar(type: Jar) {", + " with jar", + " manifest.attributes(", + " '-exportcontents': 'test.*',", + " '-removeheaders': 'Bnd-LastModified,Bundle-Name,Created-By,Tool,Private-Package',", + " 'Bundle-SymbolicName': 'test'", + " )", + " classifier 'custom'", + "}", + "osgiBndManifest { ", + " copyFromTask 'customJar'", + " mergeWithExisting true", + " includeTasks = ['customJar']", + "}"); + + testCase(buildscriptAddendum, expected, "customJar"); + } + + @Test + public void assertCustomJarExcluded() throws IOException { + String expected = StringPrinter.buildStringFromLines( + "Manifest-Version: 1.0", + ""); + + write("src/main/resources/META-INF/MANIFEST.MF", + "Manifest-Version: 1.0"); + + String buildscriptAddendum = StringPrinter.buildStringFromLines( + "task customJar(type: Jar) {", + " classifier 'custom'", + "}", + "osgiBndManifest { ", + " mergeWithExisting true", + "}"); + + testCase(buildscriptAddendum, expected, "customJar"); + } + private void testCase(String buildscriptAddendum, String expectedManifest) throws IOException { testCase(buildscriptAddendum, expectedManifest, "jar"); } @@ -140,7 +201,7 @@ private void testCase(String buildscriptAddendum, String expectedManifest, Strin " return new StringPrinter(str -> {});", " }", "}"); - gradleRunner().withArguments(task, "--stacktrace", "-i").build(); + gradleRunner().withArguments(task, "--stacktrace").build(); // make sure the jar contains the proper manifest File libsDir = file("build/libs");