Skip to content

Commit

Permalink
mojohaus#499: Add segment selection to update parent
Browse files Browse the repository at this point in the history
  • Loading branch information
jarmoniuk committed Oct 5, 2022
1 parent 720ff9e commit ad707a6
Show file tree
Hide file tree
Showing 5 changed files with 122 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -345,32 +345,10 @@ public void execute()
protected ArtifactVersion findLatestVersion( Artifact artifact, VersionRange versionRange,
Boolean allowingSnapshots, boolean usePluginRepositories )
throws ArtifactMetadataRetrievalException, MojoExecutionException
{
return findLatestVersion( artifact, versionRange, allowingSnapshots, usePluginRepositories, false );
}

/**
* Finds the latest version of the specified artifact that matches the version range.
*
* @param artifact The artifact.
* @param versionRange The version range.
* @param allowingSnapshots <code>null</code> for no override, otherwise the local override to apply.
* @param usePluginRepositories Use plugin repositories
* @param allowDowngrade whether downgrades should be allowed
* @return The latest version of the specified artifact that matches the specified version range or
* <code>null</code> if no matching version could be found.
* @throws ArtifactMetadataRetrievalException If the artifact metadata could not be found.
* @throws MojoExecutionException if something goes wrong.
* @since 1.0-alpha-1
*/
protected ArtifactVersion findLatestVersion( Artifact artifact, VersionRange versionRange,
Boolean allowingSnapshots, boolean usePluginRepositories,
boolean allowDowngrade )
throws ArtifactMetadataRetrievalException, MojoExecutionException
{
boolean includeSnapshots = allowingSnapshots != null ? allowingSnapshots : this.allowSnapshots;
final ArtifactVersions artifactVersions = getHelper().lookupArtifactVersions( artifact, usePluginRepositories );
return artifactVersions.getNewestVersion( versionRange, null, includeSnapshots, allowDowngrade );
return artifactVersions.getNewestVersion( versionRange, null, includeSnapshots, false );
}

/**
Expand Down
75 changes: 65 additions & 10 deletions src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
import javax.inject.Inject;
import javax.xml.stream.XMLStreamException;

import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;
import java.util.stream.Collectors;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.manager.WagonManager;
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
Expand All @@ -37,7 +42,10 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.mojo.versions.api.ArtifactVersions;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.api.Segment;
import org.codehaus.mojo.versions.ordering.InvalidSegmentException;
import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
import org.codehaus.mojo.versions.utils.DependencyBuilder;

Expand Down Expand Up @@ -95,6 +103,30 @@ public class UpdateParentMojo extends AbstractVersionsUpdaterMojo
defaultValue = "false" )
protected boolean allowDowngrade;

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

/**
* Whether to allow the minor version number to be changed.
*
* @since 1.2
*/
@Parameter( property = "allowMinorUpdates", defaultValue = "true" )
protected boolean allowMinorUpdates = true;

/**
* Whether to allow the incremental version number to be changed.
*
* @since 1.2
*/
@Parameter( property = "allowIncrementalUpdates", defaultValue = "true" )
protected boolean allowIncrementalUpdates = true;

// -------------------------- OTHER METHODS --------------------------

@Inject
Expand Down Expand Up @@ -135,10 +167,13 @@ 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 = parentVersion == null
? getProject().getParent().getVersion()
: parentVersion;
try
{
ArtifactVersion artifactVersion = skipResolution ? new DefaultArtifactVersion( parentVersion )
ArtifactVersion artifactVersion = skipResolution
? new DefaultArtifactVersion( parentVersion )
: resolveTargetVersion( initialVersion );
if ( artifactVersion != null )
{
Expand Down Expand Up @@ -166,10 +201,15 @@ protected void update( ModifiedPomXMLEventReader pom )
{
throw new MojoExecutionException( e.getMessage(), e );
}
catch ( InvalidSegmentException e )
{
throw new MojoExecutionException( "Invalid segment specification for version " + initialVersion, e );
}
}

private ArtifactVersion resolveTargetVersion( String initialVersion )
throws MojoExecutionException, ArtifactMetadataRetrievalException, InvalidVersionSpecificationException
protected ArtifactVersion resolveTargetVersion( String initialVersion )
throws MojoExecutionException, ArtifactMetadataRetrievalException, InvalidVersionSpecificationException,
InvalidSegmentException
{
Artifact artifact = getHelper().createDependencyArtifact( DependencyBuilder
.newBuilder()
Expand All @@ -186,14 +226,29 @@ private ArtifactVersion resolveTargetVersion( String initialVersion )
VersionRange.createFromVersionSpec( "[" + targetVersionRange.getRecommendedVersion() + ",)" ) );
}

ArtifactVersion artifactVersion = findLatestVersion( artifact, targetVersionRange, null,
false, allowDowngrade );
if ( !shouldApplyUpdate( artifact, getProject().getParent().getVersion(), artifactVersion, forceUpdate ) )
final ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false );
Optional<Segment> unchangedSegment = determineUnchangedSegment( allowMajorUpdates, allowMinorUpdates,
allowIncrementalUpdates );

// 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 ) ) )
{
getLog().debug( "Update not applied. Exiting." );
return null;
if ( ( !isBlank( parentVersion ) || allowDowngrade || targetVersionRange == null
|| ArtifactVersions.isVersionInRange( candidate, targetVersionRange ) )
&& shouldApplyUpdate( artifact, getProject().getParent().getVersion(), candidate, forceUpdate ) )
{
return candidate;
}

}
return artifactVersion;
getLog().info( "No versions found" );
return null;
}

private static <T> Iterable<T> reverse( T[] array )
{
return Arrays.stream( array ).sorted( Collections.reverseOrder() ).collect( Collectors.toList() );
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ public final ArtifactVersion getNewestVersion( VersionRange versionRange, Restri
return null;
}


public final ArtifactVersion getNewestVersion( Restriction restriction, boolean includeSnapshots )
{
return getNewestVersion( null, restriction, includeSnapshots );
Expand Down Expand Up @@ -507,17 +508,18 @@ protected Optional<String> getLowerBound( ArtifactVersion version, Optional<Segm
*/
private boolean isVersionInRestriction( Restriction restriction, ArtifactVersion candidate )
{
ArtifactVersion lowerBound = restriction.getLowerBound();
ArtifactVersion upperBound = restriction.getUpperBound();
boolean includeLower = restriction.isLowerBoundInclusive();
boolean includeUpper = restriction.isUpperBoundInclusive();
final VersionComparator versionComparator = getVersionComparator();
int lower = lowerBound == null ? -1 : versionComparator.compare( lowerBound, candidate );
int upper = upperBound == null ? +1 : versionComparator.compare( upperBound, candidate );
if ( lower > 0 || upper < 0 )
{
return false;
}
return ( includeLower || lower != 0 ) && ( includeUpper || upper != 0 );
boolean satisfiesLowerBound = restriction.getLowerBound() == null
? true
: restriction.isLowerBoundInclusive()
? restriction.getLowerBound().compareTo( candidate ) <= 0
: restriction.getLowerBound().compareTo( candidate ) < 0;

boolean satisfiesUpperBound = restriction.getUpperBound() == null
? true
: restriction.isUpperBoundInclusive()
? restriction.getUpperBound().compareTo( candidate ) >= 0
: restriction.getUpperBound().compareTo( candidate ) > 0;

return satisfiesLowerBound && satisfiesUpperBound;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ ArtifactVersion getNewestVersion( ArtifactVersion lowerBound, ArtifactVersion up
*/
ArtifactVersion getNewestVersion( VersionRange versionRange, boolean includeSnapshots );


/**
* Returns the oldest version within the specified version range or <code>null</code> if no such version exists.
*
Expand Down
86 changes: 41 additions & 45 deletions src/test/java/org/codehaus/mojo/versions/UpdateParentMojoTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.apache.maven.artifact.metadata.ArtifactMetadataRetrievalException;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.resolver.ArtifactResolver;
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;
Expand All @@ -20,6 +21,7 @@
import org.apache.maven.repository.RepositorySystem;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.change.VersionChange;
import org.codehaus.mojo.versions.ordering.InvalidSegmentException;
import org.codehaus.mojo.versions.utils.TestChangeRecorder;
import org.junit.Before;
import org.junit.BeforeClass;
Expand All @@ -34,6 +36,7 @@
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasItem;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -174,69 +177,46 @@ public void testParentDowngradeForbidden()

@Test
public void testParentDowngradeAllowedWithRange()
throws MojoExecutionException, XMLStreamException, MojoFailureException
throws MojoExecutionException, ArtifactMetadataRetrievalException,
InvalidVersionSpecificationException, InvalidSegmentException
{
mojo.allowDowngrade = true;
mojo.getProject().setParent( new MavenProject()
{{
setGroupId( "default-group" );
setArtifactId( "parent-artifact" );
setVersion( "[1.0.1-SNAPSHOT,)" );
}} );

try ( MockedStatic<PomHelper> pomHelper = mockStatic( PomHelper.class ) )
{
pomHelper.when( () -> PomHelper.setProjectParentVersion( any(), any() ) )
.thenReturn( true );
mojo.update( null );
}
assertThat( changeRecorder.getChanges(),
hasItem( new VersionChange( "default-group", "parent-artifact", "[1.0.1-SNAPSHOT,)",
"1.0.0" ) ) );
ArtifactVersion newVersion = mojo.resolveTargetVersion( "[1.0.1-SNAPSHOT,)" );
assertThat( newVersion, notNullValue() );
assertThat( newVersion.toString(), is( "1.0.0" ) );
}

@Test
public void testParentDowngradeForbiddenWithRange()
throws MojoExecutionException, XMLStreamException, MojoFailureException
throws MojoExecutionException, ArtifactMetadataRetrievalException,
InvalidVersionSpecificationException, InvalidSegmentException
{
mojo.allowDowngrade = false;
mojo.getProject().setParent( new MavenProject()
{{
setGroupId( "default-group" );
setArtifactId( "parent-artifact" );
setVersion( "[1.0.1-SNAPSHOT,)" );
}} );

try ( MockedStatic<PomHelper> pomHelper = mockStatic( PomHelper.class ) )
{
pomHelper.when( () -> PomHelper.setProjectParentVersion( any(), any() ) )
.thenReturn( true );
mojo.update( null );
}
assertThat( changeRecorder.getChanges(), is( empty() ) );
ArtifactVersion newVersion = mojo.resolveTargetVersion( "[1.0.1-SNAPSHOT,)" );
assertThat( newVersion, nullValue() );
}

@Test
public void testAllowSnapshots()
throws MojoExecutionException, XMLStreamException, MojoFailureException
throws MojoExecutionException, ArtifactMetadataRetrievalException,
InvalidVersionSpecificationException, InvalidSegmentException
{
mojo.allowSnapshots = true;
mojo.getProject().setParent( new MavenProject()
{{
setGroupId( "default-group" );
setArtifactId( "issue-670-artifact" );
setVersion( "0.0.1-1" );
}} );

try ( MockedStatic<PomHelper> pomHelper = mockStatic( PomHelper.class ) )
{
pomHelper.when( () -> PomHelper.setProjectParentVersion( any(), any() ) )
.thenReturn( true );
mojo.update( null );
}
assertThat( changeRecorder.getChanges(), hasItem( new VersionChange( "default-group",
"issue-670-artifact", "0.0.1-1",
"0.0.1-1-impl-SNAPSHOT" ) ) );
ArtifactVersion newVersion = mojo.resolveTargetVersion( "0.0.1-1" );
assertThat( newVersion, notNullValue() );
assertThat( newVersion.toString(), is( "0.0.1-1-impl-SNAPSHOT" ) );
}

@Test
Expand Down Expand Up @@ -265,21 +245,16 @@ public void testAllowSnapshotsWithParentVersion()

@Test
public void testIgnoredVersions()
throws MojoExecutionException, XMLStreamException, MojoFailureException, IllegalAccessException
throws MojoExecutionException, IllegalAccessException,
ArtifactMetadataRetrievalException, InvalidVersionSpecificationException, InvalidSegmentException
{
mojo.getProject().setParent( new MavenProject()
{{
setGroupId( "default-group" );
setArtifactId( "parent-artifact" );
setVersion( "0.9.0" );
}} );
setVariableValueToObject( mojo, "ignoredVersions", singleton( "1.0.0" ) );
try ( MockedStatic<PomHelper> pomHelper = mockStatic( PomHelper.class ) )
{
pomHelper.when( () -> PomHelper.setProjectParentVersion( any(), any() ) ).thenReturn( true );
mojo.update( null );
}
assertThat( changeRecorder.getChanges(), is( empty() ) );
assertThat( mojo.resolveTargetVersion( "0.9.0" ), nullValue() );
}

@Test
Expand Down Expand Up @@ -346,4 +321,25 @@ public void testShouldUpgradeToSnapshot() throws MojoExecutionException, XMLStre
hasItem( new VersionChange( "default-group", "parent-artifact", "0.9.0",
"1.0.1-SNAPSHOT" ) ) );
}

@Test
public void testAllowMinorUpdates()
throws MojoExecutionException, ArtifactMetadataRetrievalException,
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 = false;

ArtifactVersion newVersion = mojo.resolveTargetVersion( "0.8.0" );

assertThat( newVersion, notNullValue() );
assertThat( newVersion.toString(), is( "0.9.0" ) );
}
}

0 comments on commit ad707a6

Please sign in to comment.