From cb7ef703c4b20d305913b80ddc7f246b8b9f009c Mon Sep 17 00:00:00 2001 From: Andrzej Jarmoniuk Date: Mon, 12 Sep 2022 12:28:57 +0200 Subject: [PATCH] #610: Adding the possibility to skip version resolution if parentVersion is set --- .../invoker.properties | 2 + src/it/it-update-parent-005-issue-610/pom.xml | 16 ++++ .../verify.groovy | 3 + .../mojo/versions/UpdateParentMojo.java | 96 ++++++++++++------- .../mojo/versions/UpdateParentMojoTest.java | 50 +++++++++- 5 files changed, 128 insertions(+), 39 deletions(-) create mode 100644 src/it/it-update-parent-005-issue-610/invoker.properties create mode 100644 src/it/it-update-parent-005-issue-610/pom.xml create mode 100644 src/it/it-update-parent-005-issue-610/verify.groovy diff --git a/src/it/it-update-parent-005-issue-610/invoker.properties b/src/it/it-update-parent-005-issue-610/invoker.properties new file mode 100644 index 000000000..c46b21a9d --- /dev/null +++ b/src/it/it-update-parent-005-issue-610/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:update-parent +invoker.mavenOpts = -DparentVersion=999 -DskipResolution=true \ No newline at end of file diff --git a/src/it/it-update-parent-005-issue-610/pom.xml b/src/it/it-update-parent-005-issue-610/pom.xml new file mode 100644 index 000000000..a06e670cd --- /dev/null +++ b/src/it/it-update-parent-005-issue-610/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + + + localhost + dummy-parent4 + 70 + + + localhsot + issue-670 + 0.31-SNAPSHOT + pom + + \ No newline at end of file diff --git a/src/it/it-update-parent-005-issue-610/verify.groovy b/src/it/it-update-parent-005-issue-610/verify.groovy new file mode 100644 index 000000000..aa7ed9ebb --- /dev/null +++ b/src/it/it-update-parent-005-issue-610/verify.groovy @@ -0,0 +1,3 @@ +pom = new File( basedir, "pom.xml" ).text + +assert pom =~ /999<\/version>/ \ No newline at end of file diff --git a/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java b/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java index 50fcfdf27..bd1e78981 100644 --- a/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java @@ -24,6 +24,7 @@ import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException; import org.apache.maven.artifact.versioning.ArtifactVersion; +import org.apache.maven.artifact.versioning.DefaultArtifactVersion; import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException; import org.apache.maven.artifact.versioning.VersionRange; import org.apache.maven.plugin.MojoExecutionException; @@ -34,6 +35,8 @@ import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.mojo.versions.utils.DependencyBuilder; +import static org.apache.maven.shared.utils.StringUtils.isBlank; + /** * Sets the parent version to the latest parent version. * @@ -50,8 +53,12 @@ public class UpdateParentMojo extends AbstractVersionsUpdaterMojo // ------------------------------ FIELDS ------------------------------ /** - * Version specification to control artifact resolution. + *

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 1.0-alpha-1 */ @Parameter( property = "parentVersion" ) @@ -65,6 +72,15 @@ public class UpdateParentMojo extends AbstractVersionsUpdaterMojo @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.13.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.

@@ -87,7 +103,7 @@ public class UpdateParentMojo extends AbstractVersionsUpdaterMojo * @since 1.0-alpha-1 */ protected void update( ModifiedPomXMLEventReader pom ) - throws MojoExecutionException, MojoFailureException, XMLStreamException + throws MojoExecutionException, MojoFailureException, XMLStreamException { if ( getProject().getParent() == null ) { @@ -101,60 +117,70 @@ protected void update( ModifiedPomXMLEventReader pom ) return; } - String currentVersion = getProject().getParent().getVersion(); - String version = currentVersion; - - if ( parentVersion != null ) + if ( skipResolution && isBlank( parentVersion ) ) { - version = parentVersion; + throw new MojoExecutionException( "skipResolution is only valid if parentVersion is set" ); } - Artifact artifact = getHelper().createDependencyArtifact( DependencyBuilder.newBuilder() - .withGroupId( getProject().getParent().getGroupId() ) - .withArtifactId( getProject().getParent().getArtifactId() ) - .withVersion( version ) - .withType( "pom" ) - .build() ); - - VersionRange versionRange; + String initialVersion = parentVersion == null ? getProject().getParent().getVersion() : parentVersion; try { - versionRange = VersionRange.createFromVersionSpec( version ); - if ( versionRange.getRecommendedVersion() != null ) + ArtifactVersion artifactVersion = skipResolution ? new DefaultArtifactVersion( parentVersion ) + : resolveTargetVersion( initialVersion ); + if ( artifactVersion != null ) { - versionRange = versionRange.restrict( - VersionRange.createFromVersionSpec( "[" + versionRange.getRecommendedVersion() + ",)" ) ); + getLog().info( "Updating parent from " + getProject().getParent().getVersion() + + " to " + artifactVersion.toString() ); + + if ( PomHelper.setProjectParentVersion( pom, artifactVersion.toString() ) ) + { + if ( getLog().isDebugEnabled() ) + { + getLog().debug( "Made an update from " + getProject().getParent().getVersion() + + " to " + artifactVersion ); + } + getChangeRecorder().recordUpdate( "updateParent", getProject().getParent().getGroupId(), + getProject().getParent().getArtifactId(), getProject().getParent().getVersion(), + artifactVersion.toString() ); + } } } catch ( InvalidVersionSpecificationException e ) { - throw new MojoExecutionException( "Invalid version range specification: " + version, e ); - } - - ArtifactVersion artifactVersion; - try - { - artifactVersion = findLatestVersion( artifact, versionRange, null, false, allowDowngrade ); + throw new MojoExecutionException( "Invalid version range specification: " + initialVersion, e ); } catch ( ArtifactMetadataRetrievalException e ) { throw new MojoExecutionException( e.getMessage(), e ); } + } + + private ArtifactVersion resolveTargetVersion( String initialVersion ) + throws MojoExecutionException, ArtifactMetadataRetrievalException, InvalidVersionSpecificationException + { + Artifact artifact = getHelper().createDependencyArtifact( DependencyBuilder + .newBuilder() + .withGroupId( getProject().getParent().getGroupId() ) + .withArtifactId( getProject().getParent().getArtifactId() ) + .withVersion( initialVersion ) + .withType( "pom" ) + .build() ); - if ( !shouldApplyUpdate( artifact, currentVersion, artifactVersion, forceUpdate ) ) + VersionRange targetVersionRange = VersionRange.createFromVersionSpec( initialVersion ); + if ( targetVersionRange.getRecommendedVersion() != null ) { - return; + targetVersionRange = targetVersionRange.restrict( + VersionRange.createFromVersionSpec( "[" + targetVersionRange.getRecommendedVersion() + ",)" ) ); } - getLog().info( "Updating parent from " + currentVersion + " to " + artifactVersion.toString() ); - - if ( PomHelper.setProjectParentVersion( pom, artifactVersion.toString() ) ) + ArtifactVersion artifactVersion = findLatestVersion( artifact, targetVersionRange, null, + false, allowDowngrade ); + if ( !shouldApplyUpdate( artifact, getProject().getParent().getVersion(), artifactVersion, forceUpdate ) ) { - getLog().debug( "Made an update from " + currentVersion + " to " + artifactVersion ); - - this.getChangeRecorder().recordUpdate( "updateParent", artifact.getGroupId(), artifact.getArtifactId(), - currentVersion, artifactVersion.toString() ); + getLog().debug( "Update not applied. Exiting." ); + return null; } + return artifactVersion; } } diff --git a/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java b/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java index f73073f34..76d9191f8 100644 --- a/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java +++ b/src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java @@ -50,17 +50,15 @@ public class UpdateParentMojoTest private static RepositorySystem repositorySystem; - @SuppressWarnings( "deprecation" ) private static ArtifactMetadataSource artifactMetadataSource; @BeforeClass - @SuppressWarnings( "deprecation" ) - public static void setUpStatic() throws ArtifactMetadataRetrievalException + public static void setUpStatic() { repositorySystem = mockRepositorySystem(); artifactMetadataSource = mockArtifactMetadataSource( new HashMap() {{ - put( "parent-artifact", new String[] { "1.0.1-SNAPSHOT", "1.0.0", "0.9.0" } ); + 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( "unknown-artifact", new String[0] ); }} ); @@ -283,4 +281,48 @@ public void testIgnoredVersions() } assertThat( changeRecorder.getChanges(), is( empty() ) ); } + + @Test + public void testSkipResolutionDowngradeUnknownVersion() + { + testSkipResolution( "0.8.0" ); + } + + @Test + public void testSkipResolutionDowngrade() + { + testSkipResolution( "0.9.0" ); + } + + @Test + public void testSkipResolutionUpgradeUnknownVersion() + { + testSkipResolution( "2.0.0" ); + } + + private void testSkipResolution( String version ) + { + mojo.parentVersion = version; + mojo.skipResolution = true; + mojo.getProject().setParent( new MavenProject() + {{ + setGroupId( "default-group" ); + setArtifactId( "parent-artifact" ); + setVersion( "1.0.0" ); + }} ); + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setProjectParentVersion( any(), any() ) ) + .thenReturn( true ); + mojo.update( null ); + } + catch ( MojoExecutionException | XMLStreamException | MojoFailureException e ) + { + throw new RuntimeException( e ); + } + + assertThat( changeRecorder.getChanges(), hasItem( new VersionChange( "default-group", + "parent-artifact", "1.0.0", version ) ) ); + } }