From 77ec9624e0c204f73aae30ed7d575dbff418f372 Mon Sep 17 00:00:00 2001 From: Swell <5782559+sultan@users.noreply.github.com> Date: Wed, 23 Nov 2022 09:34:27 +0100 Subject: [PATCH] display versions outside range with star --- .../versions/api/AbstractVersionDetails.java | 60 +++++++++- .../mojo/versions/api/ArtifactVersions.java | 1 + .../AbstractVersionsReportRenderer.java | 112 ++++++++++++++---- .../PropertyUpdatesReportRenderer.java | 81 +------------ .../dependency-updates-report.properties | 1 + 5 files changed, 153 insertions(+), 102 deletions(-) diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java index 1b1a5a080c..18ae6c4f99 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java @@ -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; @@ -441,7 +444,7 @@ protected Optional getLowerBound( ArtifactVersion version, Optional updateScope ) + { + return getArtifactVersionStream( updateScope ) + .min( Collections.reverseOrder( getVersionComparator() ) ) + .orElse( null ); + } + + public final ArtifactVersion[] getReportUpdates( Optional updateScope ) + { + return getArtifactVersionStream( updateScope ) + .sorted( getVersionComparator() ) + .distinct() + .toArray( ArtifactVersion[]::new ); + } + + private Stream getArtifactVersionStream( Optional 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 = null; + VersionRange range = VersionRange.createFromVersionSpec( getCurrentVersion().toString() ); + for ( Restriction restriction : range.getRestrictions() ) + { + ArtifactVersion lowerBound = restriction.getLowerBound(); + if ( highestLowerBound == null || lowerBound != null + && getVersionComparator().compare( highestLowerBound, lowerBound ) < 0 ) + { + highestLowerBound = lowerBound ; + } + } + if ( highestLowerBound == null ) + { + highestLowerBound = 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(); + } + } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java index 6a398891b1..f73f1c41fe 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersions.java @@ -78,6 +78,7 @@ public ArtifactVersions( Artifact artifact, List 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() ); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/AbstractVersionsReportRenderer.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/AbstractVersionsReportRenderer.java index a43033af52..bbdcf3885e 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/AbstractVersionsReportRenderer.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/AbstractVersionsReportRenderer.java @@ -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; @@ -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; @@ -59,10 +67,10 @@ public abstract class AbstractVersionsReportRenderer 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 ) { @@ -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; @@ -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_(); } @@ -462,4 +450,78 @@ protected String getLabel( ArtifactVersion version, AbstractVersionDetails detai return null; } + + private List 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 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_(); + } + } + } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PropertyUpdatesReportRenderer.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PropertyUpdatesReportRenderer.java index c68656e6c6..a9ba61fcad 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PropertyUpdatesReportRenderer.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/PropertyUpdatesReportRenderer.java @@ -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; @@ -261,52 +257,12 @@ else if ( newestUpdateCache.get( details, of( MAJOR ) ) != null ) sink.tableRow_(); if ( !upToDate ) { - Set 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_(); } @@ -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(); @@ -355,36 +314,6 @@ else if ( newestUpdateCache.get( details, of( MAJOR ) ) != null ) sink.table_(); } - @SuppressWarnings( "checkstyle:MethodLength" ) - protected Set getVersionsInRange( Property property, PropertyVersions versions, - ArtifactVersion[] artifactVersions ) - { - VersionRange range; - Set 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 ) { diff --git a/versions-maven-plugin/src/main/resources/dependency-updates-report.properties b/versions-maven-plugin/src/main/resources/dependency-updates-report.properties index 9b8626d4a1..fb4a6e44b0 100644 --- a/versions-maven-plugin/src/main/resources/dependency-updates-report.properties +++ b/versions-maven-plugin/src/main/resources/dependency-updates-report.properties @@ -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