diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java index 9520a06943..df09d6121c 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/main/java/aQute/bnd/gradle/BundleTaskExtension.java @@ -8,7 +8,6 @@ import static aQute.bnd.gradle.BndUtils.unwrap; import static aQute.bnd.gradle.BndUtils.unwrapFile; import static aQute.bnd.gradle.BndUtils.unwrapFileOptional; -import static aQute.bnd.gradle.BndUtils.unwrapOptional; import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; import static java.util.stream.Collectors.toList; @@ -29,6 +28,17 @@ import java.util.jar.Manifest; import java.util.zip.ZipFile; +import aQute.bnd.exceptions.Exceptions; +import aQute.bnd.osgi.Builder; +import aQute.bnd.osgi.Constants; +import aQute.bnd.osgi.Jar; +import aQute.bnd.osgi.Processor; +import aQute.bnd.stream.MapStream; +import aQute.bnd.unmodifiable.Maps; +import aQute.bnd.version.MavenVersion; +import aQute.lib.io.IO; +import aQute.lib.strings.Strings; +import aQute.lib.utf8properties.UTF8Properties; import org.gradle.api.Action; import org.gradle.api.GradleException; import org.gradle.api.Project; @@ -52,18 +62,6 @@ import org.gradle.api.tasks.TaskInputFilePropertyBuilder; import org.gradle.work.NormalizeLineEndings; -import aQute.bnd.exceptions.Exceptions; -import aQute.bnd.osgi.Builder; -import aQute.bnd.osgi.Constants; -import aQute.bnd.osgi.Jar; -import aQute.bnd.osgi.Processor; -import aQute.bnd.stream.MapStream; -import aQute.bnd.unmodifiable.Maps; -import aQute.bnd.version.MavenVersion; -import aQute.lib.io.IO; -import aQute.lib.strings.Strings; -import aQute.lib.utf8properties.UTF8Properties; - /** * BundleTaskExtension for Gradle. *

@@ -96,6 +94,8 @@ public class BundleTaskExtension { private final ConfigurableFileCollection classpath; private final Provider bnd; private final MapProperty properties; + private final Provider defaultBundleSymbolicName; + private final Provider defaultBundleVersion; /** * The bndfile property. @@ -131,7 +131,7 @@ public ConfigurableFileCollection getClasspath() { * If the bndfile property points an existing file, this property is * ignored. Otherwise, the bnd instructions in this property will be used. * - * @return The property for the bnd instructions. + * @return The provider for the bnd instructions. */ @Input @org.gradle.api.tasks.Optional @@ -211,6 +211,13 @@ public BundleTaskExtension(org.gradle.api.tasks.bundling.Jar task) { classpath(mainSourceSet.getCompileClasspath()); properties = objects.mapProperty(String.class, Object.class) .convention(Maps.of("project", "__convention__")); + defaultBundleSymbolicName = task.getArchiveBaseName() + .zip(task.getArchiveClassifier(), (baseName, classifier) -> classifier.isEmpty() ? baseName : baseName + "-" + classifier); + defaultBundleVersion = task.getArchiveVersion() + .orElse("0") + .map(version -> MavenVersion.parseMavenString(version) + .getOSGiVersion() + .toString()); // need to programmatically add to inputs since @InputFiles in a // extension is not processed task.getInputs() @@ -229,6 +236,10 @@ public BundleTaskExtension(org.gradle.api.tasks.bundling.Jar task) { .property("bnd", getBnd()); task.getInputs() .property("properties", getProperties()); + task.getInputs() + .property("default Bundle-SymbolicName", getDefaultBundleSymbolicName()); + task.getInputs() + .property("default Bundle-Version", getDefaultBundleVersion()); } /** @@ -331,6 +342,30 @@ File getBuildFile() { return buildFile; } + /** + * The default value for the Bundle-SymbolicName manifest header. + *

+ * If the Bundle-SymbolicName manifest header is not set in the bnd instructions, + * the value of this provider will be used. + * + * @return The provider for the default Bundle-SymbolicName manifest header. + */ + Provider getDefaultBundleSymbolicName() { + return defaultBundleSymbolicName; + } + + /** + * The default value for the Bundle-Version manifest header. + *

+ * If the Bundle-Version manifest header is not set in the bnd instructions, + * the value of this provider will be used. + * + * @return The provider for the default Bundle-Version manifest header. + */ + Provider getDefaultBundleVersion() { + return defaultBundleVersion; + } + ProjectLayout getLayout() { return layout; } @@ -374,7 +409,7 @@ public void execute(Task t) { .ofNullable(manifest.getEffectiveManifest() .getAttributes()) .filterKey(key -> !Objects.equals(key, "Manifest-Version")) - .mapValue(Object::toString) + .mapValue(this::unwrapAttributeValue) .collect(MapStream.toMap((k1, k2) -> { throw new IllegalStateException("Duplicate key " + k1); }, UTF8Properties::new))); @@ -412,9 +447,6 @@ public void execute(Task t) { } File archiveFile = unwrapFile(getTask().getArchiveFile()); String archiveFileName = unwrap(getTask().getArchiveFileName()); - String archiveBaseName = unwrap(getTask().getArchiveBaseName()); - String archiveClassifier = unwrap(getTask().getArchiveClassifier()); - String archiveVersion = unwrapOptional(getTask().getArchiveVersion()).orElse(null); // Include entire contents of Jar task generated jar // (except the manifest) @@ -472,22 +504,18 @@ public void execute(Task t) { .toArray(new File[0])); getTask().getLogger() .debug("builder sourcepath: {}", builder.getSourcePath()); - // set bundle symbolic name from tasks's archiveBaseName - // property if necessary + // set bundle symbolic name if necessary String bundleSymbolicName = builder.getProperty(Constants.BUNDLE_SYMBOLICNAME); if (isEmpty(bundleSymbolicName)) { - bundleSymbolicName = archiveClassifier.isEmpty() ? archiveBaseName - : archiveBaseName + "-" + archiveClassifier; + bundleSymbolicName = unwrap(getDefaultBundleSymbolicName()); builder.setProperty(Constants.BUNDLE_SYMBOLICNAME, bundleSymbolicName); } - // set bundle version from task's archiveVersion if - // necessary + // set bundle version if necessary String bundleVersion = builder.getProperty(Constants.BUNDLE_VERSION); if (isEmpty(bundleVersion)) { - builder.setProperty(Constants.BUNDLE_VERSION, MavenVersion.parseMavenString(archiveVersion) - .getOSGiVersion() - .toString()); + bundleVersion = unwrap(getDefaultBundleVersion()); + builder.setProperty(Constants.BUNDLE_VERSION, bundleVersion); } getTask().getLogger() @@ -532,6 +560,16 @@ private org.gradle.api.java.archives.Manifest mergeManifest(Manifest builtManife return mergeManifest; } + private String unwrapAttributeValue(Object value) { + while (value instanceof Provider) { + value = ((Provider) value).getOrNull(); + } + if (value == null) { + return null; + } + return value.toString(); + } + private void failTask(String msg, File archiveFile) { IO.delete(archiveFile); throw new GradleException(msg); diff --git a/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBundlePlugin.groovy b/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBundlePlugin.groovy index 2ef48f9a16..ab81e4faf2 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBundlePlugin.groovy +++ b/gradle-plugins/biz.aQute.bnd.gradle/src/test/groovy/aQute/bnd/gradle/TestBundlePlugin.groovy @@ -147,17 +147,19 @@ class TestBundlePlugin extends Specification { result.task(":bundle").outcome == SUCCESS result.task(":jar").outcome == SUCCESS - File jartask_result = new File(testProjectBuildDir, "libs/${testProject}-1.0.0.jar") + File jartask_result = new File(testProjectBuildDir, "libs/${testProject}.jar") jartask_result.isFile() JarFile jartask_jar = new JarFile(jartask_result) Attributes jartask_manifest = jartask_jar.getManifest().getMainAttributes() - File bundletask_bundle = new File(testProjectBuildDir, "libs/${testProject}-1.0.0-bundle.jar") + File bundletask_bundle = new File(testProjectBuildDir, "libs/${testProject}-bundle.jar") bundletask_bundle.isFile() JarFile bundletask_jar = new JarFile(bundletask_bundle) Attributes bundletask_manifest = bundletask_jar.getManifest().getMainAttributes() jartask_manifest.getValue("XX-Signed") == "true" + bundletask_manifest.getValue("Bundle-SymbolicName") == "${testProject}-bundle" + bundletask_manifest.getValue("Bundle-Version") == "0.0.0" bundletask_manifest.getValue("XX-Signed") == "true" bundletask_manifest.getValue("YY-Sealed") == "true" bundletask_manifest.getValue("ZZ-Delivered") == "true" diff --git a/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin1/build.gradle b/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin1/build.gradle index 91b5f30354..9f9e130675 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin1/build.gradle +++ b/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin1/build.gradle @@ -25,7 +25,7 @@ dependencies { jar { ext.taskprop = 'prop.task' manifest { - attributes('Implementation-Title': project.archivesBaseName, + attributes('Implementation-Title': providers.provider({ -> project.archivesBaseName}), 'Implementation-Version': project.version, '-includeresource': '{${.}/bar.txt}', '-include': '${.}/other.bnd', diff --git a/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin2/build.gradle b/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin2/build.gradle index 0476a1e248..659acfd0b8 100644 --- a/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin2/build.gradle +++ b/gradle-plugins/biz.aQute.bnd.gradle/testresources/builderplugin2/build.gradle @@ -10,7 +10,6 @@ plugins { } group = 'test.bnd.gradle' -version = '1.0.0' repositories { mavenCentral() @@ -19,7 +18,6 @@ repositories { ext { extraInstructions = provider { '''\ -YY-Sealed: true ZZ-Delivered: true ''' } @@ -28,7 +26,7 @@ ZZ-Delivered: true // Not a bundle. def jarTask = tasks.named('jar', Jar) { manifest { - attributes('XX-Signed': true) + attributes('XX-Signed': provider({true})) } } @@ -37,6 +35,9 @@ task bundle(type: Bundle) { group = 'build' from jarTask.map { zipTree(it.archiveFile) } archiveClassifier = 'bundle' + manifest { + attributes('YY-Sealed': provider({true})) + } bundle { bnd = jarTask.flatMap { jar -> @@ -44,9 +45,9 @@ task bundle(type: Bundle) { "-include: jar:${file.asFile.toURI()}!/META-INF/MANIFEST.MF" } } - + bnd extraInstructions - + bnd ''' Bundle-Name: ${project.group}:${task.archiveBaseName}-${task.archiveClassifier} '''