Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Resolves #776: onlyUpgradable change the filter to versions where the current version is not the latest one #777

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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