filteredNewer = new ArrayList<>( newer.length );
- for ( ArtifactVersion artifactVersion : newer )
- {
- Artifact artefactWithNewVersion =
- new DefaultArtifact( artifact.getGroupId(), artifact.getArtifactId(),
- VersionRange.createFromVersion( artifactVersion.toString() ), artifact.getScope(),
- artifact.getType(), null, new DefaultArtifactHandler(), false );
- if ( isIncluded( artefactWithNewVersion ) )
- {
- filteredNewer.add( artifactVersion );
- }
- }
- return filteredNewer.toArray( new ArtifactVersion[0] );
+ return Arrays.stream( newer )
+ .filter( version ->
+ {
+ Artifact artefactWithNewVersion =
+ new DefaultArtifact( dependency.getGroupId(), dependency.getArtifactId(),
+ VersionRange.createFromVersion( version.toString() ), dependency.getScope(),
+ dependency.getType(), null, new DefaultArtifactHandler(), false );
+ return isIncluded( artefactWithNewVersion );
+ } )
+ .reduce( ( v1, v2 ) -> v2 );
}
}
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java
index 8b9b234301..f5009dc2ee 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojo.java
@@ -26,13 +26,10 @@
import java.util.Collection;
import java.util.Optional;
-import org.apache.maven.artifact.Artifact;
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.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.plugin.MojoExecutionException;
@@ -41,7 +38,6 @@
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.repository.RepositorySystem;
-import org.codehaus.mojo.versions.api.ArtifactVersions;
import org.codehaus.mojo.versions.api.PomHelper;
import org.codehaus.mojo.versions.api.Segment;
import org.codehaus.mojo.versions.ordering.InvalidSegmentException;
@@ -50,16 +46,17 @@
import org.codehaus.mojo.versions.utils.SegmentUtils;
import static java.util.Collections.singletonList;
+import static java.util.Optional.empty;
/**
- * Replaces any version with the latest version.
+ * Replaces any version with the latest version found in the artifactory.
*
* @author Stephen Connolly
* @since 1.0-alpha-3
*/
@Mojo( name = "use-latest-versions", threadSafe = true )
public class UseLatestVersionsMojo
- extends AbstractVersionsDependencyUpdaterMojo
+ extends UseLatestVersionsMojoBase
{
/**
* Whether to allow the major version number to be changed.
@@ -67,7 +64,7 @@ public class UseLatestVersionsMojo
* @since 1.2
*/
@Parameter( property = "allowMajorUpdates", defaultValue = "true" )
- private boolean allowMajorUpdates;
+ private boolean allowMajorUpdates = true;
/**
* Whether to allow the minor version number to be changed.
@@ -76,7 +73,7 @@ public class UseLatestVersionsMojo
* @since 1.2
*/
@Parameter( property = "allowMinorUpdates", defaultValue = "true" )
- private boolean allowMinorUpdates;
+ private boolean allowMinorUpdates = true;
/**
* Whether to allow the incremental version number to be changed.
@@ -86,7 +83,7 @@ public class UseLatestVersionsMojo
* @since 1.2
*/
@Parameter( property = "allowIncrementalUpdates", defaultValue = "true" )
- private boolean allowIncrementalUpdates;
+ private boolean allowIncrementalUpdates = true;
/**
* Whether to downgrade a snapshot dependency if allowSnapshots
is false
@@ -162,81 +159,27 @@ protected void update( ModifiedPomXMLEventReader pom )
}
}
+ @SuppressWarnings( "unchecked" )
private void useLatestVersions( ModifiedPomXMLEventReader pom, Collection dependencies )
- throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException
+ throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException
{
Optional unchangedSegment = SegmentUtils.determineUnchangedSegment( allowMajorUpdates,
allowMinorUpdates, allowIncrementalUpdates, getLog() );
- for ( Dependency dep : dependencies )
- {
- if ( isExcludeReactor() && isProducedByReactor( dep ) )
- {
- getLog().info( "Ignoring reactor dependency: " + toString( dep ) );
- continue;
- }
-
- if ( isHandledByProperty( dep ) )
- {
- getLog().debug( "Ignoring dependency with property as version: " + toString( dep ) );
- continue;
- }
-
- String version = dep.getVersion();
- Artifact artifact = this.toArtifact( dep );
- if ( !isIncluded( artifact ) )
- {
- continue;
- }
-
- ArtifactVersion selectedVersion = new DefaultArtifactVersion( version );
- getLog().debug( "Selected version:" + selectedVersion );
-
- getLog().debug( "Looking for newer versions of " + toString( dep ) );
- ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false );
-
- try
- {
- ArtifactVersion[] newerVersions = versions.getNewerVersions( version, unchangedSegment, allowSnapshots,
- allowDowngrade );
-
- //ArtifactVersion[] filteredVersions = filter( unchangedSegment, selectedVersion, newerVersions );
- ArtifactVersion[] filteredVersions = newerVersions;
- if ( filteredVersions.length > 0 )
+ useLatestVersions( pom, dependencies,
+ ( dep, versions ) ->
{
- String newVersion = filteredVersions[filteredVersions.length - 1].toString();
- if ( getProject().getParent() != null )
+ try
{
- final Artifact parentArtifact = getProject().getParentArtifact();
- if ( artifact.getId().equals( parentArtifact.getId() ) && isProcessingParent() )
- {
- if ( PomHelper.setProjectParentVersion( pom, newVersion ) )
- {
- getLog().debug( "Made parent update from " + version + " to " + newVersion );
-
- this.getChangeRecorder().recordUpdate( "useLatestVersions", parentArtifact.getGroupId(),
- parentArtifact.getArtifactId(), version,
- newVersion );
- }
- }
+ return versions.getNewestVersion( dep.getVersion(), unchangedSegment, allowSnapshots,
+ allowDowngrade );
}
- if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version,
- newVersion,
- getProject().getModel() ) )
+ catch ( InvalidSegmentException e )
{
- getLog().info( "Updated " + toString( dep ) + " to version " + newVersion );
-
- this.getChangeRecorder().recordUpdate( "useLatestVersions", dep.getGroupId(),
- dep.getArtifactId(), version, newVersion );
+ getLog().warn( String.format( "Skipping the processing of %s:%s:%s due to: %s",
+ dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), e.getMessage() ) );
}
- }
- }
- catch ( InvalidSegmentException e )
- {
- getLog().warn( String.format( "Skipping the processing of %s:%s:%s due to: %s", dep.getGroupId(),
- dep.getArtifactId(), dep.getVersion(), e.getMessage() ) );
- }
- }
+ return empty();
+ }, "useLatestVersions" );
}
-
}
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojoBase.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojoBase.java
new file mode 100644
index 0000000000..05a657a623
--- /dev/null
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestVersionsMojoBase.java
@@ -0,0 +1,147 @@
+package org.codehaus.mojo.versions;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import javax.xml.stream.XMLStreamException;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Optional;
+import java.util.function.BiFunction;
+import java.util.function.Predicate;
+
+import org.apache.maven.artifact.Artifact;
+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.artifact.versioning.DefaultArtifactVersion;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.project.MavenProjectBuilder;
+import org.apache.maven.repository.RepositorySystem;
+import org.codehaus.mojo.versions.api.ArtifactVersions;
+import org.codehaus.mojo.versions.api.PomHelper;
+import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader;
+
+/**
+ * Common base class for {@link UseLatestVersionsMojo}
+ * and {@link UseLatestReleasesMojo}
+ */
+public abstract class UseLatestVersionsMojoBase
+ extends AbstractVersionsDependencyUpdaterMojo
+{
+ public UseLatestVersionsMojoBase( RepositorySystem repositorySystem,
+ MavenProjectBuilder projectBuilder,
+ ArtifactMetadataSource artifactMetadataSource,
+ WagonManager wagonManager,
+ ArtifactResolver artifactResolver )
+ {
+ super( repositorySystem, projectBuilder, artifactMetadataSource, wagonManager, artifactResolver );
+ }
+
+ /**
+ * Updates the pom, given a set of dependencies, a function retrieving the newest version,
+ * and an optional array of filters against which the input dependencies are matched.
+ *
+ * @param pom POM to be modified
+ * @param dependencies collection of dependencies with the dependency versions before the change
+ * @param newestVersionProducer function providing the newest version given a dependency and
+ * an {@link ArtifactVersions} instance
+ * @param changeRecorderTitle title for the change recorder records
+ * @param filters optional array of filters
+ * @throws XMLStreamException thrown if the POM update doesn't succeed
+ * @throws ArtifactMetadataRetrievalException thrown if an artifact cannot be retried
+ */
+ @SafeVarargs
+ protected final void useLatestVersions( ModifiedPomXMLEventReader pom,
+ Collection dependencies,
+ BiFunction>
+ newestVersionProducer,
+ String changeRecorderTitle,
+ Predicate... filters )
+ throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException
+ {
+ for ( Dependency dep : dependencies )
+ {
+ if ( !Arrays.stream( filters )
+ .map( f -> f.test( dep ) )
+ .reduce( Boolean::logicalAnd )
+ .orElse( true ) )
+ {
+ continue;
+ }
+
+ if ( isExcludeReactor() && isProducedByReactor( dep ) )
+ {
+ getLog().info( "Ignoring reactor dependency: " + toString( dep ) );
+ continue;
+ }
+
+ if ( isHandledByProperty( dep ) )
+ {
+ getLog().debug( "Ignoring dependency with property as version: " + toString( dep ) );
+ continue;
+ }
+
+ Artifact artifact = toArtifact( dep );
+ if ( !isIncluded( artifact ) )
+ {
+ continue;
+ }
+
+ ArtifactVersion selectedVersion = new DefaultArtifactVersion( dep.getVersion() );
+ getLog().debug( "Selected version:" + selectedVersion );
+
+ getLog().debug( "Looking for newer versions of " + toString( dep ) );
+ ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false );
+ Optional newestVer = newestVersionProducer.apply( dep, versions );
+ if ( newestVer.isPresent() )
+ {
+ String verStr = newestVer.get().toString();
+ if ( getProject().getParent() != null )
+ {
+ final Artifact parentArtifact = getProject().getParentArtifact();
+ if ( artifact.getId().equals( parentArtifact.getId() ) && isProcessingParent() )
+ {
+ if ( PomHelper.setProjectParentVersion( pom, verStr ) )
+ {
+ getLog().debug( "Made parent update from " + dep.getVersion() + " to " + verStr );
+
+ this.getChangeRecorder().recordUpdate( changeRecorderTitle, parentArtifact.getGroupId(),
+ parentArtifact.getArtifactId(), dep.getVersion(),
+ verStr );
+ }
+ }
+ }
+ if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), dep.getVersion(),
+ verStr,
+ getProject().getModel() ) )
+ {
+ getLog().info( "Updated " + toString( dep ) + " to version " + verStr );
+
+ this.getChangeRecorder().recordUpdate( changeRecorderTitle, dep.getGroupId(),
+ dep.getArtifactId(), dep.getVersion(), verStr );
+ }
+ }
+ }
+ }
+}
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java
index 1d3f9665fd..1b1a5a080c 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/AbstractVersionDetails.java
@@ -255,6 +255,32 @@ public final ArtifactVersion[] getNewerVersions( String versionString, Optional<
return getVersions( restriction, includeSnapshots );
}
+ @Override
+ public Optional getNewestVersion( String versionString, Optional upperBoundSegment,
+ boolean includeSnapshots, boolean allowDowngrade )
+ throws InvalidSegmentException
+ {
+ ArtifactVersion currentVersion = new DefaultArtifactVersion( versionString );
+ ArtifactVersion lowerBound = allowDowngrade
+ ? getLowerBound( currentVersion, upperBoundSegment )
+ .map( DefaultArtifactVersion::new )
+ .orElse( null )
+ : currentVersion;
+ ArtifactVersion upperBound =
+ 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 );
+ return Arrays.stream( getVersions( includeSnapshots ) )
+ .filter( candidate -> isVersionInRestriction( restriction, candidate ) )
+ .filter( candidate -> includeSnapshots || !ArtifactUtils.isSnapshot( candidate.toString() ) )
+ .max( getVersionComparator() );
+ }
+
@Override
public final ArtifactVersion[] getVersions( Restriction restriction, boolean includeSnapshots )
{
diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java
index 265b4fcfaa..542130619e 100644
--- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java
+++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/api/VersionDetails.java
@@ -229,6 +229,23 @@ ArtifactVersion getNewestVersion( ArtifactVersion lowerBound, ArtifactVersion up
*/
ArtifactVersion getNewestVersion( VersionRange versionRange, boolean includeSnapshots );
+ /**
+ * Returns the latest version, newer than the given version, given the upper bound segment and whether snapshots
+ * should be included.
+ *
+ * @param versionString current version
+ * @param upperBoundSegment the upper bound segment; empty() means no upper bound
+ * @param includeSnapshots whether snapshot versions should be included
+ * @param allowDowngrade whether to allow downgrading if the current version is a snapshots and snapshots
+ * are disallowed
+ * @return newer version or {@link Optional#empty()} if none can be found
+ * @throws InvalidSegmentException if the requested segment is outside the bounds (less than 1 or greater than
+ * the segment count)
+ */
+ Optional getNewestVersion( String versionString, Optional upperBoundSegment,
+ boolean includeSnapshots, boolean allowDowngrade )
+ throws InvalidSegmentException;
+
/**
* Returns the newest version newer than the specified current version, but within the specified update scope or
* null
if no such version exists.
diff --git a/versions-maven-plugin/src/site/markdown/index.md b/versions-maven-plugin/src/site/markdown/index.md
index cf780e9359..f008eb1a60 100644
--- a/versions-maven-plugin/src/site/markdown/index.md
+++ b/versions-maven-plugin/src/site/markdown/index.md
@@ -59,8 +59,7 @@ The Versions Plugin has the following goals.
released and replaces them with the corresponding release version.
* [versions:use-next-releases](./use-next-releases-mojo.html) searches the pom for all non-SNAPSHOT versions which
have been a newer release and replaces them with the next release version.
-* [versions:use-latest-releases](./use-latest-releases-mojo.html) searches the pom for all non-SNAPSHOT versions which
- have been a newer release and replaces them with the latest release version.
+* [versions:use-latest-releases](./use-latest-releases-mojo.html) searches the pom for all dependencies using *release* versions (i.e. not SNAPSHOT and not versions ending with a year-month-day suffix) and replaces them with the latest *release* version.
* [versions:use-next-snapshots](./use-next-snapshots-mojo.html) searches the pom for all non-SNAPSHOT versions which
have been a newer -SNAPSHOT version and replaces them with the next -SNAPSHOT version.
* [versions:use-latest-snapshots](./use-latest-snapshots-mojo.html) searches the pom for all non-SNAPSHOT versions
diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTest.java
index e5b0ac4e1d..ac0a033d92 100644
--- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTest.java
+++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestVersionsMojoTest.java
@@ -31,6 +31,8 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.hasItem;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.not;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
@@ -60,6 +62,7 @@ public void setUp() throws Exception
"1.0.0-SNAPSHOT", "0.9.0"} );
put( "poison-artifact", new String[] {"1.1.1.1-SNAPSHOT", "1.1.1.0", "1.1.1.0-SNAPSHOT", "1.0.0.0",
"1.0.0.0-SNAPSHOT", "0.9.0.0"} );
+ put( "other-artifact", new String[] {"1.0", "2.0"} );
}} );
mojo = new UseLatestVersionsMojo( repositorySystemMock,
@@ -263,4 +266,56 @@ public void testIgnoredVersions()
}
assertThat( changeRecorder.getChanges(), Is.is( empty() ) );
}
+
+ @Test
+ public void testIncludeFilter()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, IllegalAccessException
+ {
+ mojo.getProject().getModel().setDependencies( Arrays.asList(
+ DependencyBuilder.dependencyWith( "default-group", "dependency-artifact", "0.9.0",
+ "default", "pom", SCOPE_COMPILE ),
+ DependencyBuilder.dependencyWith( "default-group", "other-artifact", "1.0",
+ "default", "pom", SCOPE_COMPILE )
+ ) );
+ setVariableValueToObject( mojo, "processDependencies", true );
+ setVariableValueToObject( mojo, "includes", new String[] {"default-group:other-artifact"} );
+
+
+ try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) )
+ {
+ pomHelper.when( () -> PomHelper.setDependencyVersion( any(), any(), any(), any(), any(), any() ) )
+ .thenReturn( true );
+ mojo.update( null );
+ }
+ assertThat( changeRecorder.getChanges(), hasSize( 1 ) );
+ assertThat( changeRecorder.getChanges(),
+ hasItem( new VersionChange( "default-group", "other-artifact", "1.0",
+ "2.0" ) ) );
+ }
+
+ @Test
+ public void testExcludeFilter()
+ throws MojoExecutionException, XMLStreamException, MojoFailureException, IllegalAccessException
+ {
+ mojo.getProject().getModel().setDependencies( Arrays.asList(
+ DependencyBuilder.dependencyWith( "default-group", "dependency-artifact", "0.9.0",
+ "default", "pom", SCOPE_COMPILE ),
+ DependencyBuilder.dependencyWith( "default-group", "other-artifact", "1.0",
+ "default", "pom", SCOPE_COMPILE )
+ ) );
+ setVariableValueToObject( mojo, "processDependencies", true );
+ setVariableValueToObject( mojo, "excludes", new String[] {"default-group:other-artifact"} );
+
+
+ try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) )
+ {
+ pomHelper.when( () -> PomHelper.setDependencyVersion( any(), any(), any(), any(), any(), any() ) )
+ .thenReturn( true );
+ mojo.update( null );
+ }
+ assertThat( changeRecorder.getChanges(), hasSize( 1 ) );
+ assertThat( changeRecorder.getChanges(),
+ not( hasItem( new VersionChange( "default-group", "other-artifact", "1.0",
+ "2.0" ) ) ) );
+ }
}