Skip to content

Commit

Permalink
Merge pull request #5280 from bjhargrave/issues/5279
Browse files Browse the repository at this point in the history
gradle: Make default Bundle-SymbolicName and Bundle-Version inputs
  • Loading branch information
bjhargrave committed Jun 14, 2022
2 parents b09493d + 8874576 commit 017248d
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 35 deletions.
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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.
* <p>
Expand Down Expand Up @@ -96,6 +94,8 @@ public class BundleTaskExtension {
private final ConfigurableFileCollection classpath;
private final Provider<String> bnd;
private final MapProperty<String, Object> properties;
private final Provider<String> defaultBundleSymbolicName;
private final Provider<String> defaultBundleVersion;

/**
* The bndfile property.
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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());
}

/**
Expand Down Expand Up @@ -331,6 +342,30 @@ File getBuildFile() {
return buildFile;
}

/**
* The default value for the Bundle-SymbolicName manifest header.
* <p>
* 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<String> getDefaultBundleSymbolicName() {
return defaultBundleSymbolicName;
}

/**
* The default value for the Bundle-Version manifest header.
* <p>
* 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<String> getDefaultBundleVersion() {
return defaultBundleVersion;
}

ProjectLayout getLayout() {
return layout;
}
Expand Down Expand Up @@ -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)));
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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);
Expand Down
Expand Up @@ -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"
Expand Down
Expand Up @@ -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',
Expand Down
Expand Up @@ -10,7 +10,6 @@ plugins {
}

group = 'test.bnd.gradle'
version = '1.0.0'

repositories {
mavenCentral()
Expand All @@ -19,7 +18,6 @@ repositories {
ext {
extraInstructions = provider {
'''\
YY-Sealed: true
ZZ-Delivered: true
'''
}
Expand All @@ -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}))
}
}

Expand All @@ -37,16 +35,19 @@ 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 ->
jar.archiveFile.map { file ->
"-include: jar:${file.asFile.toURI()}!/META-INF/MANIFEST.MF"
}
}

bnd extraInstructions

bnd '''
Bundle-Name: ${project.group}:${task.archiveBaseName}-${task.archiveClassifier}
'''
Expand Down

0 comments on commit 017248d

Please sign in to comment.