diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java
index 44c5d57c7a..07b39fe2ed 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestReleasesMojo.java
@@ -96,6 +96,16 @@ public class UseLatestReleasesMojo extends UseLatestVersionsMojoBase {
@Parameter(property = "allowIncrementalUpdates", defaultValue = "true")
protected boolean allowIncrementalUpdates = true;
+ /**
+ *
Whether to downgrade a snapshot dependency if allowSnapshots
is false
+ * and there exists a non-snapshot version within the range fulfilling the criteria.
+ * Only valid if allowSnapshots
is false
.
+ *
+ * @since 2.15.0
+ */
+ @Parameter(property = "allowDowngrade", defaultValue = "false")
+ protected boolean allowDowngrade;
+
// ------------------------------ METHODS --------------------------
@Inject
@@ -148,7 +158,8 @@ private void useLatestReleases(
(dep, versions) -> {
try {
return getLastFiltered(
- versions.getNewerVersions(dep.getVersion(), unchangedSegment, false, false), dep);
+ versions.getNewerVersions(dep.getVersion(), unchangedSegment, false, allowDowngrade),
+ dep);
} catch (InvalidSegmentException e) {
getLog().warn(String.format(
"Skipping the processing of %s:%s:%s due to: %s",
@@ -157,7 +168,8 @@ private void useLatestReleases(
return empty();
},
changeKind,
- dep -> !SNAPSHOT_REGEX.matcher(dep.getVersion()).matches());
+ dep -> allowDowngrade
+ || !SNAPSHOT_REGEX.matcher(dep.getVersion()).matches());
}
/**
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java
index a0fdfddcc9..8f614956c3 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java
@@ -26,18 +26,21 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
+import java.util.Optional;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.wagon.Wagon;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.api.VersionRetrievalException;
import org.codehaus.mojo.versions.api.recording.ChangeRecord;
import org.codehaus.mojo.versions.api.recording.ChangeRecorder;
+import org.codehaus.mojo.versions.ordering.InvalidSegmentException;
import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
import static java.util.Collections.singletonList;
@@ -51,7 +54,15 @@
@Mojo(name = "use-next-releases", threadSafe = true)
public class UseNextReleasesMojo extends UseLatestVersionsMojoBase {
- // ------------------------------ METHODS --------------------------
+ /**
+ * Whether to downgrade a snapshot dependency if allowSnapshots
is false
+ * and there exists a non-snapshot version within the range fulfilling the criteria.
+ * Only valid if allowSnapshots
is false
.
+ *
+ * @since 2.15.0
+ */
+ @Parameter(property = "allowDowngrade", defaultValue = "false")
+ protected boolean allowDowngrade;
@Inject
public UseNextReleasesMojo(
@@ -99,9 +110,17 @@ private void useNextReleases(
useLatestVersions(
pom,
dependencies,
- (dep, versions) -> Arrays.stream(versions.getNewerVersions(dep.getVersion(), false))
- .findFirst(),
+ (dep, versions) -> {
+ try {
+ return Arrays.stream(versions.getNewerVersions(
+ dep.getVersion(), Optional.empty(), false, allowDowngrade))
+ .findFirst();
+ } catch (InvalidSegmentException e) {
+ throw new RuntimeException(e);
+ }
+ },
changeKind,
- dep -> !SNAPSHOT_REGEX.matcher(dep.getVersion()).matches());
+ dep -> allowDowngrade
+ || !SNAPSHOT_REGEX.matcher(dep.getVersion()).matches());
}
}
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java
index b263c0887c..319005a68e 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java
@@ -26,18 +26,21 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
+import java.util.Optional;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.repository.RepositorySystem;
import org.apache.maven.wagon.Wagon;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.api.VersionRetrievalException;
import org.codehaus.mojo.versions.api.recording.ChangeRecord;
import org.codehaus.mojo.versions.api.recording.ChangeRecorder;
+import org.codehaus.mojo.versions.ordering.InvalidSegmentException;
import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
import static java.util.Collections.singletonList;
@@ -51,6 +54,16 @@
@Mojo(name = "use-next-versions", threadSafe = true)
public class UseNextVersionsMojo extends UseLatestVersionsMojoBase {
+ /**
+ * Whether to downgrade a snapshot dependency if allowSnapshots
is false
+ * and there exists a non-snapshot version within the range fulfilling the criteria.
+ * Only valid if allowSnapshots
is false
.
+ *
+ * @since 2.15.0
+ */
+ @Parameter(property = "allowDowngrade", defaultValue = "false")
+ protected boolean allowDowngrade;
+
// ------------------------------ METHODS --------------------------
@Inject
@@ -97,8 +110,15 @@ private void useNextVersions(
useLatestVersions(
pom,
dependencies,
- (dep, versions) -> Arrays.stream(versions.getNewerVersions(dep.getVersion(), allowSnapshots))
- .findFirst(),
+ (dep, versions) -> {
+ try {
+ return Arrays.stream(versions.getNewerVersions(
+ dep.getVersion(), Optional.empty(), allowSnapshots, allowDowngrade))
+ .findFirst();
+ } catch (InvalidSegmentException e) {
+ throw new RuntimeException(e);
+ }
+ },
changeKind);
}
}
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java
index 2760d8807b..c8777c2b36 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java
@@ -11,6 +11,7 @@
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.api.VersionRetrievalException;
+import org.codehaus.mojo.versions.change.DefaultVersionChange;
import org.codehaus.mojo.versions.utils.DependencyBuilder;
import org.codehaus.mojo.versions.utils.TestChangeRecorder;
import org.hamcrest.Matchers;
@@ -26,7 +27,10 @@
import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession;
import static org.codehaus.mojo.versions.utils.MockUtils.mockRepositorySystem;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasItem;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mockStatic;
public class UseLatestReleasesMojoTest {
@@ -98,4 +102,65 @@ public void testDontUpgradeToBeta()
}
assertThat(changeRecorder.getChanges(), Matchers.empty());
}
+
+ @Test
+ public void testAllowDowngrade()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException {
+ mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("artifactA", new String[] {"1.0.0", "1.0.1-SNAPSHOT"});
+ }
+ });
+ mojo.getProject()
+ .setDependencies(singletonList(DependencyBuilder.newBuilder()
+ .withGroupId("default-group")
+ .withArtifactId("artifactA")
+ .withVersion("1.0.1-SNAPSHOT")
+ .build()));
+ mojo.allowDowngrade = true;
+
+ try (MockedStatic pomHelper = mockStatic(PomHelper.class)) {
+ pomHelper
+ .when(() -> PomHelper.setDependencyVersion(
+ any(), anyString(), anyString(), anyString(), anyString(), any(Model.class)))
+ .thenReturn(true);
+ pomHelper
+ .when(() -> PomHelper.getRawModel(any(MavenProject.class)))
+ .thenReturn(mojo.getProject().getModel());
+ mojo.update(null);
+ }
+ assertThat(
+ changeRecorder.getChanges(),
+ hasItem(new DefaultVersionChange(
+ "default-group", "artifactA",
+ "1.0.1-SNAPSHOT", "1.0.0")));
+ }
+
+ @Test
+ public void testDisallowDowngrade()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException {
+ mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("artifactA", new String[] {"1.0.0", "1.0.1-SNAPSHOT"});
+ }
+ });
+ mojo.getProject()
+ .setDependencies(singletonList(DependencyBuilder.newBuilder()
+ .withGroupId("default-group")
+ .withArtifactId("artifactA")
+ .withVersion("1.0.1-SNAPSHOT")
+ .build()));
+
+ try (MockedStatic pomHelper = mockStatic(PomHelper.class)) {
+ pomHelper
+ .when(() -> PomHelper.setDependencyVersion(
+ any(), anyString(), anyString(), anyString(), anyString(), any(Model.class)))
+ .thenReturn(true);
+ pomHelper
+ .when(() -> PomHelper.getRawModel(any(MavenProject.class)))
+ .thenReturn(mojo.getProject().getModel());
+ mojo.update(null);
+ }
+ assertThat(changeRecorder.getChanges(), empty());
+ }
}
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextReleasesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextReleasesMojoTest.java
index 3a8329f343..8ff57dd70f 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextReleasesMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextReleasesMojoTest.java
@@ -18,13 +18,18 @@
* under the License.
*/
+import javax.xml.stream.XMLStreamException;
+
import java.util.Collections;
import java.util.HashMap;
import org.apache.maven.model.Model;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.mojo.versions.api.PomHelper;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
import org.codehaus.mojo.versions.change.DefaultVersionChange;
import org.codehaus.mojo.versions.utils.DependencyBuilder;
import org.codehaus.mojo.versions.utils.TestChangeRecorder;
@@ -34,14 +39,17 @@
import org.mockito.MockedStatic;
import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
import static org.apache.maven.plugin.testing.ArtifactStubFactory.setVariableValueToObject;
import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem;
import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession;
import static org.codehaus.mojo.versions.utils.MockUtils.mockRepositorySystem;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasItem;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mockStatic;
/**
@@ -123,4 +131,65 @@ public void testFindANewerRelease() throws IllegalAccessException {
changeRecorder.getChanges(),
hasItem(new DefaultVersionChange("default-group", "dependency-artifact", "1.1.0", "1.1.1")));
}
+
+ @Test
+ public void testAllowDowngrade()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException {
+ mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("artifactA", new String[] {"1.0.0", "1.0.1-SNAPSHOT"});
+ }
+ });
+ mojo.getProject()
+ .setDependencies(singletonList(DependencyBuilder.newBuilder()
+ .withGroupId("default-group")
+ .withArtifactId("artifactA")
+ .withVersion("1.0.1-SNAPSHOT")
+ .build()));
+ mojo.allowDowngrade = true;
+
+ try (MockedStatic pomHelper = mockStatic(PomHelper.class)) {
+ pomHelper
+ .when(() -> PomHelper.setDependencyVersion(
+ any(), anyString(), anyString(), anyString(), anyString(), any(Model.class)))
+ .thenReturn(true);
+ pomHelper
+ .when(() -> PomHelper.getRawModel(any(MavenProject.class)))
+ .thenReturn(mojo.getProject().getModel());
+ mojo.update(null);
+ }
+ assertThat(
+ changeRecorder.getChanges(),
+ hasItem(new DefaultVersionChange(
+ "default-group", "artifactA",
+ "1.0.1-SNAPSHOT", "1.0.0")));
+ }
+
+ @Test
+ public void testDisallowDowngrade()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException {
+ mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("artifactA", new String[] {"1.0.0", "1.0.1-SNAPSHOT"});
+ }
+ });
+ mojo.getProject()
+ .setDependencies(singletonList(DependencyBuilder.newBuilder()
+ .withGroupId("default-group")
+ .withArtifactId("artifactA")
+ .withVersion("1.0.1-SNAPSHOT")
+ .build()));
+
+ try (MockedStatic pomHelper = mockStatic(PomHelper.class)) {
+ pomHelper
+ .when(() -> PomHelper.setDependencyVersion(
+ any(), anyString(), anyString(), anyString(), anyString(), any(Model.class)))
+ .thenReturn(true);
+ pomHelper
+ .when(() -> PomHelper.getRawModel(any(MavenProject.class)))
+ .thenReturn(mojo.getProject().getModel());
+ mojo.update(null);
+ }
+ assertThat(changeRecorder.getChanges(), empty());
+ }
}
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextVersionsMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextVersionsMojoTest.java
index 0dddd3f4b5..7ab0d45cbb 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextVersionsMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseNextVersionsMojoTest.java
@@ -18,13 +18,18 @@
* under the License.
*/
+import javax.xml.stream.XMLStreamException;
+
import java.util.Collections;
import java.util.HashMap;
import org.apache.maven.model.Model;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.mojo.versions.api.PomHelper;
+import org.codehaus.mojo.versions.api.VersionRetrievalException;
import org.codehaus.mojo.versions.change.DefaultVersionChange;
import org.codehaus.mojo.versions.utils.DependencyBuilder;
import org.codehaus.mojo.versions.utils.TestChangeRecorder;
@@ -34,14 +39,17 @@
import org.mockito.MockedStatic;
import static java.util.Collections.emptyList;
+import static java.util.Collections.singletonList;
import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE;
import static org.apache.maven.plugin.testing.ArtifactStubFactory.setVariableValueToObject;
import static org.codehaus.mojo.versions.utils.MockUtils.mockAetherRepositorySystem;
import static org.codehaus.mojo.versions.utils.MockUtils.mockMavenSession;
import static org.codehaus.mojo.versions.utils.MockUtils.mockRepositorySystem;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasItem;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mockStatic;
/**
@@ -129,4 +137,65 @@ public void testFindANewerVersion() throws IllegalAccessException {
changeRecorder.getChanges(),
hasItem(new DefaultVersionChange("default-group", "dependency-artifact", "1.1.0-SNAPSHOT", "1.1.1")));
}
+
+ @Test
+ public void testAllowDowngrade()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException {
+ mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("artifactA", new String[] {"1.0.0", "1.0.1-SNAPSHOT"});
+ }
+ });
+ mojo.getProject()
+ .setDependencies(singletonList(DependencyBuilder.newBuilder()
+ .withGroupId("default-group")
+ .withArtifactId("artifactA")
+ .withVersion("1.0.1-SNAPSHOT")
+ .build()));
+ mojo.allowDowngrade = true;
+
+ try (MockedStatic pomHelper = mockStatic(PomHelper.class)) {
+ pomHelper
+ .when(() -> PomHelper.setDependencyVersion(
+ any(), anyString(), anyString(), anyString(), anyString(), any(Model.class)))
+ .thenReturn(true);
+ pomHelper
+ .when(() -> PomHelper.getRawModel(any(MavenProject.class)))
+ .thenReturn(mojo.getProject().getModel());
+ mojo.update(null);
+ }
+ assertThat(
+ changeRecorder.getChanges(),
+ hasItem(new DefaultVersionChange(
+ "default-group", "artifactA",
+ "1.0.1-SNAPSHOT", "1.0.0")));
+ }
+
+ @Test
+ public void testDisallowDowngrade()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, VersionRetrievalException {
+ mojo.aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() {
+ {
+ put("artifactA", new String[] {"1.0.0", "1.0.1-SNAPSHOT"});
+ }
+ });
+ mojo.getProject()
+ .setDependencies(singletonList(DependencyBuilder.newBuilder()
+ .withGroupId("default-group")
+ .withArtifactId("artifactA")
+ .withVersion("1.0.1-SNAPSHOT")
+ .build()));
+
+ try (MockedStatic pomHelper = mockStatic(PomHelper.class)) {
+ pomHelper
+ .when(() -> PomHelper.setDependencyVersion(
+ any(), anyString(), anyString(), anyString(), anyString(), any(Model.class)))
+ .thenReturn(true);
+ pomHelper
+ .when(() -> PomHelper.getRawModel(any(MavenProject.class)))
+ .thenReturn(mojo.getProject().getModel());
+ mojo.update(null);
+ }
+ assertThat(changeRecorder.getChanges(), empty());
+ }
}