diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojo.java index 78272957b3..d30114d948 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojo.java @@ -21,19 +21,33 @@ import javax.inject.Inject; +import java.util.Arrays; +import java.util.Collections; import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; 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.ArtifactVersions; +import org.codehaus.mojo.versions.api.Segment; import org.codehaus.mojo.versions.api.VersionRetrievalException; import org.codehaus.mojo.versions.api.recording.ChangeRecorder; +import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; +import org.codehaus.mojo.versions.utils.DefaultArtifactVersionCache; import org.codehaus.mojo.versions.utils.DependencyBuilder; +import org.codehaus.mojo.versions.utils.SegmentUtils; + +import static org.apache.maven.shared.utils.StringUtils.isBlank; /** * Displays any updates of the project's parent project @@ -46,6 +60,78 @@ public class DisplayParentUpdatesMojo extends AbstractVersionsDisplayMojo { public static final int MESSAGE_LENGTH = 68; + // ------------------------------ FIELDS ------------------------------ + + /** + *

If {@code skipResolution} is not set, specifies the bottom version considered + * for target version resolution. If it is a version range, the resolved version will be + * restricted by that range.

+ * + *

If {@code skipResolution} is {@code true}, will specify the target version to which + * the parent artifact will be updated.

+ * @since 2.17.0 + */ + @Parameter(property = "parentVersion") + protected String parentVersion = null; + + /** + * to update parent version by force when it is RELEASE or LATEST + * + * @since 2.17.0 + */ + @Parameter(property = "forceUpdate", defaultValue = "false") + protected boolean forceUpdate = false; + + /** + * Skips version resolution, only valid if {@code parentVersion} is set. + * Will effectively set the new parent version to the one from {@code parentVersion} + * + * @since 2.17.0 + */ + @Parameter(property = "skipResolution", defaultValue = "false") + protected boolean skipResolution = false; + + /** + *

Whether to downgrade a snapshot dependency if allowSnapshots is false + * and there exists a version within the range fulfilling the criteria.

+ *

Default false

+ * + * @since 2.17.0 + */ + @Parameter(property = "allowDowngrade", defaultValue = "false") + protected boolean allowDowngrade; + + /** + * Whether to allow the major version number to be changed. + * + * @since 2.17.0 + */ + @Parameter(property = "allowMajorUpdates", defaultValue = "true") + protected boolean allowMajorUpdates = true; + + /** + *

Whether to allow the minor version number to be changed.

+ * + *

Note: {@code false} also implies {@linkplain #allowMajorUpdates} {@code false}

+ * + * @since 2.17.0 + */ + @Parameter(property = "allowMinorUpdates", defaultValue = "true") + protected boolean allowMinorUpdates = true; + + /** + *

Whether to allow the incremental version number to be changed.

+ * + *

Note: {@code false} also implies {@linkplain #allowMajorUpdates} + * and {@linkplain #allowMinorUpdates} {@code false}

+ * + * @since 2.17.0 + */ + @Parameter(property = "allowIncrementalUpdates", defaultValue = "true") + protected boolean allowIncrementalUpdates = true; + + // -------------------------- OTHER METHODS -------------------------- + @Inject public DisplayParentUpdatesMojo( RepositorySystem repositorySystem, @@ -68,23 +154,21 @@ public void execute() throws MojoExecutionException, MojoFailureException { return; } - String currentVersion = getProject().getParent().getVersion(); - Artifact artifact = getHelper() - .createDependencyArtifact(DependencyBuilder.newBuilder() - .withGroupId(getProject().getParent().getGroupId()) - .withArtifactId(getProject().getParent().getArtifactId()) - .withVersion(currentVersion) - .withType("pom") - .build()); - + if (skipResolution && isBlank(parentVersion)) { + throw new MojoExecutionException("skipResolution is only valid if parentVersion is set"); + } + String initialVersion = Optional.ofNullable(parentVersion) + .orElse(getProject().getParent().getVersion()); ArtifactVersion artifactVersion; try { - artifactVersion = findLatestVersion(artifact, null, allowSnapshots, false); - } catch (VersionRetrievalException e) { + artifactVersion = skipResolution + ? DefaultArtifactVersionCache.of(parentVersion) + : resolveTargetVersion(initialVersion); + } catch (VersionRetrievalException | InvalidVersionSpecificationException | InvalidSegmentException e) { throw new MojoExecutionException(e.getMessage(), e); } - if (artifactVersion == null || currentVersion.equals(artifactVersion.toString())) { + if (artifactVersion == null || initialVersion.equals(artifactVersion.toString())) { logLine(false, "The parent project is the latest version:"); StringBuilder buf = new StringBuilder(MESSAGE_LENGTH); buf.append(" "); @@ -92,12 +176,12 @@ public void execute() throws MojoExecutionException, MojoFailureException { buf.append(':'); buf.append(getProject().getParent().getArtifactId()); buf.append(' '); - int padding = MESSAGE_LENGTH - currentVersion.length(); + int padding = MESSAGE_LENGTH - initialVersion.length(); while (buf.length() < padding) { buf.append('.'); } buf.append(' '); - buf.append(currentVersion); + buf.append(initialVersion); logLine(false, buf.toString()); } else { logLine(false, "The parent project has a newer version:"); @@ -108,20 +192,70 @@ public void execute() throws MojoExecutionException, MojoFailureException { buf.append(getProject().getParent().getArtifactId()); buf.append(' '); int padding = MESSAGE_LENGTH - - currentVersion.length() + - initialVersion.length() - artifactVersion.toString().length() - " -> ".length(); while (buf.length() < padding) { buf.append('.'); } buf.append(' '); - buf.append(currentVersion); + buf.append(initialVersion); buf.append(" -> "); buf.append(artifactVersion); logLine(false, buf.toString()); } } + protected ArtifactVersion resolveTargetVersion(String initialVersion) + throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, + InvalidSegmentException { + Artifact artifact = getHelper() + .createDependencyArtifact(DependencyBuilder.newBuilder() + .withGroupId(getProject().getParent().getGroupId()) + .withArtifactId(getProject().getParent().getArtifactId()) + .withVersion(initialVersion) + .withType("pom") + .build()); + + VersionRange targetVersionRange = VersionRange.createFromVersionSpec(initialVersion); + if (targetVersionRange.getRecommendedVersion() != null) { + targetVersionRange = targetVersionRange.restrict( + VersionRange.createFromVersionSpec("[" + targetVersionRange.getRecommendedVersion() + ",)")); + } + + final ArtifactVersions versions = getHelper().lookupArtifactVersions(artifact, false); + Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( + allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); + + // 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; + } + + private static Iterable reverse(T[] array) { + return Arrays.stream(array).sorted(Collections.reverseOrder()).collect(Collectors.toList()); + } + @Override protected void update(ModifiedPomXMLEventReader pom) {} } 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 882fd62713..02ecb55799 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 @@ -30,7 +30,6 @@ import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; -import org.apache.maven.plugin.logging.Log; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.repository.RepositorySystem; @@ -46,11 +45,9 @@ import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.mojo.versions.utils.DefaultArtifactVersionCache; import org.codehaus.mojo.versions.utils.DependencyBuilder; +import org.codehaus.mojo.versions.utils.SegmentUtils; -import static java.util.Optional.empty; -import static java.util.Optional.of; import static org.apache.maven.shared.utils.StringUtils.isBlank; -import static org.codehaus.mojo.versions.api.Segment.*; /** * Sets the parent version to the latest parent version. @@ -166,7 +163,8 @@ protected void update(ModifiedPomXMLEventReader pom) throw new MojoExecutionException("skipResolution is only valid if parentVersion is set"); } - String initialVersion = parentVersion == null ? getProject().getParent().getVersion() : parentVersion; + String initialVersion = Optional.ofNullable(parentVersion) + .orElse(getProject().getParent().getVersion()); try { ArtifactVersion artifactVersion = skipResolution ? DefaultArtifactVersionCache.of(parentVersion) @@ -215,27 +213,8 @@ protected ArtifactVersion resolveTargetVersion(String initialVersion) } final ArtifactVersions versions = getHelper().lookupArtifactVersions(artifact, false); - Log log = getLog(); - if (log != null && !allowIncrementalUpdates) { - log.info("Assuming allowMinorUpdates false because allowIncrementalUpdates is false."); - } - - if (log != null && !allowMinorUpdates) { - log.info("Assuming allowMajorUpdates false because allowMinorUpdates is false."); - } - - Optional unchangedSegment1 = allowMajorUpdates && allowMinorUpdates && allowIncrementalUpdates - ? empty() - : allowMinorUpdates && allowIncrementalUpdates - ? of(MAJOR) - : allowIncrementalUpdates ? of(MINOR) : of(INCREMENTAL); - if (log != null && log.isDebugEnabled()) { - log.debug(unchangedSegment1 - .map(Segment::minorTo) - .map(Segment::toString) - .orElse("ALL") + " version changes allowed"); - } - Optional unchangedSegment = unchangedSegment1; + Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( + allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates, getLog()); // currentVersion (set to parentVersion here) is not included in the version range for searching upgrades // unless we set allowDowngrade to true diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojoTest.java new file mode 100644 index 0000000000..c3cc4b3fd3 --- /dev/null +++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/DisplayParentUpdatesMojoTest.java @@ -0,0 +1,392 @@ +package org.codehaus.mojo.versions; + +/* + * Copyright MojoHaus and Contributors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import javax.xml.stream.XMLStreamException; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collections; +import java.util.HashMap; + +import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; +import org.apache.maven.artifact.versioning.VersionRange; +import org.apache.maven.model.Dependency; +import org.apache.maven.model.Model; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.testing.stubs.DefaultArtifactHandlerStub; +import org.apache.maven.project.MavenProject; +import org.apache.maven.repository.RepositorySystem; +import org.codehaus.mojo.versions.api.VersionRetrievalException; +import org.codehaus.mojo.versions.ordering.InvalidSegmentException; +import org.codehaus.mojo.versions.utils.TestUtils; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import static java.util.Collections.singleton; +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.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.hamcrest.Matchers.nullValue; +import static org.hamcrest.Matchers.stringContainsInOrder; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +public class DisplayParentUpdatesMojoTest { + private DisplayParentUpdatesMojo mojo; + + private static RepositorySystem repositorySystem; + + private static org.eclipse.aether.RepositorySystem aetherRepositorySystem; + + private Path tempDir; + + private Path tempFile; + + @BeforeClass + public static void setUpStatic() { + repositorySystem = mockRepositorySystem(); + aetherRepositorySystem = mockAetherRepositorySystem(new HashMap() { + { + put("parent-artifact", new String[] {"0.9.0", "1.0.0", "1.0.1-SNAPSHOT"}); + put("issue-670-artifact", new String[] {"0.0.1-1", "0.0.1-1-impl-SNAPSHOT"}); + 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]); + } + }); + } + + @Before + public void setUp() throws IllegalAccessException, IOException { + tempDir = TestUtils.createTempDir("display-property-updates"); + tempFile = Files.createTempFile(tempDir, "output", ""); + mojo = new DisplayParentUpdatesMojo(repositorySystem, aetherRepositorySystem, null, null) { + { + setProject(createProject()); + reactorProjects = Collections.emptyList(); + session = mockMavenSession(); + } + }; + mojo.outputFile = tempFile.toFile(); + mojo.setPluginContext(new HashMap<>()); + } + + @After + public void tearDown() throws Exception { + TestUtils.tearDownTempDir(tempDir); + } + + private MavenProject createProject() { + return new MavenProject() { + { + setModel(new Model() { + { + setGroupId("default-group"); + setArtifactId("project-artifact"); + setVersion("1.0.1-SNAPSHOT"); + } + }); + + setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("parent-artifact"); + setVersion("1.0.1-SNAPSHOT"); + } + }); + } + }; + } + + private static RepositorySystem mockRepositorySystem() { + RepositorySystem repositorySystem = mock(RepositorySystem.class); + when(repositorySystem.createDependencyArtifact(any(Dependency.class))).thenAnswer(invocation -> { + Dependency dependency = invocation.getArgument(0); + return new DefaultArtifact( + dependency.getGroupId(), + dependency.getArtifactId(), + dependency.getVersion(), + dependency.getScope(), + dependency.getType(), + dependency.getClassifier() != null ? dependency.getClassifier() : "default", + new DefaultArtifactHandlerStub("default")); + }); + return repositorySystem; + } + + @Test + public void testArtifactIdDoesNotExist() + throws MojoExecutionException, InvalidVersionSpecificationException, VersionRetrievalException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("unknown-artifact"); + setVersion("1.0.1-SNAPSHOT"); + } + }); + + Artifact artifact = new DefaultArtifact( + "default-group", + "unknown-artifact", + "1.0.1-SNAPSHOT", + SCOPE_COMPILE, + "pom", + "default", + new DefaultArtifactHandlerStub("default")); + assertThat( + mojo.findLatestVersion(artifact, VersionRange.createFromVersionSpec("1.0.1-SNAPSHOT"), null, false), + is(nullValue())); + } + + @Test + public void testParentDowngradeAllowed() throws MojoExecutionException, MojoFailureException, IOException { + mojo.allowDowngrade = true; + mojo.execute(); + assertThat( + String.join("", Files.readAllLines(tempFile)), + stringContainsInOrder( + "The parent project has a newer version:", + "default-group:parent-artifact", + "1.0.1-SNAPSHOT -> 1.0.0")); + } + + @Test + public void testParentDowngradeForbidden() throws MojoExecutionException, MojoFailureException, IOException { + mojo.allowDowngrade = false; + mojo.execute(); + assertThat( + String.join("", Files.readAllLines(tempFile)), + stringContainsInOrder( + "The parent project is the latest version:", + "default-group:parent-artifact", + "1.0.1-SNAPSHOT")); + } + + @Test + public void testParentDowngradeAllowedWithRange() + throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, + InvalidSegmentException { + mojo.allowDowngrade = true; + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("parent-artifact"); + } + }); + + ArtifactVersion newVersion = mojo.resolveTargetVersion("[1.0.1-SNAPSHOT,)"); + assertThat(newVersion, notNullValue()); + assertThat(newVersion.toString(), is("1.0.0")); + } + + @Test + public void testParentDowngradeForbiddenWithRange() + throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, + InvalidSegmentException { + mojo.allowDowngrade = false; + ArtifactVersion newVersion = mojo.resolveTargetVersion("[1.0.1-SNAPSHOT,)"); + assertThat(newVersion, nullValue()); + } + + @Test + public void testAllowSnapshots() + throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, + InvalidSegmentException { + mojo.allowSnapshots = true; + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("issue-670-artifact"); + } + }); + + ArtifactVersion newVersion = mojo.resolveTargetVersion("0.0.1-1"); + assertThat(newVersion, notNullValue()); + assertThat(newVersion.toString(), is("0.0.1-1-impl-SNAPSHOT")); + } + + @Test + public void testAllowSnapshotsWithParentVersion() throws MojoExecutionException, MojoFailureException, IOException { + mojo.allowSnapshots = true; + mojo.parentVersion = "0.0.1-1-impl-SNAPSHOT"; + mojo.execute(); + assertThat( + String.join("", Files.readAllLines(tempFile)), + stringContainsInOrder( + "The parent project is the latest version:", + "default-group:parent-artifact", + "0.0.1-1-impl-SNAPSHOT")); + } + + @Test + public void testIgnoredVersions() + throws MojoExecutionException, IllegalAccessException, VersionRetrievalException, + InvalidVersionSpecificationException, InvalidSegmentException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("parent-artifact"); + } + }); + setVariableValueToObject(mojo, "ignoredVersions", singleton("1.0.0")); + assertThat(mojo.resolveTargetVersion("0.9.0"), nullValue()); + } + + @Test + public void testSkipResolutionDowngradeUnknownVersion() + throws MojoExecutionException, MojoFailureException, IOException { + testSkipResolution("0.8.0"); + } + + @Test + public void testSkipResolutionDowngrade() throws MojoExecutionException, MojoFailureException, IOException { + testSkipResolution("0.9.0"); + } + + @Test + public void testSkipResolutionUpgradeUnknownVersion() + throws MojoExecutionException, MojoFailureException, IOException { + testSkipResolution("2.0.0"); + } + + private void testSkipResolution(String version) throws IOException, MojoExecutionException, MojoFailureException { + mojo.parentVersion = version; + mojo.skipResolution = true; + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("parent-artifact"); + setVersion("1.0.0"); + } + }); + mojo.execute(); + assertThat( + String.join("", Files.readAllLines(tempFile)), + stringContainsInOrder( + "The parent project is the latest version:", "default-group:parent-artifact", version)); + } + + @Test + public void testShouldUpgradeToSnapshot() throws MojoExecutionException, MojoFailureException, IOException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("parent-artifact"); + setVersion("0.9.0"); + } + }); + mojo.allowSnapshots = true; + mojo.parentVersion = "[0,1.0.1-SNAPSHOT]"; + mojo.execute(); + assertThat( + String.join("", Files.readAllLines(tempFile)), + stringContainsInOrder( + "The parent project has a newer version:", + "default-group:parent-artifact", + "[0,1.0.1-SNAPSHOT]", + "1.0.1-SNAPSHOT")); + } + + @Test + public void testAllowMinorUpdates() + throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, + InvalidSegmentException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("parent-artifact"); + setVersion("0.8.0"); + } + }); + mojo.allowMajorUpdates = false; + mojo.allowMinorUpdates = true; + mojo.allowIncrementalUpdates = true; + + ArtifactVersion newVersion = mojo.resolveTargetVersion("0.8.0"); + + assertThat(newVersion, notNullValue()); + assertThat(newVersion.toString(), is("0.9.0")); + } + + @Test + public void testAllowIncrementalUpdates() + throws MojoExecutionException, VersionRetrievalException, InvalidVersionSpecificationException, + InvalidSegmentException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("test-incremental"); + } + }); + mojo.allowMajorUpdates = false; + mojo.allowMinorUpdates = false; + mojo.allowIncrementalUpdates = true; + + ArtifactVersion newVersion = mojo.resolveTargetVersion("1.1.0"); + + assertThat(newVersion, notNullValue()); + assertThat(newVersion.toString(), is("1.1.1")); + } + + @Test + public void testParentVersionRange() throws MojoExecutionException, MojoFailureException, IOException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("dummy-parent2"); + setVersion("1.0"); + } + }); + mojo.allowSnapshots = true; + mojo.parentVersion = "[,3.0-!)"; + mojo.execute(); + + assertThat( + String.join("", Files.readAllLines(tempFile)), + stringContainsInOrder("The parent project has a newer version:", "dummy-parent2", "[,3.0-!)", "2.0")); + } + + @Test + public void testParentVersionRange2() + throws MojoExecutionException, XMLStreamException, MojoFailureException, IOException { + mojo.getProject().setParent(new MavenProject() { + { + setGroupId("default-group"); + setArtifactId("dummy-parent2"); + setVersion("2.0"); + } + }); + mojo.allowSnapshots = true; + mojo.parentVersion = "[,3.0-!)"; + mojo.execute(); + assertThat( + String.join("", Files.readAllLines(tempFile)), + stringContainsInOrder("The parent project is the latest version:", "dummy-parent2", "[,3.0-!)")); + } +}