Skip to content

Commit

Permalink
Add an 'update-manifest' mojo to align manifest versions to dependencies
Browse files Browse the repository at this point in the history
It is recommended to use as the lower bound the dependency the code was
compiled with to avoid using newer code from dependencies, but managing
that manually can be a daunting task.

This now adds a new 'update-manifest' mojo that helps in calculate the
lower bound and update the manifest accordingly.
  • Loading branch information
laeubi committed Aug 15, 2024
1 parent 07d24b8 commit 708edfd
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ MavenSession getMavenSession() {

public void execute() throws MojoExecutionException, MojoFailureException {
File file = getFileToBeUpdated();
if (file != null) {
if (file != null && file.exists()) {
try {
doUpdate(file);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/*******************************************************************************
* Copyright (c) 2024 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.versionbump;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.jar.JarFile;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.eclipse.equinox.p2.metadata.IInstallableUnit;
import org.eclipse.equinox.p2.query.QueryUtil;
import org.eclipse.tycho.DependencyArtifacts;
import org.eclipse.tycho.core.TychoProjectManager;
import org.eclipse.tycho.model.manifest.MutableBundleManifest;
import org.eclipse.tycho.p2tools.copiedfromp2.QueryableArray;
import org.osgi.framework.Version;

@Mojo(name = "update-manifest", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME)
public class UpdateManifestMojo extends AbstractUpdateMojo {

@Parameter(defaultValue = "${project.basedir}/" + JarFile.MANIFEST_NAME)
private File manifestFile;

@Component
private TychoProjectManager projectManager;

@Override
protected void doUpdate(File file) throws Exception {
MutableBundleManifest manifest = MutableBundleManifest.read(file);
DependencyArtifacts artifacts = projectManager.getDependencyArtifacts(getProject()).orElse(null);
if (artifacts != null) {
Map<String, String> updated = new HashMap<>();
QueryableArray queryable = new QueryableArray(artifacts.getInstallableUnits());
for (Entry<String, String> requiredBundle : manifest.getRequiredBundleVersions().entrySet()) {
String oldValue = requiredBundle.getValue();
String bsn = requiredBundle.getKey();
IInstallableUnit unit = queryable.query(QueryUtil.createLatestQuery(QueryUtil.createIUQuery(bsn)), null)
.stream().findFirst().orElse(null);
if (unit != null) {
if (oldValue == null || oldValue.isBlank()) {
//no value at all
//TODO configure how to handle?!?
} else if (oldValue.startsWith("[") || oldValue.startsWith("(")) {
//a version range to handle
//TODO
} else {
//a plain version to handle
Version currentVersion = Version.parseVersion(oldValue);
Version latestVersion = Version.parseVersion(unit.getVersion().toString());
if (latestVersion.compareTo(currentVersion) > 0
&& !versionEqualsIgnoreQualifier(currentVersion, latestVersion)) {
String format = String.format("%d.%d.%d", latestVersion.getMajor(),
latestVersion.getMinor(), latestVersion.getMicro());
getLog().info("Update lower bound of required bundle " + bsn + " from " + oldValue + " to "
+ format);
updated.put(bsn, format);
//TODO configure if we should set an upper bound!
}
}
}
}
if (!updated.isEmpty()) {
manifest.updateRequiredBundleVersions(updated);
MutableBundleManifest.write(manifest, file);
}
}
}

private boolean versionEqualsIgnoreQualifier(Version v1, Version v2) {
return v1.getMajor() == v2.getMajor() && v1.getMinor() == v2.getMinor() && v1.getMicro() == v1.getMicro();
}

@Override
protected File getFileToBeUpdated() throws MojoExecutionException, MojoFailureException {

return manifestFile;
}

}

0 comments on commit 708edfd

Please sign in to comment.