Skip to content

Commit

Permalink
#454: Introducing "infinity-like" calculus for dependency range compu…
Browse files Browse the repository at this point in the history
…tation
  • Loading branch information
jarmoniuk authored and slawekjaranowski committed Oct 4, 2022
1 parent e7aa406 commit f7c728a
Show file tree
Hide file tree
Showing 25 changed files with 633 additions and 157 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public abstract class AbstractVersionsDependencyUpdaterMojo

/**
* A comma separated list of artifact patterns to include. Follows the pattern
* "groupId:artifactId:type:classifier:version". Designed to allow specifing the set of includes from the command
* "groupId:artifactId:type:classifier:version". Designed to allow specifying the set of includes from the command
* line. When specifying includes from the pom, use the {@link #includes} configuration instead. If this property is
* specified then the {@link # include} configuration is ignored.
*
Expand All @@ -71,7 +71,7 @@ public abstract class AbstractVersionsDependencyUpdaterMojo

/**
* A comma separated list of artifact patterns to exclude. Follows the pattern
* "groupId:artifactId:type:classifier:version". Designed to allow specifing the set of excludes from the command
* "groupId:artifactId:type:classifier:version". Designed to allow specifying the set of excludes from the command
* line. When specifying excludes from the pom, use the {@link #excludes} configuration instead. If this property is
* specified then the {@link # exclude} configuration is ignored.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -780,40 +780,47 @@ private Set<String> getVersionsInRange( Property property, PropertyVersions vers

protected String getLabel( ArtifactVersion version, AbstractVersionDetails versions )
{
String label = null;
if ( equals( version, versions.getNewestUpdate( of( MAJOR ) ) ) )
if ( equals( version, versions.getNewestUpdate( of( SUBINCREMENTAL ) ) ) )
{
label = getText( "report.latestMajor" );
return getText( "report.latestSubIncremental" );
}
else if ( equals( version, versions.getOldestUpdate( of( MAJOR ) ) ) )

if ( equals( version, versions.getOldestUpdate( of( SUBINCREMENTAL ) ) ) )
{
label = getText( "report.nextMajor" );
return getText( "report.nextVersion" );
}
else if ( equals( version, versions.getNewestUpdate( of( MINOR ) ) ) )

if ( equals( version, versions.getOldestUpdate( of( INCREMENTAL ) ) ) )
{
label = getText( "report.latestMinor" );
return getText( "report.nextIncremental" );
}
else if ( equals( version, versions.getOldestUpdate( of( MINOR ) ) ) )

if ( equals( version, versions.getNewestUpdate( of( INCREMENTAL ) ) ) )
{
label = getText( "report.nextMinor" );
return getText( "report.latestIncremental" );
}
else if ( equals( version, versions.getNewestUpdate( of( INCREMENTAL ) ) ) )

if ( equals( version, versions.getOldestUpdate( of( MINOR ) ) ) )
{
label = getText( "report.latestIncremental" );
return getText( "report.nextMinor" );
}
else if ( equals( version, versions.getOldestUpdate( of( INCREMENTAL ) ) ) )

if ( equals( version, versions.getNewestUpdate( of( MINOR ) ) ) )
{
label = getText( "report.nextIncremental" );
return getText( "report.latestMinor" );
}
else if ( equals( version, versions.getNewestUpdate( of( SUBINCREMENTAL ) ) ) )

if ( equals( version, versions.getOldestUpdate( of( MAJOR ) ) ) )
{
label = getText( "report.latestSubIncremental" );
return getText( "report.nextMajor" );
}
else if ( equals( version, versions.getOldestUpdate( of( SUBINCREMENTAL ) ) ) )

if ( equals( version, versions.getNewestUpdate( of( MAJOR ) ) ) )
{
label = getText( "report.nextVersion" );
return getText( "report.latestMajor" );
}
return label;

return "";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,7 @@ protected ArtifactVersion findLatestVersion( Artifact artifact, VersionRange ver
* @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.
Expand Down Expand Up @@ -515,6 +516,7 @@ protected boolean shouldApplyUpdate( Artifact artifact, String currentVersion, A
* @param artifact The artifact.
* @param currentVersion The current version of the artifact.
* @param updateVersion The proposed new version of the artifact.
* @param forceUpdate if true, LATEST and RELEASE versions will be overwritten with the real version
* @return <code>true</code> if the update should be applied to the pom.
* @since 2.9
*/
Expand Down Expand Up @@ -575,7 +577,7 @@ protected boolean shouldApplyUpdate( Artifact artifact, String currentVersion, A
* @param allowMajorUpdates Allow major updates
* @param allowMinorUpdates Allow minor updates
* @param allowIncrementalUpdates Allow incremental updates
* @return Returns the segment (0-based) that is unchangable. If any segment can change, returns -1.
* @return Returns the segment (0-based) that is unchangeable. If any segment can change, returns -1.
*/
protected Optional<Segment> determineUnchangedSegment( boolean allowMajorUpdates, boolean allowMinorUpdates,
boolean allowIncrementalUpdates )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public class DependencyUpdatesReport extends AbstractVersionsReport
protected boolean processDependencyManagement;

/**
* Whether to process the depdendencyManagement part transitive or not.
* Whether to process the dependencyManagement part transitive or not.
* In case of <code>&lt;type&gt;pom&lt;/type&gt;</code>and
* <code>&lt;scope&gt;import&lt;/scope&gt;</code> this means
* by default to report also the imported dependencies.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public class DisplayDependencyUpdatesMojo
private boolean processDependencyManagement;

/**
* Whether to process the depdendencyManagement part transitive or not.
* Whether to process the dependencyManagement part transitive or not.
* In case of <code>&lt;type&gt;pom&lt;/type&gt;</code>and
* <code>&lt;scope&gt;import&lt;/scope&gt;</code> this means
* by default to report also the imported dependencies.
Expand Down Expand Up @@ -691,12 +691,28 @@ private DependencyManagement getProjectDependencyManagement( MavenProject projec

private Optional<Segment> calculateUpdateScope()
{
return !allowAnyUpdates
? allowMajorUpdates ? of( MAJOR )
: allowMinorUpdates ? of( MINOR )
: allowIncrementalUpdates ? of( INCREMENTAL )
: empty()
: empty();
if ( !allowIncrementalUpdates && !allowMinorUpdates && !allowMajorUpdates && !allowAnyUpdates )
{
throw new IllegalArgumentException( "One of: allowAnyUpdates, allowMajorUpdates, allowMinorUpdates, "
+ "allowIncrementalUpdates must be true" );
}

if ( allowAnyUpdates && allowMajorUpdates && allowMinorUpdates )
{
return empty();
}

if ( allowMajorUpdates && allowMinorUpdates )
{
return of( MAJOR );
}

if ( allowMinorUpdates )
{
return of( MINOR );
}

return of( INCREMENTAL );
}

private void logUpdates( Map<Dependency, ArtifactVersions> updates, String section )
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/codehaus/mojo/versions/SetMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -402,9 +402,10 @@ public void execute() throws MojoExecutionException, MojoFailureException

/**
* Returns the incremented version, with the nextSnapshotIndexToIncrement indicating the 1-based index,
* conunting from the left, or the most major version component, of the version string.
* from the left, or the most major version component, of the version string.
*
* @param version input version
* @param nextSnapshotIndexToIncrement 1-based segment number to be incremented
* @return version with the incremented index specified by nextSnapshotIndexToIncrement or last index
* @throws MojoExecutionException thrown if the input parameters are invalid
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,13 @@
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.Restriction;
import org.apache.maven.artifact.versioning.VersionRange;
import org.codehaus.mojo.versions.ordering.BoundArtifactVersion;
import org.codehaus.mojo.versions.ordering.InvalidSegmentException;
import org.codehaus.mojo.versions.ordering.VersionComparator;

import static java.util.Optional.empty;
import static java.util.Optional.of;
import static org.codehaus.mojo.versions.api.Segment.SUBINCREMENTAL;

/**
* Base class for {@link org.codehaus.mojo.versions.api.VersionDetails}.
Expand Down Expand Up @@ -171,7 +173,6 @@ private static <T> Iterable<T> reverse( T[] array )
public final ArtifactVersion getNewestVersion( VersionRange versionRange, Restriction restriction,
boolean includeSnapshots, boolean allowDowngrade )
{
final VersionComparator versionComparator = getVersionComparator();
// reverse( getVersions( ... ) ) will contain versions sorted from latest to oldest,
// so we only need to find the first candidate fulfilling the criteria
for ( ArtifactVersion candidate : reverse( getVersions( includeSnapshots ) ) )
Expand Down Expand Up @@ -260,13 +261,22 @@ public final ArtifactVersion[] getNewerVersions( String versionString, Optional<
throws InvalidSegmentException
{
ArtifactVersion currentVersion = new DefaultArtifactVersion( versionString );
ArtifactVersion lowerBound =
allowDowngrade ? getLowerBoundArtifactVersion( currentVersion, upperBoundSegment ) : currentVersion;
ArtifactVersion upperBound = !upperBoundSegment.isPresent() ? null
: getVersionComparator().incrementSegment( lowerBound, upperBoundSegment.get() );
ArtifactVersion lowerBound = allowDowngrade
? getLowerBound( currentVersion, upperBoundSegment )
.map( DefaultArtifactVersion::new )
.orElse( null )
: currentVersion;
ArtifactVersion upperBound =
!upperBoundSegment.isPresent()
? null
: upperBoundSegment
.map( s -> (ArtifactVersion) new BoundArtifactVersion( currentVersion,
s.isMajorTo( SUBINCREMENTAL )
? Segment.of( s.value() + 1 )
: s ) )
.orElse( null );

Restriction restriction = new Restriction( lowerBound, allowDowngrade, upperBound, allowDowngrade );
// TODO shouldn't allowDowngrade boolean be passed to this call ?
return getVersions( restriction, includeSnapshots );
}

Expand Down Expand Up @@ -346,7 +356,8 @@ public final ArtifactVersion getOldestUpdate( ArtifactVersion currentVersion, Op
{
try
{
return getOldestVersion( restrictionFor( currentVersion, updateScope ), includeSnapshots );
return getOldestVersion( getVersionComparator().restrictionFor( currentVersion, updateScope ),
includeSnapshots );
}
catch ( InvalidSegmentException e )
{
Expand All @@ -359,7 +370,8 @@ public final ArtifactVersion getNewestUpdate( ArtifactVersion currentVersion, Op
{
try
{
return getNewestVersion( restrictionFor( currentVersion, updateScope ), includeSnapshots );
return getNewestVersion( getVersionComparator().restrictionFor( currentVersion, updateScope ),
includeSnapshots );
}
catch ( InvalidSegmentException e )
{
Expand All @@ -372,7 +384,8 @@ public final ArtifactVersion[] getAllUpdates( ArtifactVersion currentVersion, Op
{
try
{
return getVersions( restrictionFor( currentVersion, updateScope ), includeSnapshots );
return getVersions( getVersionComparator().restrictionFor( currentVersion, updateScope ),
includeSnapshots );
}
catch ( InvalidSegmentException e )
{
Expand Down Expand Up @@ -433,32 +446,12 @@ public ArtifactVersion[] getAllUpdates( VersionRange versionRange, boolean inclu
return getVersions( versionRange, restriction, includeSnapshots );
}

/**
* Returns the lower bound version based on the given artifact version
* and the lowest unchanged segment index (0-based); -1 means that the whole version string can be changed,
* implying that there is also no string designation of the lower bound version.
*
* @param version {@link ArtifactVersion} object specyfing the verion for which the lower bound is being computed
* @param unchangedSegment first segment not to be changed; empty() means any segment can change
* @return {@link ArtifactVersion} the lowest artifact version with the given segment held or null if no such
* version can be found
* @throws InvalidSegmentException if the requested segment is outside the bounds (less than 1 or greater than
* the segment count)
*/
protected ArtifactVersion getLowerBoundArtifactVersion( ArtifactVersion version,
Optional<Segment> unchangedSegment )
throws InvalidSegmentException
{
Optional<String> lowerBound = getLowerBound( version, unchangedSegment );
return lowerBound.map( DefaultArtifactVersion::new ).orElse( null );
}

/**
* Returns the string designation of the lower bound version based on the given artifact version
* and the lowest unchanged segment index (0-based); -1 means that the whole version string can be changed,
* implying that there is also no string designation of the lower bound version.
*
* @param version {@link ArtifactVersion} object specyfing the verion for which the lower bound is being computed
* @param version {@link ArtifactVersion} object specifying the version for which the lower bound is being computed
* @param unchangedSegment first segment not to be changed; empty() means anything can change
* @return {@link Optional} string containing the lowest artifact version with the given segment held
* @throws InvalidSegmentException if the requested segment is outside of the bounds (less than 1 or greater than
Expand Down Expand Up @@ -527,26 +520,4 @@ private boolean isVersionInRestriction( Restriction restriction, ArtifactVersion
}
return ( includeLower || lower != 0 ) && ( includeUpper || upper != 0 );
}

/**
* Helper method to get the artifact boundaries for computing updates
*
* @param currentVersion The current version.
* @param scope scope of the restriction or Optional.empty() for no restriction
* @return {@linkplain Restriction} object based on the arguments
* @throws InvalidSegmentException if {@code segment} ∉ [0, segmentCount)
*/
protected Restriction restrictionFor( ArtifactVersion currentVersion, Optional<Segment> scope )
throws InvalidSegmentException
{
VersionComparator versionComparator = getVersionComparator();
ArtifactVersion lowerBound = scope.isPresent() && scope.get().value() < Segment.SUBINCREMENTAL.value()
? versionComparator.incrementSegment( currentVersion, scope.get() )
: currentVersion;
ArtifactVersion upperBound = scope.isPresent() && scope.get().value() > Segment.MAJOR.value()
? versionComparator.incrementSegment( currentVersion, Segment.of( scope.get().value() - 1 ) )
: null;
return new Restriction( lowerBound, lowerBound != currentVersion,
upperBound, false );
}
}
3 changes: 2 additions & 1 deletion src/main/java/org/codehaus/mojo/versions/api/PomHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -1476,9 +1476,10 @@ public static String getGroupId( Model model )
* Finds the local root of the specified project.
*
* @param project The project to find the local root for.
* @param builder {@linkplain MavenProjectBuilder} object
* @param localRepository the local repo.
* @param globalProfileManager the global profile manager.
* @param logger The logger to log to.
* @param logger The logger to log tog
* @return The local root (note this may be the project passed as an argument).
*/
public static MavenProject getLocalRoot( MavenProjectBuilder builder, MavenProject project,
Expand Down
31 changes: 15 additions & 16 deletions src/main/java/org/codehaus/mojo/versions/api/Segment.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,7 @@
*/
public enum Segment implements Comparable<Segment>
{
MAJOR( 0 ), MINOR( 1 ), INCREMENTAL( 2 ), SUBINCREMENTAL( 3 );

private final int index;

Segment( int index )
{
this.index = index;
}
MAJOR, MINOR, INCREMENTAL, SUBINCREMENTAL;

/**
* Returns the 0-based sendex index
Expand All @@ -42,20 +35,26 @@ public enum Segment implements Comparable<Segment>
*/
public int value()
{
return index;
return ordinal();
}

public static Segment of( int index )
{
switch ( index )
if ( index < 0 || index > 3 )
{
case 0: return MAJOR;
case 1: return MINOR;
case 2: return INCREMENTAL;
case 3: return SUBINCREMENTAL;
default:
throw new IllegalArgumentException( "Wrong segment index: " + index );
throw new IllegalArgumentException( "Wrong segment index: " + index );
}
return values()[index];
}

/**
* Returns true if the given segment is more major than the other
* @param other other segment to compare
* @return true if the given segment is more major
*/
public boolean isMajorTo( Segment other )
{
return value() < other.value();
}

@Override
Expand Down
Loading

0 comments on commit f7c728a

Please sign in to comment.