Skip to content

Commit

Permalink
Resolves #776: onlyUpgradable change the filter to versions where the…
Browse files Browse the repository at this point in the history
… current version is not the latest one
  • Loading branch information
andrzejj0 authored and slawekjaranowski committed Oct 22, 2022
1 parent 8ee15b7 commit d421b45
Show file tree
Hide file tree
Showing 7 changed files with 143 additions and 170 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,18 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

import org.apache.maven.artifact.manager.WagonManager;
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.doxia.sink.Sink;
import org.apache.maven.model.Dependency;
import org.apache.maven.plugins.annotations.Mojo;
Expand Down Expand Up @@ -202,8 +205,21 @@ && getProject().getOriginalModel().getDependencyManagement().getDependencies() !

if ( onlyUpgradable )
{
dependencyUpdates = filter( dependencyUpdates, e -> e.getVersions().length > 1 );
dependencyManagementUpdates = filter( dependencyManagementUpdates, e -> e.getVersions().length > 1 );
dependencyUpdates = filter( dependencyUpdates, e -> e.getVersions().length > 0 );
dependencyManagementUpdates = filter( dependencyManagementUpdates, e -> e.getVersions().length > 0 );
}

if ( getLog().isDebugEnabled() )
{
getLog().debug( "Dependency versions:" );
dependencyUpdates.forEach( ( key, value ) -> getLog().debug( key.toString() + ": "
+ Arrays.stream( value.getVersions() ).map( ArtifactVersion::toString )
.collect( Collectors.joining( ", " ) ) ) );

getLog().debug( "Dependency management versions:" );
dependencyManagementUpdates.forEach( ( key, value ) -> getLog().debug( key.toString() + ": "
+ Arrays.stream( value.getVersions() ).map( ArtifactVersion::toString )
.collect( Collectors.joining( ", " ) ) ) );
}

for ( String format : formats )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,8 @@ protected void doGenerateReport( Locale locale, Sink sink ) throws MavenReportEx

if ( onlyUpgradable )
{
pluginUpdates =
filter( pluginUpdates, plugin -> plugin.getVersions().length > 1 );
pluginManagementUpdates = filter( pluginManagementUpdates,
plugin -> plugin.getVersions().length > 1 );
pluginUpdates = filter( pluginUpdates, p -> p.getVersions().length > 0 );
pluginManagementUpdates = filter( pluginManagementUpdates, p -> p.getVersions().length > 0 );
}

PluginUpdatesModel model = new PluginUpdatesModel( pluginUpdates, pluginManagementUpdates );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,12 @@ public final ArtifactVersion[] getAllUpdates( Optional<Segment> updateScope, boo
return null;
}

@Override
public final ArtifactVersion[] getAllUpdates()
{
return getAllUpdates( (VersionRange) null, isIncludeSnapshots() );
}

@Override
public final ArtifactVersion[] getAllUpdates( VersionRange versionRange )
{
Expand Down
204 changes: 53 additions & 151 deletions src/main/java/org/codehaus/mojo/versions/api/DefaultVersionsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,15 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.artifact.manager.WagonManager;
Expand Down Expand Up @@ -668,109 +669,95 @@ public ArtifactVersion createArtifactVersion( String version )
return new DefaultArtifactVersion( version );
}

/**
* Returns a map of all possible updates per dependency. The lookup is done in parallel using
* {@code LOOKUP_PARALLEL_THREADS} threads.
*
* @param dependencies The set of {@link Dependency} instances to look up.
* @param usePluginRepositories Search the plugin repositories.
* @return map containing the ArtifactVersions object per dependency
* @throws ArtifactMetadataRetrievalException if the lookup does not succeed
*/
@Override
public Map<Dependency, ArtifactVersions> lookupDependenciesUpdates( Set<Dependency> dependencies,
boolean usePluginRepositories )
throws ArtifactMetadataRetrievalException
{
// Create the request for details collection for parallel lookup...
final List<Callable<DependencyArtifactVersions>> requestsForDetails =
new ArrayList<>( dependencies.size() );
for ( final Dependency dependency : dependencies )
{
requestsForDetails.add( new DependencyLookup( dependency, usePluginRepositories ) );
}

final Map<Dependency, ArtifactVersions> dependencyUpdates = new TreeMap<>( DependencyComparator.INSTANCE );

// Lookup details in parallel...
final ExecutorService executor = Executors.newFixedThreadPool( LOOKUP_PARALLEL_THREADS );
ExecutorService executor = Executors.newFixedThreadPool( LOOKUP_PARALLEL_THREADS );
try
{
final List<Future<DependencyArtifactVersions>> responseForDetails =
executor.invokeAll( requestsForDetails );

// Construct the final results...
for ( final Future<DependencyArtifactVersions> details : responseForDetails )
Map<Dependency, ArtifactVersions> dependencyUpdates = new TreeMap<>( DependencyComparator.INSTANCE );
List<Future<? extends Pair<Dependency, ArtifactVersions>>> futures = dependencies.stream()
.map( dependency -> executor.submit( () -> new ImmutablePair<>
( dependency, lookupDependencyUpdates( dependency, usePluginRepositories ) ) ) )
.collect( Collectors.toList() );
for ( Future<? extends Pair<Dependency, ArtifactVersions>> details : futures )
{
final DependencyArtifactVersions dav = details.get();
dependencyUpdates.put( dav.getDependency(), dav.getArtifactVersions() );
Pair<Dependency, ArtifactVersions> pair = details.get();
dependencyUpdates.put( pair.getKey(), pair.getValue() );
}

return dependencyUpdates;
}
catch ( ExecutionException | InterruptedException ie )
{
throw new ArtifactMetadataRetrievalException( "Unable to acquire metadata for dependencies " + dependencies
+ ": " + ie.getMessage(), ie, null );
+ ": " + ie.getMessage(), ie, null );
}
finally
{
executor.shutdownNow();
executor.shutdown();
}
return dependencyUpdates;
}

@Override
public ArtifactVersions lookupDependencyUpdates( Dependency dependency, boolean usePluginRepositories )
throws ArtifactMetadataRetrievalException
{
getLog().debug( "Checking "
+ ArtifactUtils.versionlessKey( dependency.getGroupId(), dependency.getArtifactId() )
+ " for updates newer than " + dependency.getVersion() );

return lookupArtifactVersions( createDependencyArtifact( dependency ), usePluginRepositories );
ArtifactVersions allVersions = lookupArtifactVersions( createDependencyArtifact( dependency ),
usePluginRepositories );
return new ArtifactVersions( allVersions.getArtifact(), Arrays.stream( allVersions.getAllUpdates() )
.collect( Collectors.toList() ), allVersions.getVersionComparator() );
}

@Override
public Map<Plugin, PluginUpdatesDetails> lookupPluginsUpdates( Set<Plugin> plugins, boolean allowSnapshots )
throws ArtifactMetadataRetrievalException
{
// Create the request for details collection for parallel lookup...
List<Callable<PluginPluginUpdatesDetails>> requestsForDetails = new ArrayList<>( plugins.size() );
for ( final Plugin plugin : plugins )
{
requestsForDetails.add( new PluginLookup( plugin, allowSnapshots ) );
}

Map<Plugin, PluginUpdatesDetails> pluginUpdates = new TreeMap<>( PluginComparator.INSTANCE );

// Lookup details in parallel...
ExecutorService executor = Executors.newFixedThreadPool( LOOKUP_PARALLEL_THREADS );
try
{
final List<Future<PluginPluginUpdatesDetails>> responseForDetails =
executor.invokeAll( requestsForDetails );

// Construct the final results...
for ( final Future<PluginPluginUpdatesDetails> details : responseForDetails )
Map<Plugin, PluginUpdatesDetails> pluginUpdates = new TreeMap<>( PluginComparator.INSTANCE );
List<Future<? extends Pair<Plugin, PluginUpdatesDetails>>> futures = plugins.stream()
.map( p -> executor.submit( () -> new ImmutablePair<>
( p, lookupPluginUpdates( p, allowSnapshots ) ) ) )
.collect( Collectors.toList() );
for ( Future<? extends Pair<Plugin, PluginUpdatesDetails>> details : futures )
{
final PluginPluginUpdatesDetails pud = details.get();
pluginUpdates.put( pud.getPlugin(), pud.getPluginUpdatesDetails() );
Pair<Plugin, PluginUpdatesDetails> pair = details.get();
pluginUpdates.put( pair.getKey(), pair.getValue() );
}

return pluginUpdates;
}
catch ( ExecutionException | InterruptedException ie )
{
throw new ArtifactMetadataRetrievalException( "Unable to acquire metadata for plugins " + plugins + ": "
+ ie.getMessage(), ie, null );
+ ie.getMessage(), ie, null );
}
finally
{
executor.shutdownNow();
executor.shutdown();
}
return pluginUpdates;
}

@Override
public PluginUpdatesDetails lookupPluginUpdates( Plugin plugin, boolean allowSnapshots )
throws ArtifactMetadataRetrievalException
{
String version = plugin.getVersion();
version = version == null ? "LATEST" : version;
getLog().debug( "Checking " + ArtifactUtils.versionlessKey( plugin.getGroupId(), plugin.getArtifactId() )
+ " for updates newer than " + version );

final ArtifactVersions pluginArtifactVersions =
lookupArtifactVersions( createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), version ),
true );
String version = plugin.getVersion() != null
? plugin.getVersion()
: "LATEST";

Set<Dependency> pluginDependencies = new TreeSet<>( DependencyComparator.INSTANCE );
if ( plugin.getDependencies() != null )
Expand All @@ -780,7 +767,13 @@ public PluginUpdatesDetails lookupPluginUpdates( Plugin plugin, boolean allowSna
Map<Dependency, ArtifactVersions> pluginDependencyDetails =
lookupDependenciesUpdates( pluginDependencies, false );

return new PluginUpdatesDetails( pluginArtifactVersions, pluginDependencyDetails, allowSnapshots );
ArtifactVersions allVersions =
lookupArtifactVersions( createPluginArtifact( plugin.getGroupId(), plugin.getArtifactId(), version ),
true );
ArtifactVersions updatedVersions = new ArtifactVersions( allVersions.getArtifact(),
Arrays.stream( allVersions.getAllUpdates() ).collect( Collectors.toList() ),
allVersions.getVersionComparator() );
return new PluginUpdatesDetails( updatedVersions, pluginDependencyDetails, allowSnapshots );
}

@Override
Expand Down Expand Up @@ -832,8 +825,8 @@ public Map<Property, PropertyVersions> getVersionPropertiesMap( MavenProject pro
}
}

List<String> includePropertiesList = getSplittedProperties( includeProperties );
List<String> excludePropertiesList = getSplittedProperties( excludeProperties );
List<String> includePropertiesList = getSplitProperties( includeProperties );
List<String> excludePropertiesList = getSplitProperties( excludeProperties );

getLog().debug( "Searching for properties associated with builders" );
Iterator<Property> i = properties.values().iterator();
Expand Down Expand Up @@ -902,7 +895,7 @@ else if ( !excludePropertiesList.isEmpty() && excludePropertiesList.contains( pr
return propertyVersions;
}

private List<String> getSplittedProperties( String commaSeparatedProperties )
private List<String> getSplitProperties( String commaSeparatedProperties )
{
List<String> propertiesList = Collections.emptyList();
if ( StringUtils.isNotEmpty( commaSeparatedProperties ) )
Expand All @@ -913,97 +906,6 @@ private List<String> getSplittedProperties( String commaSeparatedProperties )
return propertiesList;
}

// This is a data container to hold the result of a Dependency lookup to its ArtifactVersions.
private static class DependencyArtifactVersions
{
private final Dependency dependency;

private final ArtifactVersions artifactVersions;

DependencyArtifactVersions( final Dependency dependency, final ArtifactVersions artifactVersions )
{
this.dependency = dependency;
this.artifactVersions = artifactVersions;
}

public Dependency getDependency()
{
return dependency;
}

public ArtifactVersions getArtifactVersions()
{
return artifactVersions;
}
}

// This is a data container to hold the result of a Dependency lookup to its ArtifactVersions.
private static class PluginPluginUpdatesDetails
{
private final Plugin plugin;

private final PluginUpdatesDetails pluginUpdatesDetails;

PluginPluginUpdatesDetails( final Plugin plugin, final PluginUpdatesDetails pluginUpdatesDetails )
{
this.plugin = plugin;
this.pluginUpdatesDetails = pluginUpdatesDetails;
}

public Plugin getPlugin()
{
return plugin;
}

public PluginUpdatesDetails getPluginUpdatesDetails()
{
return pluginUpdatesDetails;
}
}

// This Callable wraps lookupDependencyUpdates so that it can be run in parallel.
private class DependencyLookup
implements Callable<DependencyArtifactVersions>
{
private final Dependency dependency;

private final boolean usePluginRepositories;

DependencyLookup( final Dependency dependency, final boolean usePluginRepositories )
{
this.dependency = dependency;
this.usePluginRepositories = usePluginRepositories;
}

public DependencyArtifactVersions call()
throws Exception
{
return new DependencyArtifactVersions( dependency,
lookupDependencyUpdates( dependency, usePluginRepositories ) );
}
}

// This Callable wraps lookupPluginUpdates so that it can be run in parallel.
private class PluginLookup
implements Callable<PluginPluginUpdatesDetails>
{
private final Plugin plugin;

private final boolean allowSnapshots;

PluginLookup( final Plugin plugin, final Boolean allowSnapshots )
{
this.plugin = plugin;
this.allowSnapshots = allowSnapshots;
}

public PluginPluginUpdatesDetails call()
throws Exception
{
return new PluginPluginUpdatesDetails( plugin, lookupPluginUpdates( plugin, allowSnapshots ) );
}
}

/**
* Builder class for {@linkplain DefaultVersionsHelper}
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,14 @@ ArtifactVersion getNewestUpdate( Optional<Segment> updateScope, boolean includeS
ArtifactVersion[] getAllUpdates( Optional<Segment> updateScope, boolean includeSnapshots )
throws InvalidSegmentException;

/**
* Returns the all versions newer than the specified current version
*
* @return the all versions after currentVersion
* @since 2.13.0
*/
ArtifactVersion[] getAllUpdates();

/**
* Returns the all versions newer than the specified current version, but within the specified update scope.
*
Expand Down
Loading

0 comments on commit d421b45

Please sign in to comment.