Skip to content

Commit

Permalink
display versions outside range with star
Browse files Browse the repository at this point in the history
  • Loading branch information
sultan committed Nov 23, 2022
1 parent acc5dbd commit 47a3327
Show file tree
Hide file tree
Showing 5 changed files with 141 additions and 102 deletions.
Expand Up @@ -20,11 +20,14 @@
*/

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

import org.apache.maven.artifact.ArtifactUtils;
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.Restriction;
import org.apache.maven.artifact.versioning.VersionRange;
import org.codehaus.mojo.versions.ordering.BoundArtifactVersion;
Expand Down Expand Up @@ -441,7 +444,7 @@ protected Optional<String> getLowerBound( ArtifactVersion version, Optional<Segm
* @param candidate the version to check.
* @return true if the candidate version is within the range of the restriction parameter.
*/
private boolean isVersionInRestriction( Restriction restriction, ArtifactVersion candidate )
public boolean isVersionInRestriction( Restriction restriction, ArtifactVersion candidate )
{
ArtifactVersion lowerBound = restriction.getLowerBound();
ArtifactVersion upperBound = restriction.getUpperBound();
Expand All @@ -456,4 +459,47 @@ private boolean isVersionInRestriction( Restriction restriction, ArtifactVersion
}
return ( includeLower || lower != 0 ) && ( includeUpper || upper != 0 );
}

public final ArtifactVersion getReportNewestUpdate( Optional<Segment> updateScope )
{
return getArtifactVersionStream( updateScope )
.min( Collections.reverseOrder( getVersionComparator() ) )
.orElse( null );
}

public final ArtifactVersion[] getReportUpdates( Optional<Segment> updateScope )
{
return getArtifactVersionStream( updateScope )
.sorted( getVersionComparator() )
.distinct()
.toArray( ArtifactVersion[]::new );
}

private Stream<ArtifactVersion> getArtifactVersionStream( Optional<Segment> updateScope )
{
if ( isCurrentVersionDefined() )
{
try
{
// one range spec can have multiple restrictions, and multiple 'lower bound', we want the highest one.
// [1.0,2.0),[3.0,4.0) -> 3.0
ArtifactVersion highestLowerBound = VersionRange.createFromVersionSpec( getCurrentVersion().toString() )
.getRestrictions().stream().map( Restriction::getLowerBound ).filter( Objects::nonNull )
.max( getVersionComparator() ).orElse( getCurrentVersion() );
Restriction restriction = getVersionComparator().restrictionFor( highestLowerBound, updateScope );

// TODO filter snaphost only once not twice
boolean includeSnapshots1 = isIncludeSnapshots();
return Arrays.stream( getVersions( includeSnapshots1 ) )
.filter( candidate -> includeSnapshots1 || !ArtifactUtils.isSnapshot( candidate.toString() ) )
.filter( candidate -> isVersionInRestriction( restriction, candidate ) );
}
catch ( InvalidVersionSpecificationException | InvalidSegmentException ignored )
{
// ignored
}
}
return Stream.empty();
}

}
Expand Up @@ -78,6 +78,7 @@ public ArtifactVersions( Artifact artifact, List<ArtifactVersion> versions, Vers
this.versionComparator = versionComparator;
this.versions = new TreeSet<>( versionComparator );
this.versions.addAll( versions );
// TODO owerwrite if null by version from elsewhere
if ( artifact.getVersion() != null )
{
setCurrentVersion( artifact.getVersion() );
Expand Down
Expand Up @@ -20,10 +20,16 @@
*/

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.artifact.versioning.Restriction;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
Expand All @@ -32,6 +38,8 @@
import org.codehaus.mojo.versions.api.ArtifactVersions;
import org.codehaus.mojo.versions.api.ArtifactVersionsCache;
import org.codehaus.mojo.versions.api.ReportRenderer;
import org.codehaus.mojo.versions.api.Segment;
import org.codehaus.mojo.versions.ordering.BoundArtifactVersion;
import org.codehaus.plexus.i18n.I18N;

import static java.util.Optional.empty;
Expand Down Expand Up @@ -59,10 +67,10 @@ public abstract class AbstractVersionsReportRenderer<T> extends VersionsReportRe
protected T model;

protected ArtifactVersionsCache newestUpdateCache
= new ArtifactVersionsCache( AbstractVersionDetails::getNewestUpdate );
= new ArtifactVersionsCache( AbstractVersionDetails::getReportNewestUpdate );

protected ArtifactVersionsCache allUpdatesCache
= new ArtifactVersionsCache( AbstractVersionDetails::getAllUpdates );
= new ArtifactVersionsCache( AbstractVersionDetails::getReportUpdates );

protected AbstractVersionsReportRenderer( I18N i18n, Sink sink, Locale locale, String bundleName, T model )
{
Expand Down Expand Up @@ -207,9 +215,9 @@ protected void renderSummaryTableHeader( boolean hasScope, boolean hasType )
"report.latestIncremental", "report.latestMinor", "report.latestMajor" );
}

protected void renderSummaryTableRow( Dependency artifact, ArtifactVersions details,
boolean includeScope )
protected void renderSummaryTableRow( Dependency artifact, ArtifactVersions details, boolean includeScope )
{
details.setCurrentVersion( artifact.getVersion() );
ArtifactVersion[] allUpdates = allUpdatesCache.get( details, empty() );
boolean upToDate = allUpdates == null || allUpdates.length == 0;

Expand Down Expand Up @@ -392,27 +400,7 @@ else if ( newestUpdateCache.get( details, of( MAJOR ) ) != null )
sink.text( getText( "report.updateVersions" ) );
sink.tableHeaderCell_();
sink.tableCell( cellAttributes );
for ( int i = 0; i < allUpdates.length; i++ )
{
if ( i > 0 )
{
sink.lineBreak();
}
String label = getLabel( allUpdates[i], details );
if ( label != null )
{
safeBold();
}
sink.text( allUpdates[i].toString() );
if ( label != null )
{
safeBold_();
sink.nonBreakingSpace();
safeItalic();
sink.text( label );
safeItalic_();
}
}
sinkVersions( details, allUpdates );
sink.tableCell_();
sink.tableRow_();
}
Expand Down Expand Up @@ -462,4 +450,78 @@ protected String getLabel( ArtifactVersion version, AbstractVersionDetails detai

return null;
}

private List<Restriction> getArtifactVersionRange( AbstractVersionDetails details )
{
String spec = details.getCurrentVersion().toString();
try
{
VersionRange range = VersionRange.createFromVersionSpec( spec );
return range.getRestrictions().stream().map(
restriction -> new Restriction(
restriction.getLowerBound() == null ? null
: new BoundArtifactVersion( restriction.getLowerBound(), Segment.of(
details.getVersionComparator().getSegmentCount( restriction.getLowerBound() ) - 0 ) ),
restriction.isLowerBoundInclusive(),
restriction.getLowerBound() == null ? null
: new BoundArtifactVersion( restriction.getLowerBound(), Segment.of(
details.getVersionComparator().getSegmentCount( restriction.getLowerBound() ) - 1 ) ),
restriction.isUpperBoundInclusive() )
).collect( Collectors.toList() );
}
catch ( InvalidVersionSpecificationException ignored )
{
// ignored
}
return Collections.EMPTY_LIST;
}

protected void sinkVersions( AbstractVersionDetails details, ArtifactVersion[] allUpdates )
{
List<Restriction> versionRange = getArtifactVersionRange( details );
boolean someNotAllowed = false;
for ( int i = 0; i < allUpdates.length; i++ )
{
if ( i > 0 )
{
sink.lineBreak();
}
// if candidate version in range, display no star.
ArtifactVersion candidate = allUpdates[i];
boolean allowed = versionRange.stream().anyMatch( restriction ->
details.isVersionInRestriction( restriction, candidate ) );
String label = getLabel( allUpdates[i], details );
if ( !allowed )
{
sink.text( "* " );
someNotAllowed = true;
}
if ( allowed && label != null )
{
safeBold();
}
sink.text( allUpdates[i].toString() );
if ( label != null )
{
if ( allowed )
{
safeBold_();
}
sink.nonBreakingSpace();
safeItalic();
sink.text( label );
safeItalic_();
}
}
if ( someNotAllowed )
{
sink.lineBreak();
sink.lineBreak();
sink.text( "* " );
safeItalic();
sink.text( getText( "report.excludedVersion" ) );
safeItalic_();
}
}

}
Expand Up @@ -19,15 +19,11 @@
* under the License.
*/

import java.util.HashSet;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.apache.maven.artifact.ArtifactUtils;
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.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributes;
import org.apache.maven.doxia.sink.impl.SinkEventAttributeSet;
Expand Down Expand Up @@ -261,52 +257,12 @@ else if ( newestUpdateCache.get( details, of( MAJOR ) ) != null )
sink.tableRow_();
if ( !upToDate )
{
Set<String> rangeVersions = getVersionsInRange( property, details, allUpdates );
sink.tableRow();
sink.tableHeaderCell( headerAttributes );
sink.text( getText( "report.updateVersions" ) );
sink.tableHeaderCell_();
sink.tableCell( cellAttributes );
boolean someNotAllowed = false;
for ( int i = 0; i < allUpdates.length; i++ )
{
if ( i > 0 )
{
sink.lineBreak();
}
boolean allowed = ( rangeVersions.contains( allUpdates[i].toString() ) );
String label = getLabel( allUpdates[i], details );
if ( !allowed )
{
sink.text( "* " );
someNotAllowed = true;
}
if ( allowed && label != null )
{
safeBold();
}
sink.text( allUpdates[i].toString() );
if ( label != null )
{
if ( allowed )
{
safeBold_();
}
sink.nonBreakingSpace();
safeItalic();
sink.text( label );
safeItalic_();
}
}
if ( someNotAllowed )
{
sink.lineBreak();
sink.lineBreak();
sink.text( "* " );
safeItalic();
sink.text( getText( "report.excludedVersion" ) );
safeItalic_();
}
sinkVersions( details, allUpdates );
sink.tableCell_();
sink.tableRow_();
}
Expand All @@ -315,7 +271,10 @@ else if ( newestUpdateCache.get( details, of( MAJOR ) ) != null )
sink.text( getText( "report.versionRange" ) );
sink.tableHeaderCell_();
sink.tableCell( cellAttributes );
sink.text( StringUtils.isEmpty( property.getVersion() ) ? "[,)" : property.getVersion() );
// TODO property.getVersion() always returns null or empty string, why ?
sink.text( !StringUtils.isEmpty( property.getVersion() ) ? property.getVersion()
: !StringUtils.isEmpty( details.getCurrentVersion().toString() )
? details.getCurrentVersion().toString() : "[,)" );
sink.tableCell_();
sink.tableRow_();
sink.tableRow();
Expand Down Expand Up @@ -355,36 +314,6 @@ else if ( newestUpdateCache.get( details, of( MAJOR ) ) != null )
sink.table_();
}

@SuppressWarnings( "checkstyle:MethodLength" )
protected Set<String> getVersionsInRange( Property property, PropertyVersions versions,
ArtifactVersion[] artifactVersions )
{
VersionRange range;
Set<String> rangeVersions = new HashSet<>();
ArtifactVersion[] tmp;
if ( property.getVersion() != null )
{
try
{
range = VersionRange.createFromVersionSpec( property.getVersion() );
tmp = versions.getAllUpdates( range );
}
catch ( InvalidVersionSpecificationException e )
{
tmp = artifactVersions;
}
}
else
{
tmp = artifactVersions;
}
for ( ArtifactVersion artifactVersion : tmp )
{
rangeVersions.add( artifactVersion.toString() );
}
return rangeVersions;
}

@Override
protected void renderSummaryTableHeader( boolean hasScope, boolean hasType )
{
Expand Down
Expand Up @@ -53,3 +53,4 @@ report.minorUpdatesAvailable=There is at least one newer minor version available
Minor updates are sometimes passive.
report.majorUpdatesAvailable=There is at least one newer major version available. \
Major updates are rarely passive.
report.excludedVersion=Outside allowed version range

0 comments on commit 47a3327

Please sign in to comment.