Skip to content

Commit

Permalink
Do not update to the next major version unless explicitly requested
Browse files Browse the repository at this point in the history
Currently the update-target mojo just updates to the highest version,
but in some cases it is desirable to not update to the next "major"
version.

This adds a new parameter to prevent major updates unless explicitly
requested.
  • Loading branch information
laeubi committed Aug 12, 2024
1 parent ff39623 commit d1adc82
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Objects;
import java.util.Set;

import org.apache.maven.RepositoryUtils;
Expand Down Expand Up @@ -49,6 +50,7 @@
import org.eclipse.aether.resolution.VersionRangeResolutionException;
import org.eclipse.aether.resolution.VersionRangeResult;
import org.eclipse.aether.version.Version;
import org.eclipse.tycho.TychoConstants;

@Component(role = MavenDependenciesResolver.class)
public class MavenDependenciesResolver {
Expand Down Expand Up @@ -104,14 +106,10 @@ public Collection<org.apache.maven.artifact.Artifact> resolve(MavenProject proje
DependencyNode rootNode = collectResult.getRoot();

CumulativeScopeArtifactFilter scopeArtifactFilter = new CumulativeScopeArtifactFilter(scopesToResolve);
DependencyRequest dependencyRequest = new DependencyRequest(collect, new DependencyFilter() {
DependencyRequest dependencyRequest = new DependencyRequest(collect, (DependencyFilter) (node, parents) -> {

@Override
public boolean accept(DependencyNode node, List<DependencyNode> parents) {

Artifact artifact = RepositoryUtils.toArtifact(node.getArtifact());
return artifact != null && scopeArtifactFilter.include(artifact);
}
Artifact artifact = RepositoryUtils.toArtifact(node.getArtifact());
return artifact != null && scopeArtifactFilter.include(artifact);
});
dependencyRequest.setRoot(rootNode);

Expand Down Expand Up @@ -169,8 +167,9 @@ public Artifact resolveHighestVersion(MavenProject project, MavenSession session
if (version.endsWith(".0)")) {
version = version.substring(0, version.length() - 3) + ")";
}
String typeId = Objects.requireNonNullElse(dependency.getType(), TychoConstants.JAR_EXTENSION);
DefaultArtifact artifact = new DefaultArtifact(dependency.getGroupId(), dependency.getArtifactId(),
stereotypes.get(dependency.getType()).getExtension(), version);
stereotypes.get(typeId).getExtension(), version);
VersionRangeRequest request = new VersionRangeRequest(artifact, project.getRemoteProjectRepositories(), null);
VersionRangeResult versionResult = repoSystem.resolveVersionRange(repositorySession, request);
for (Iterator<Version> iterator = versionResult.getVersions().iterator(); iterator.hasNext();) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.eclipse.aether.resolution.ArtifactResolutionException;
import org.eclipse.aether.resolution.VersionRangeResolutionException;
import org.eclipse.aether.version.InvalidVersionSpecificationException;
import org.eclipse.tycho.TargetEnvironment;
import org.eclipse.tycho.core.maven.MavenDependenciesResolver;
import org.eclipse.tycho.core.resolver.P2ResolutionResult;
Expand All @@ -64,6 +65,7 @@
*/
@Mojo(name = "update-target")
public class UpdateTargetMojo extends AbstractUpdateMojo {

@Parameter(property = "target")
private File targetFile;

Expand All @@ -76,9 +78,19 @@ public class UpdateTargetMojo extends AbstractUpdateMojo {
@Component
private MavenSession mavenSession;

/**
* If specified also update to new major versions of the dependency otherwise only perform
* minor, micro or "qualifier" changes, please note that for maven locations the semantic might
* be slightly different as maven does not follow OSGi version scheme, in this case we interpret
* the first part of the version as the major version.
*/
@Parameter(property = "major", defaultValue = "true")
private boolean updateMajorVersion;

@Override
protected void doUpdate() throws IOException, URISyntaxException, ParserConfigurationException,
TargetResolveException, MojoFailureException, VersionRangeResolutionException, ArtifactResolutionException {
TargetResolveException, MojoFailureException, VersionRangeResolutionException, ArtifactResolutionException,
InvalidVersionSpecificationException {
File file = getFileToBeUpdated();
getLog().info("Update target file " + file);
//we use the descent xml parser here because we need to retain the formating of the original file
Expand Down Expand Up @@ -127,10 +139,24 @@ protected void doUpdate() throws IOException, URISyntaxException, ParserConfigur
mavenDependency.setVersion(getElementValue("version", dependency));
mavenDependency.setType(getElementValue("type", dependency));
mavenDependency.setClassifier(getElementValue("classifier", dependency));
Artifact highestVersionArtifact = resolver.resolveHighestVersion(project, mavenSession,
String oldVersion = mavenDependency.getVersion();
if (!updateMajorVersion) {
try {
String[] strings = oldVersion.split("\\.");
mavenDependency.setVersion("[," + (Integer.parseInt(strings[0]) + 1) + ")");
} catch (RuntimeException e) {
getLog().warn("Can't check for update of " + mavenDependency
+ " because the version format is not parseable: " + e);
continue;
}
}
Artifact newArtifactVersion = resolver.resolveHighestVersion(project, mavenSession,
mavenDependency);
String newVersion = highestVersionArtifact.getVersion();
if (newVersion.equals(mavenDependency.getVersion())) {
if (newArtifactVersion == null) {
continue;
}
String newVersion = newArtifactVersion.getVersion();
if (newVersion.equals(oldVersion)) {
getLog().debug(mavenDependency + " is already up-to date");
} else {
changed = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@
<version>1.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>1.3.5</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.0.0</version>
<type>jar</type>
</dependency>
</dependencies>
</location>
</locations>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,20 @@
package org.eclipse.tycho.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.File;
import java.io.FileInputStream;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.maven.it.Verifier;
import org.eclipse.aether.util.version.GenericVersionScheme;
import org.eclipse.aether.version.Version;
import org.eclipse.aether.version.VersionScheme;
import org.eclipse.tycho.targetplatform.TargetDefinition.InstallableUnitLocation;
import org.eclipse.tycho.targetplatform.TargetDefinition.Location;
import org.eclipse.tycho.targetplatform.TargetDefinition.MavenDependency;
Expand All @@ -39,7 +44,6 @@ public void testUpdateTarget() throws Exception {
Verifier verifier = getVerifier("tycho-version-bump-plugin/update-target", false, true);
String sourceTargetFile = "update-target.target";
verifier.setSystemProperty("target", sourceTargetFile);
verifier.setSystemProperty("tycho.localArtifacts", "ignore");
verifier.executeGoal("org.eclipse.tycho.extras:tycho-version-bump-plugin:" + TychoVersion.getTychoVersion()
+ ":update-target");
verifier.verifyErrorFreeLog();
Expand All @@ -61,13 +65,58 @@ public void testUpdateTarget() throws Exception {
MavenGAVLocation maven = locations.stream().filter(MavenGAVLocation.class::isInstance)
.map(MavenGAVLocation.class::cast).findFirst()
.orElseThrow(() -> new AssertionError("Maven Location not found!"));
Collection<MavenDependency> roots = maven.getRoots();
assertEquals(1, roots.size());
MavenDependency dependency = roots.iterator().next();
MavenDependency dependency = dependencies(maven, "javax.annotation", "javax.annotation-api").findFirst()
.orElseThrow(() -> new AssertionError("javax.annotation dependency not found"));
assertEquals("Maven version was not updated correctly in " + targetFile, "1.3.2", dependency.getVersion());
List<MavenDependency> list = dependencies(maven, "jakarta.annotation", "jakarta.annotation-api").toList();
assertEquals(2, list.size());
VersionScheme scheme = new GenericVersionScheme();
// we can not know the exact latest major version, but we know it must be larger
// than 3.0
Version version3 = scheme.parseVersion("3");
assertTrue("Maven version was not updated correctly in " + targetFile + " for jakarta.annotation-api 1.3.5",
scheme.parseVersion(list.get(0).getVersion()).compareTo(version3) >= 0);
assertTrue(
"No Update for Maven version was expected in " + targetFile + " for jakarta.annotation-api 2.0.0",
scheme.parseVersion(list.get(1).getVersion()).compareTo(version3) >= 0);
}
}

@Test
public void testUpdateTargetWithoutMajor() throws Exception {
Verifier verifier = getVerifier("tycho-version-bump-plugin/update-target", false, true);
String sourceTargetFile = "update-target.target";
verifier.setSystemProperty("target", sourceTargetFile);
verifier.setSystemProperty("major", "false");
verifier.executeGoal("org.eclipse.tycho.extras:tycho-version-bump-plugin:" + TychoVersion.getTychoVersion()
+ ":update-target");
verifier.verifyErrorFreeLog();
File targetFile = new File(verifier.getBasedir(), sourceTargetFile);
try (FileInputStream input = new FileInputStream(targetFile)) {
Document target = TargetDefinitionFile.parseDocument(input);
TargetDefinitionFile parsedTarget = TargetDefinitionFile.parse(target, targetFile.getAbsolutePath());
List<? extends Location> locations = parsedTarget.getLocations();
MavenGAVLocation maven = locations.stream().filter(MavenGAVLocation.class::isInstance)
.map(MavenGAVLocation.class::cast).findFirst()
.orElseThrow(() -> new AssertionError("Maven Location not found!"));
List<MavenDependency> list = dependencies(maven, "jakarta.annotation", "jakarta.annotation-api").toList();
assertEquals(2, list.size());
assertEquals(
"No Update for Maven version was expected in " + targetFile + " for jakarta.annotation-api 1.3.5",
"1.3.5", list.get(0).getVersion());
assertEquals(
"Maven version was not updated correctly in " + targetFile + " for jakarta.annotation-api 2.0.0",
"2.1.1", list.get(1).getVersion());

}
}

private Stream<MavenDependency> dependencies(MavenGAVLocation maven, String g, String a) {
Collection<MavenDependency> roots = maven.getRoots();
assertEquals(1, roots.size());
return roots.stream().filter(md -> md.getGroupId().equals(g)).filter(md -> md.getArtifactId().equals(a));
}

private void assertIUVersion(String id, String version, List<? extends Unit> units, File targetFile) {
for (Unit unit : units) {
if (unit.getId().equals(id) && unit.getVersion().equals(version)) {
Expand Down

0 comments on commit d1adc82

Please sign in to comment.