From 2fcedecf38bf6244b911d486a6d8abd8c19ce5d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Tue, 15 Aug 2023 13:00:37 +0200 Subject: [PATCH] Support changing of version in pde.bnd files Currently the set-version mojo does not support updating the pde.bnd file, this now adds support for updating pde.bnd files in similar fashion like MANIFEST.MF Fix https://github.com/eclipse-tycho/tycho/issues/2706 --- .../set-version/pde-bnd/.mvn/extensions.xml | 7 ++ .../set-version/pde-bnd/bundle/pde.bnd | 4 + .../set-version/pde-bnd/pom.xml | 24 ++++ .../update-eclipse-metadata/pde-bnd/pde.bnd | 4 + .../update-eclipse-metadata/pde-bnd/pom.xml | 22 ++++ .../TychoVersionsPluginTest.java | 35 +++++- .../tycho/versions/bundle/BndLine.java | 68 ++++++++++ .../tycho/versions/bundle/MutableBndFile.java | 118 ++++++++++++++++++ .../bundle/MutableBundleManifest.java | 12 +- .../tycho/versions/engine/VersionUpdater.java | 19 ++- .../BundleManifestManipulator.java | 102 +++++++++++++-- .../bundle/tests/MutableBndFileTest.java | 57 +++++++++ .../src/test/resources/bnds/linebreak.bnd | 5 + 13 files changed, 455 insertions(+), 22 deletions(-) create mode 100644 tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/.mvn/extensions.xml create mode 100644 tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/bundle/pde.bnd create mode 100644 tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/pom.xml create mode 100644 tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pde.bnd create mode 100644 tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pom.xml create mode 100644 tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/BndLine.java create mode 100644 tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBndFile.java create mode 100644 tycho-versions-plugin/src/test/java/org/eclipse/tycho/versions/bundle/tests/MutableBndFileTest.java create mode 100644 tycho-versions-plugin/src/test/resources/bnds/linebreak.bnd diff --git a/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/.mvn/extensions.xml b/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/.mvn/extensions.xml new file mode 100644 index 0000000000..79a6c51e8d --- /dev/null +++ b/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/.mvn/extensions.xml @@ -0,0 +1,7 @@ + + + org.eclipse.tycho + tycho-build + ${tycho-version} + + diff --git a/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/bundle/pde.bnd b/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/bundle/pde.bnd new file mode 100644 index 0000000000..7b5bdff6c2 --- /dev/null +++ b/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/bundle/pde.bnd @@ -0,0 +1,4 @@ +Bundle-Name: Bnd +Bundle-SymbolicName: pde.bnd +Bundle-Vendor: +Bundle-Version: 1.0.0 \ No newline at end of file diff --git a/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/pom.xml b/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/pom.xml new file mode 100644 index 0000000000..03e6d68072 --- /dev/null +++ b/tycho-its/projects/tycho-version-plugin/set-version/pde-bnd/pom.xml @@ -0,0 +1,24 @@ + + + 4.0.0 + + org.eclipse.tycho.its + pde-parent + 1.0.0 + pom + + bundle + + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + + diff --git a/tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pde.bnd b/tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pde.bnd new file mode 100644 index 0000000000..7b5bdff6c2 --- /dev/null +++ b/tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pde.bnd @@ -0,0 +1,4 @@ +Bundle-Name: Bnd +Bundle-SymbolicName: pde.bnd +Bundle-Vendor: +Bundle-Version: 1.0.0 \ No newline at end of file diff --git a/tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pom.xml b/tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pom.xml new file mode 100644 index 0000000000..213378f216 --- /dev/null +++ b/tycho-its/projects/tycho-version-plugin/update-eclipse-metadata/pde-bnd/pom.xml @@ -0,0 +1,22 @@ + + + 4.0.0 + org.eclipse.tycho.its + pde.bnd + 2.0.0-SNAPSHOT + eclipse-plugin + PDE-BND Bundle + + + + org.eclipse.tycho + tycho-maven-plugin + ${tycho-version} + true + + + + \ No newline at end of file diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java index dee0dc6097..40d6f407bf 100644 --- a/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java +++ b/tycho-its/src/test/java/org/eclipse/tycho/test/versionsplugin/TychoVersionsPluginTest.java @@ -13,12 +13,14 @@ package org.eclipse.tycho.test.versionsplugin; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import java.io.File; import java.io.FileReader; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Properties; import org.apache.maven.it.Verifier; import org.apache.maven.model.Model; @@ -29,7 +31,7 @@ public class TychoVersionsPluginTest extends AbstractTychoIntegrationTest { - private final String VERSION = TychoVersion.getTychoVersion(); + private static final String VERSION = TychoVersion.getTychoVersion(); /** *

@@ -80,6 +82,37 @@ public void updateTargetVersionTest() throws Exception { && targetContent.contains("sequenceNumber=\"12\"")); } + @Test + public void updateProjectVersionBndTest() throws Exception { + String expectedNewVersion = "1.2.3"; + + Verifier verifier = getVerifier("tycho-version-plugin/set-version/pde-bnd", true); + + verifier.addCliOption("-DnewVersion=" + expectedNewVersion); + verifier.executeGoal("org.eclipse.tycho:tycho-versions-plugin:" + VERSION + ":set-version"); + + verifier.verifyErrorFreeLog(); + Properties properties = new Properties(); + properties.load(Files.newInputStream(new File(verifier.getBasedir(), "bundle/pde.bnd").toPath())); + String versionProperty = properties.getProperty("Bundle-Version"); + assertNotNull("Bundle-Version is null", versionProperty); + assertEquals("Bundle-Version is not as expected!", expectedNewVersion, versionProperty); + } + + @Test + public void updateProjectMetadataVersionBndTest() throws Exception { + String expectedNewVersion = "2.0.0.qualifier"; + + Verifier verifier = getVerifier("tycho-version-plugin/update-eclipse-metadata/pde-bnd", false, false); + verifier.executeGoal("org.eclipse.tycho:tycho-versions-plugin:" + VERSION + ":update-eclipse-metadata"); + verifier.verifyErrorFreeLog(); + Properties properties = new Properties(); + properties.load(Files.newInputStream(new File(verifier.getBasedir(), "pde.bnd").toPath())); + String versionProperty = properties.getProperty("Bundle-Version"); + assertNotNull("Bundle-Version is null", versionProperty); + assertEquals("Bundle-Version is not as expected!", expectedNewVersion, versionProperty); + } + /** * Verifies that the update-pom goal of the tycho-version plug-in updates the * version of a pom when the pom file is implicit. The command line for this diff --git a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/BndLine.java b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/BndLine.java new file mode 100644 index 0000000000..ff5de6bfa2 --- /dev/null +++ b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/BndLine.java @@ -0,0 +1,68 @@ +/******************************************************************************* + * Copyright (c) 2023 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.versions.bundle; + +import java.io.IOException; +import java.io.StringReader; +import java.util.Properties; +import java.util.Set; + +class BndLine { + + String eol; + String rawstring; + BndLine nextline; + String key; + String value; + String newValue; + + boolean isContinuation() { + return rawstring.strip().endsWith("\\"); + } + + void parse() { + Properties properties = new Properties(); + String collect = collect(); + try { + properties.load(new StringReader(collect)); + } catch (IOException e) { + throw new AssertionError("I/O error while reading a string!", e); + } + Set names = properties.stringPropertyNames(); + if (names.isEmpty()) { + return; + } + if (names.size() == 1) { + this.key = names.iterator().next(); + this.value = properties.getProperty(key); + return; + } + throw new AssertionError("Line yields more than one property: " + collect); + } + + String collect() { + if (nextline == null) { + return rawstring; + } + return rawstring + nextline.collect(); + } + + @Override + public String toString() { + if (key == null) { + return collect(); + } + return key + ": " + value; + } + +} diff --git a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBndFile.java b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBndFile.java new file mode 100644 index 0000000000..2dc829ee12 --- /dev/null +++ b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBndFile.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2023 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.tycho.versions.bundle; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PushbackReader; +import java.io.Writer; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +public class MutableBndFile { + + private final List bndLines = new ArrayList(); + + public void setValue(String key, String value) { + if (key == null) { + return; + } + for (BndLine bndLine : bndLines) { + if (Objects.equals(key, bndLine.key)) { + bndLine.newValue = value; + return; + } + } + } + + public String getValue(String key) { + if (key == null) { + return null; + } + for (BndLine bndLine : bndLines) { + if (Objects.equals(key, bndLine.key)) { + if (bndLine.newValue != null) { + return bndLine.newValue; + } + return bndLine.value; + } + } + return null; + } + + public void write(File bndFile) throws IOException { + try (BufferedWriter writer = Files.newBufferedWriter(bndFile.toPath())) { + write(writer); + } + } + + public void write(Writer writer) throws IOException { + for (BndLine bndLine : bndLines) { + if (bndLine.newValue == null || bndLine.key == null) { + writer.write(bndLine.collect()); + } else { + String value = bndLine.value; + if (value == null) { + writer.write(bndLine.collect() + bndLine.newValue); + } else { + writer.write(bndLine.collect().replace(value, bndLine.newValue)); + } + } + } + } + + public static MutableBndFile read(File file) throws IOException { + try (InputStream is = new FileInputStream(file)) { + return read(is); + } + } + + public static MutableBndFile read(InputStream is) throws IOException { + PushbackReader pushbackReader = new PushbackReader( + new BufferedReader(new InputStreamReader(new BufferedInputStream(is), StandardCharsets.UTF_8)), 1); + MutableBndFile bndFile = new MutableBndFile(); + BndLine line; + BndLine last = null; + while ((line = readLine(pushbackReader)) != null) { + if (last != null && last.isContinuation()) { + last.nextline = line; + } else { + bndFile.bndLines.add(line); + } + last = line; + } + bndFile.bndLines.forEach(BndLine::parse); + return bndFile; + + } + + private static BndLine readLine(PushbackReader reader) throws IOException { + BndLine bndLine = new BndLine(); + String str = MutableBundleManifest.readLineWithLineEnding(reader, lineEnding -> bndLine.eol = lineEnding); + if (str == null) { + return null; + } + bndLine.rawstring = str; + return bndLine; + } + +} diff --git a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBundleManifest.java b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBundleManifest.java index 73a12883d8..e72ceaee35 100644 --- a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBundleManifest.java +++ b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/bundle/MutableBundleManifest.java @@ -33,6 +33,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.function.Consumer; import org.eclipse.osgi.util.ManifestElement; import org.eclipse.tycho.versions.engine.Versions; @@ -64,7 +65,7 @@ public static MutableBundleManifest read(InputStream is) throws IOException { ManifestAttribute curr = null; String str; - while ((str = readLineWithLineEnding(br, mf)) != null) { + while ((str = readLineWithLineEnding(br, mf::setLineEndingWhenFirstLine)) != null) { if (str.trim().isEmpty()) { break; } else if (str.charAt(0) == ' ') { @@ -90,7 +91,8 @@ public static MutableBundleManifest read(InputStream is) throws IOException { return mf; } - private static String readLineWithLineEnding(PushbackReader reader, MutableBundleManifest mf) throws IOException { + public static String readLineWithLineEnding(PushbackReader reader, Consumer lineEndingConsumer) + throws IOException { StringBuilder result = new StringBuilder(); int ch, lastch = -1; @@ -98,10 +100,10 @@ private static String readLineWithLineEnding(PushbackReader reader, MutableBundl if (lastch == '\r') { if (ch == '\n') { result.append((char) ch); - mf.setLineEndingWhenFirstLine("\r\n"); + lineEndingConsumer.accept("\r\n"); } else { reader.unread(ch); - mf.setLineEndingWhenFirstLine("\r"); + lineEndingConsumer.accept("\r"); } break; } @@ -109,7 +111,7 @@ private static String readLineWithLineEnding(PushbackReader reader, MutableBundl result.append((char) ch); if (ch == '\n' || ch == '\u2028' || ch == '\u2029' || ch == '\u0085') { // see Scanner#LINE_SEPARATOR_PATTERN - mf.setLineEndingWhenFirstLine(new String(new char[] { (char) ch })); + lineEndingConsumer.accept(new String(new char[] { (char) ch })); break; } diff --git a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/engine/VersionUpdater.java b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/engine/VersionUpdater.java index 7e1791351d..64af65d8ff 100644 --- a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/engine/VersionUpdater.java +++ b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/engine/VersionUpdater.java @@ -21,16 +21,20 @@ import java.util.Collection; import java.util.HashMap; import java.util.Map; +import java.util.jar.JarFile; import org.codehaus.plexus.component.annotations.Requirement; import org.codehaus.plexus.logging.Logger; import org.eclipse.tycho.PackagingType; +import org.eclipse.tycho.TychoConstants; import org.eclipse.tycho.model.Feature; import org.eclipse.tycho.model.IU; import org.eclipse.tycho.model.ProductConfiguration; +import org.eclipse.tycho.versions.bundle.MutableBndFile; import org.eclipse.tycho.versions.bundle.MutableBundleManifest; import org.eclipse.tycho.versions.pom.PomFile; import org.eclipse.tycho.versions.utils.ProductFileFilter; +import org.osgi.framework.Constants; /** * Update pom or Eclipse/OSGi version to make both versions consistent. @@ -53,9 +57,18 @@ private static interface VersionAdaptor { static { VersionAdaptor bundleVersionAdaptor = (project, logger) -> { - MutableBundleManifest manifest = MutableBundleManifest - .read(new File(project.getBasedir(), "META-INF/MANIFEST.MF")); - return manifest.getVersion(); + File manifestFile = new File(project.getBasedir(), JarFile.MANIFEST_NAME); + if (manifestFile.isFile()) { + MutableBundleManifest manifest = MutableBundleManifest.read(manifestFile); + return manifest.getVersion(); + } + File bndFile = new File(project.getBasedir(), TychoConstants.PDE_BND); + if (bndFile.isFile()) { + MutableBndFile mutableBndFile = MutableBndFile.read(bndFile); + return mutableBndFile.getValue(Constants.BUNDLE_VERSION); + } + throw new IllegalStateException("neither " + JarFile.MANIFEST_NAME + " nor " + TychoConstants.PDE_BND + + " file found in project " + project.getBasedir()); }; updaters.put(PackagingType.TYPE_ECLIPSE_PLUGIN, bundleVersionAdaptor); updaters.put(PackagingType.TYPE_ECLIPSE_TEST_PLUGIN, bundleVersionAdaptor); diff --git a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/BundleManifestManipulator.java b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/BundleManifestManipulator.java index e8be3824eb..72a8ff13cd 100644 --- a/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/BundleManifestManipulator.java +++ b/tycho-versions-plugin/src/main/java/org/eclipse/tycho/versions/manipulation/BundleManifestManipulator.java @@ -21,9 +21,12 @@ import java.util.HashSet; import java.util.Map; import java.util.Map.Entry; +import java.util.Optional; import java.util.Set; import org.codehaus.plexus.component.annotations.Component; +import org.eclipse.tycho.TychoConstants; +import org.eclipse.tycho.versions.bundle.MutableBndFile; import org.eclipse.tycho.versions.bundle.MutableBundleManifest; import org.eclipse.tycho.versions.engine.MetadataManipulator; import org.eclipse.tycho.versions.engine.PackageVersionChange; @@ -32,6 +35,7 @@ import org.eclipse.tycho.versions.engine.VersionChange; import org.eclipse.tycho.versions.engine.VersionChangesDescriptor; import org.eclipse.tycho.versions.engine.Versions; +import org.osgi.framework.Constants; @Component(role = MetadataManipulator.class, hint = "bundle-manifest") public class BundleManifestManipulator extends AbstractMetadataManipulator { @@ -77,6 +81,10 @@ public void writeMetadata(ProjectMetadata project) throws IOException { if (mf != null) { MutableBundleManifest.write(mf, getManifestFile(project)); } + MutableBndFile bnd = project.getMetadata(MutableBndFile.class); + if (bnd != null) { + bnd.write(getBndFile(project)); + } } private Set computeExportedPackageChanges(ProjectMetadata project, @@ -86,7 +94,11 @@ private Set computeExportedPackageChanges(ProjectMetadata return Collections.emptySet(); } - MutableBundleManifest mf = getBundleManifest(project); + Optional bundleManifest = getBundleManifest(project); + if (bundleManifest.isEmpty()) { + return Set.of(); + } + MutableBundleManifest mf = bundleManifest.get(); // ignore ".qualifier" literals in package versions String versionToReplace = Versions.toBaseVersion(versionChangeForProject.getVersion()); String newVersion = Versions.toBaseVersion(versionChangeForProject.getNewVersion()); @@ -105,7 +117,21 @@ private Set computeExportedPackageChanges(ProjectMetadata private VersionChange findVersionChangeForProject(ProjectMetadata project, VersionChangesDescriptor versionChangeContext) { - MutableBundleManifest mf = getBundleManifest(project); + Optional bundleManifest = getBundleManifest(project); + if (bundleManifest.isEmpty()) { + Optional bndFile = getBundleBndFile(project); + if (bndFile.isPresent()) { + MutableBndFile bnd = bndFile.get(); + String bsn = bnd.getValue(Constants.BUNDLE_SYMBOLICNAME); + String vrs = bnd.getValue(Constants.BUNDLE_VERSION); + VersionChange versionChangeForProject = versionChangeContext.findVersionChangeByArtifactId(bsn); + if (versionChangeForProject != null && versionChangeForProject.getVersion().equals(vrs)) { + return versionChangeForProject; + } + } + return null; + } + MutableBundleManifest mf = bundleManifest.get(); VersionChange versionChangeForProject = versionChangeContext .findVersionChangeByArtifactId(mf.getSymbolicName()); if (versionChangeForProject != null && versionChangeForProject.getVersion().equals(mf.getVersion())) { @@ -117,7 +143,21 @@ private VersionChange findVersionChangeForProject(ProjectMetadata project, private void updateBundleAndExportPackageVersions(ProjectMetadata project, VersionChangesDescriptor versionChangeContext) { - MutableBundleManifest mf = getBundleManifest(project); + Optional bundleManifest = getBundleManifest(project); + if (bundleManifest.isEmpty()) { + Optional bndFile = getBundleBndFile(project); + if (bndFile.isPresent()) { + MutableBndFile bnd = bndFile.get(); + VersionChange versionChangeForProject = findVersionChangeForProject(project, versionChangeContext); + if (versionChangeForProject != null) { + logger.info(" " + TychoConstants.PDE_BND + "//Bundle-Version: " + + versionChangeForProject.getVersion() + " => " + versionChangeForProject.getNewVersion()); + bnd.setValue(Constants.BUNDLE_VERSION, versionChangeForProject.getNewVersion()); + } + } + return; + } + MutableBundleManifest mf = bundleManifest.get(); VersionChange versionChangeForProject = findVersionChangeForProject(project, versionChangeContext); if (versionChangeForProject != null) { logger.info(" META-INF/MANIFEST.MF//Bundle-Version: " + versionChangeForProject.getVersion() + " => " @@ -140,7 +180,11 @@ private void updateBundleAndExportPackageVersions(ProjectMetadata project, } private void updateFragmentHostVersion(ProjectMetadata project, VersionChangesDescriptor versionChangeContext) { - MutableBundleManifest mf = getBundleManifest(project); + Optional bundleManifest = getBundleManifest(project); + if (bundleManifest.isEmpty()) { + return; + } + MutableBundleManifest mf = bundleManifest.get(); if (mf.isFragment()) { VersionChange versionChange = versionChangeContext .findVersionChangeByArtifactId(mf.getFragmentHostSymbolicName()); @@ -156,7 +200,11 @@ private void updateFragmentHostVersion(ProjectMetadata project, VersionChangesDe } private void updateRequireBundleVersions(ProjectMetadata project, VersionChangesDescriptor versionChangeContext) { - MutableBundleManifest mf = getBundleManifest(project); + Optional bundleManifest = getBundleManifest(project); + if (bundleManifest.isEmpty()) { + return; + } + MutableBundleManifest mf = bundleManifest.get(); Map requiredBundleVersions = mf.getRequiredBundleVersions(); Map versionsToUpdate = new HashMap<>(); for (PomVersionChange versionChange : versionChangeContext.getVersionChanges()) { @@ -172,7 +220,11 @@ private void updateRequireBundleVersions(ProjectMetadata project, VersionChanges } private void updateImportPackageVersions(ProjectMetadata project, VersionChangesDescriptor versionChangeContext) { - MutableBundleManifest mf = getBundleManifest(project); + Optional bundleManifest = getBundleManifest(project); + if (bundleManifest.isEmpty()) { + return; + } + MutableBundleManifest mf = bundleManifest.get(); Map importedPackageNewVersions = new HashMap<>(); for (Entry importPackageVersions : mf.getImportPackagesVersions().entrySet()) { String packageName = importPackageVersions.getKey(); @@ -192,22 +244,46 @@ private void updateImportPackageVersions(ProjectMetadata project, VersionChanges mf.updateImportedPackageVersions(importedPackageNewVersions); } - private MutableBundleManifest getBundleManifest(ProjectMetadata project) { + private Optional getBundleManifest(ProjectMetadata project) { MutableBundleManifest mf = project.getMetadata(MutableBundleManifest.class); if (mf == null) { File file = getManifestFile(project); - try { - mf = MutableBundleManifest.read(file); - } catch (IOException e) { - throw new IllegalArgumentException("Could not parse bundle manifest " + file, e); + if (file.isFile()) { + try { + mf = MutableBundleManifest.read(file); + } catch (IOException e) { + throw new IllegalArgumentException("Could not parse bundle manifest " + file, e); + } + project.putMetadata(mf); + return Optional.of(mf); + } + } + return Optional.ofNullable(mf); + } + + private Optional getBundleBndFile(ProjectMetadata project) { + MutableBndFile bnd = project.getMetadata(MutableBndFile.class); + if (bnd == null) { + File file = getBndFile(project); + if (file.isFile()) { + try { + bnd = MutableBndFile.read(file); + } catch (IOException e) { + throw new IllegalArgumentException("Could not parse bundle manifest " + file, e); + } + project.putMetadata(bnd); + return Optional.of(bnd); } - project.putMetadata(mf); } - return mf; + return Optional.ofNullable(bnd); } private File getManifestFile(ProjectMetadata project) { return new File(project.getBasedir(), "META-INF/MANIFEST.MF"); } + private File getBndFile(ProjectMetadata project) { + return new File(project.getBasedir(), TychoConstants.PDE_BND); + } + } diff --git a/tycho-versions-plugin/src/test/java/org/eclipse/tycho/versions/bundle/tests/MutableBndFileTest.java b/tycho-versions-plugin/src/test/java/org/eclipse/tycho/versions/bundle/tests/MutableBndFileTest.java new file mode 100644 index 0000000000..851f41ef74 --- /dev/null +++ b/tycho-versions-plugin/src/test/java/org/eclipse/tycho/versions/bundle/tests/MutableBndFileTest.java @@ -0,0 +1,57 @@ +/******************************************************************************* + * Copyright (c) 2023 Christoph Läubrich and others. + * This program and the accompanying materials + * are made available under the terms of the Eclipse Public License 2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/legal/epl-2.0/ + * + * SPDX-License-Identifier: EPL-2.0 + * + * Contributors: + * Christoph Läubrich - implementation + *******************************************************************************/ +package org.eclipse.tycho.versions.bundle.tests; + +import static org.junit.Assert.assertEquals; + +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; + +import org.eclipse.tycho.versions.bundle.MutableBndFile; +import org.junit.Test; +import org.osgi.framework.Constants; + +public class MutableBndFileTest { + + @Test + public void linebreakTest() throws IOException { + MutableBndFile bnd = getBndFile("linebreak"); + //bnd.setValue(Constants.BUNDLE_VERSION, "xxx"); + StringWriter writer = new StringWriter(); + bnd.write(writer); + assertEquals(getBndString("linebreak"), writer.toString()); + } + + @Test + public void versionTest() throws IOException { + String newVersion = "xxx"; + MutableBndFile bnd = getBndFile("linebreak"); + bnd.setValue(Constants.BUNDLE_VERSION, newVersion); + StringWriter writer = new StringWriter(); + bnd.write(writer); + assertEquals(getBndString("linebreak").replace("1.0.0.qualifier", newVersion), writer.toString()); + } + + private MutableBndFile getBndFile(String filename) throws IOException { + return MutableBndFile.read(getBndStream(filename)); + } + + private String getBndString(String filename) throws IOException { + return new String(getBndStream(filename).readAllBytes()); + } + + private InputStream getBndStream(String filename) { + return getClass().getResourceAsStream("/bnds/" + filename + ".bnd"); + } +} diff --git a/tycho-versions-plugin/src/test/resources/bnds/linebreak.bnd b/tycho-versions-plugin/src/test/resources/bnds/linebreak.bnd new file mode 100644 index 0000000000..9082cf37ff --- /dev/null +++ b/tycho-versions-plugin/src/test/resources/bnds/linebreak.bnd @@ -0,0 +1,5 @@ +Bundle-Name: Bnd +Bundle-SymbolicName: pde.bnd +Bundle-Vendor: +Bundle-Version: \ + 1.0.0.qualifier \ No newline at end of file