diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java index b992255a5..32b76113c 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java @@ -48,6 +48,7 @@ import org.codehaus.mojo.versions.utils.SegmentUtils; import org.eclipse.aether.RepositorySystem; +import static java.util.stream.StreamSupport.stream; import static org.apache.commons.lang3.StringUtils.isBlank; /** @@ -164,12 +165,9 @@ protected void update(MutableXMLStreamReader pom) throw new MojoExecutionException("skipResolution is only valid if parentVersion is set"); } - String initialVersion = Optional.ofNullable(parentVersion) - .orElse(getProject().getParent().getVersion()); try { - ArtifactVersion artifactVersion = skipResolution - ? DefaultArtifactVersionCache.of(parentVersion) - : resolveTargetVersion(initialVersion); + ArtifactVersion artifactVersion = + skipResolution ? DefaultArtifactVersionCache.of(parentVersion) : resolveTargetVersion(); if (artifactVersion != null) { getLog().info("Updating parent from " + getProject().getParent().getVersion() + " to " + artifactVersion); @@ -190,25 +188,25 @@ protected void update(MutableXMLStreamReader pom) } } } catch (InvalidVersionSpecificationException e) { - throw new MojoExecutionException("Invalid version range specification: " + initialVersion, e); + throw new MojoExecutionException("Invalid version range specification: " + parentVersion, e); } catch (InvalidSegmentException e) { - throw new MojoExecutionException("Invalid segment specification for version " + initialVersion, e); + throw new MojoExecutionException("Invalid segment specification for version " + parentVersion, e); } } - protected ArtifactVersion resolveTargetVersion(String initialVersion) + protected ArtifactVersion resolveTargetVersion() throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, InvalidSegmentException { Artifact artifact = getHelper() .createDependencyArtifact(DependencyBuilder.newBuilder() .withGroupId(getProject().getParent().getGroupId()) .withArtifactId(getProject().getParent().getArtifactId()) - .withVersion(initialVersion) + .withVersion(getProject().getParent().getVersion()) .withType("pom") .build()); - VersionRange targetVersionRange = VersionRange.createFromVersionSpec(initialVersion); - if (targetVersionRange.getRecommendedVersion() != null) { + VersionRange targetVersionRange = VersionRange.createFromVersionSpec(parentVersion); + if (targetVersionRange != null && targetVersionRange.getRecommendedVersion() != null) { targetVersionRange = targetVersionRange.restrict( VersionRange.createFromVersionSpec("[" + targetVersionRange.getRecommendedVersion() + ",)")); } @@ -219,27 +217,35 @@ protected ArtifactVersion resolveTargetVersion(String initialVersion) // currentVersion (set to parentVersion here) is not included in the version range for searching upgrades // unless we set allowDowngrade to true - for (ArtifactVersion candidate : reverse(versions.getNewerVersions( - initialVersion, unchangedSegment, allowSnapshots, !isBlank(parentVersion) || allowDowngrade))) { - if (allowDowngrade - || targetVersionRange == null - || ArtifactVersions.isVersionInRange(candidate, targetVersionRange)) { - if (shouldApplyUpdate(artifact, getProject().getParent().getVersion(), candidate, forceUpdate)) { - return candidate; - } else { - getLog().debug("Update not applied. Exiting."); - return null; - } - } - } - if (versions.isEmpty(allowSnapshots)) { - getLog().info("No versions found"); - } else { - getLog().info("The parent project is the latest version"); - } - - return null; + VersionRange finalTargetVersionRange = targetVersionRange; + return stream( + reverse(versions.getNewerVersions( + getProject().getParent().getVersion(), + unchangedSegment, + allowSnapshots, + allowDowngrade)) + .spliterator(), + false) + .filter(v -> finalTargetVersionRange == null + || ArtifactVersions.isVersionInRange(v, finalTargetVersionRange)) + .findFirst() + .map(candidate -> { + if (shouldApplyUpdate(artifact, getProject().getParent().getVersion(), candidate, forceUpdate)) { + return candidate; + } else { + getLog().debug("Update not applied. Exiting."); + return null; + } + }) + .orElseGet(() -> { + if (versions.isEmpty(allowSnapshots)) { + getLog().info("No versions found"); + } else { + getLog().info("The parent project is the latest version"); + } + return null; + }); } private static Iterable reverse(T[] array) { diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java index bedfd48b0..d8d2a14a0 100644 --- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java +++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java @@ -76,6 +76,7 @@ public static void setUpStatic() { put("dummy-parent2", new String[] {"1.0", "2.0", "3.0", "3.0-alpha-1", "3.0-beta-1"}); put("test-incremental", new String[] {"1.0.0", "1.1.0", "1.1.1", "2.0.0"}); put("unknown-artifact", new String[0]); + put("mojo-parent", new String[] {"70", "78", "86"}); } }); } @@ -186,10 +187,10 @@ public void testParentDowngradeAllowedWithRange() { setGroupId("default-group"); setArtifactId("parent-artifact"); + setVersion("[1.0.1-SNAPSHOT,)"); } }); - - ArtifactVersion newVersion = mojo.resolveTargetVersion("[1.0.1-SNAPSHOT,)"); + ArtifactVersion newVersion = mojo.resolveTargetVersion(); assertThat(newVersion, notNullValue()); assertThat(newVersion.toString(), is("1.0.0")); } @@ -199,7 +200,8 @@ public void testParentDowngradeForbiddenWithRange() throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, InvalidSegmentException { mojo.allowDowngrade = false; - ArtifactVersion newVersion = mojo.resolveTargetVersion("[1.0.1-SNAPSHOT,)"); + mojo.parentVersion = "[1.0.1-SNAPSHOT,)"; + ArtifactVersion newVersion = mojo.resolveTargetVersion(); assertThat(newVersion, nullValue()); } @@ -212,10 +214,11 @@ public void testAllowSnapshots() { setGroupId("default-group"); setArtifactId("issue-670-artifact"); + setVersion("0.0.1-1"); } }); - ArtifactVersion newVersion = mojo.resolveTargetVersion("0.0.1-1"); + ArtifactVersion newVersion = mojo.resolveTargetVersion(); assertThat(newVersion, notNullValue()); assertThat(newVersion.toString(), is("0.0.1-1-impl-SNAPSHOT")); } @@ -253,10 +256,11 @@ public void testIgnoredVersions() { setGroupId("default-group"); setArtifactId("parent-artifact"); + setVersion("0.9.0"); } }); setVariableValueToObject(mojo, "ignoredVersions", singleton("1.0.0")); - assertThat(mojo.resolveTargetVersion("0.9.0"), nullValue()); + assertThat(mojo.resolveTargetVersion(), nullValue()); } @Test @@ -337,8 +341,8 @@ public void testAllowMinorUpdates() mojo.allowMajorUpdates = false; mojo.allowMinorUpdates = true; mojo.allowIncrementalUpdates = true; - - ArtifactVersion newVersion = mojo.resolveTargetVersion("0.8.0"); + mojo.parentVersion = "0.8.0"; + ArtifactVersion newVersion = mojo.resolveTargetVersion(); assertThat(newVersion, notNullValue()); assertThat(newVersion.toString(), is("0.9.0")); @@ -352,13 +356,13 @@ public void testAllowIncrementalUpdates() { setGroupId("default-group"); setArtifactId("test-incremental"); + setVersion("1.1.0"); } }); mojo.allowMajorUpdates = false; mojo.allowMinorUpdates = false; mojo.allowIncrementalUpdates = true; - - ArtifactVersion newVersion = mojo.resolveTargetVersion("1.1.0"); + ArtifactVersion newVersion = mojo.resolveTargetVersion(); assertThat(newVersion, notNullValue()); assertThat(newVersion.toString(), is("1.1.1")); @@ -407,4 +411,52 @@ public void testParentVersionRange2() } assertThat(changeRecorder.getChanges(), empty()); } + + /* + * Reproduces issue 1060 + */ + @Test + public void testIssue1060VersionRangeAllowDowngradeFalse() + throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("dummy-parent2"); + setVersion("2.0"); + } + }); + mojo.parentVersion = "[,2.9-!)"; + mojo.allowDowngrade = false; + try (MockedStatic pomHelper = mockStatic(PomHelper.class)) { + pomHelper + .when(() -> PomHelper.setProjectParentVersion(any(), any())) + .thenReturn(true); + mojo.update(null); + } + assertThat(changeRecorder.getChanges(), empty()); + } + + /* + * Reproduces issue 1060 + */ + @Test + public void testIssue1060VersionRangeAllowDowngradeTrue() + throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("mojo-parent"); + setVersion("78"); + } + }); + mojo.parentVersion = "[,79-!)"; + mojo.allowDowngrade = true; + try (MockedStatic pomHelper = mockStatic(PomHelper.class)) { + pomHelper + .when(() -> PomHelper.setProjectParentVersion(any(), any())) + .thenReturn(true); + mojo.update(null); + } + assertThat(changeRecorder.getChanges(), empty()); + } }