diff --git a/.gitignore b/.gitignore index 8f164d2f9a..2a91b82853 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ target .project *.iml .idea +.checkstyle /.factorypath 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 ec624f677b..6a398891b1 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 @@ -253,4 +253,5 @@ public String toString() return "ArtifactVersions" + "{artifact=" + artifact + ", versions=" + versions + ", versionComparator=" + versionComparator + '}'; } + } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java index e5aa2e384b..9966d9a1c2 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/ArtifactVersionsCache.java @@ -52,6 +52,8 @@ public ArtifactVersionsCache( BiFunction concrete implementation of {@linkplain AbstractVersionDetails} + * @param return type of the cached function * @param artifactVersions {@linkplain ArtifactVersions} object referring to the given dependency * @param updateScope update scope * @return last retrieved update information diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java index 119e6192c3..825be779e2 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/api/PropertyVersions.java @@ -492,4 +492,5 @@ public int getSegmentCount( ArtifactVersion v ) return result; } } + } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java b/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java index b3c3c2c67b..dc8c013c1d 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java @@ -20,7 +20,6 @@ */ import java.io.OutputStream; -import java.util.Objects; /** * A recorder that ignores updates. @@ -29,35 +28,20 @@ public class ChangeRecorderNull implements ChangeRecorder { /** - * Create a new change recorder that serializes to XML. - * - * @return A new change recorder + * Creates a new instance */ - - public static ChangeRecorder create() - { - return new ChangeRecorderNull(); - } - - private ChangeRecorderNull() + public ChangeRecorderNull() { - } @Override public final void recordUpdate( final String kind, final String groupId, final String artifactId, final String oldVersion, final String newVersion ) { - Objects.requireNonNull( kind, "kind" ); - Objects.requireNonNull( groupId, "groupId" ); - Objects.requireNonNull( artifactId, "artifactId" ); - Objects.requireNonNull( oldVersion, "oldVersion" ); - Objects.requireNonNull( newVersion, "newVersion" ); } @Override public final void serialize( final OutputStream outputStream ) { - } } diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java b/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java index d6b62526df..6fa2a82c41 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java @@ -53,21 +53,17 @@ public class ChangeRecorderXML implements ChangeRecorder private final Element root; /** - * Create a new change recorder that serializes to XML. - * - * @return A new change recorder + * Creates a new instance */ - - public static ChangeRecorder create() + public ChangeRecorderXML() { try { final DocumentBuilderFactory documentBuilders = DocumentBuilderFactory.newInstance(); final DocumentBuilder documentBuilder = documentBuilders.newDocumentBuilder(); - final Document document = documentBuilder.newDocument(); - final Element root = document.createElementNS( CHANGES_NAMESPACE, "updates" ); + document = documentBuilder.newDocument(); + root = document.createElementNS( CHANGES_NAMESPACE, "updates" ); document.appendChild( root ); - return new ChangeRecorderXML( document, root ); } catch ( final ParserConfigurationException | DOMException e ) { @@ -75,12 +71,6 @@ public static ChangeRecorder create() } } - private ChangeRecorderXML( final Document document, final Element root ) - { - this.document = Objects.requireNonNull( document, "document" ); - this.root = Objects.requireNonNull( root, "root" ); - } - @Override public final void recordUpdate( final String kind, final String groupId, final String artifactId, final String oldVersion, final String newVersion ) diff --git a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java index dfab65532b..24ad4df5a8 100644 --- a/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java +++ b/versions-common/src/main/java/org/codehaus/mojo/versions/utils/DependencyBuilder.java @@ -144,6 +144,9 @@ public static DependencyBuilder newBuilder() /** * Convenience builder method + * @param groupId groupId of the dependency + * @param artifactId artifactId of the dependency + * @param version version of the dependency * @return new instance of {@linkplain Dependency} */ public static Dependency dependencyWith( String groupId, String artifactId, String version ) @@ -157,6 +160,12 @@ public static Dependency dependencyWith( String groupId, String artifactId, Stri /** * Convenience builder method + * @param groupId groupId of the dependency + * @param artifactId artifactId of the dependency + * @param version version of the dependency + * @param type type of the dependency + * @param classifier classifier of the dependency + * @param scope scope of the dependency * @return new instance of {@linkplain Dependency} */ public static Dependency dependencyWith( String groupId, String artifactId, String version, String type, diff --git a/versions-common/src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java b/versions-common/src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java index c5cb59a076..32c602805c 100644 --- a/versions-common/src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java +++ b/versions-common/src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java @@ -64,7 +64,7 @@ public void testChanges() throws Exception copyResource( "expectedFile.xml", file0 ); - final ChangeRecorder recorder = ChangeRecorderXML.create(); + final ChangeRecorder recorder = new ChangeRecorderXML(); recorder.recordUpdate( "exampleKind", "org.codehaus", "example0", "0.0.1", "0.0.2" ); recorder.recordUpdate( "exampleKind", "org.codehaus", "example1", "1.0.0", "2.0.0" ); diff --git a/versions-maven-plugin/src/it-repo/dummy-with-parent.pom b/versions-maven-plugin/src/it-repo/dummy-with-parent.pom new file mode 100644 index 0000000000..ee67ab6786 --- /dev/null +++ b/versions-maven-plugin/src/it-repo/dummy-with-parent.pom @@ -0,0 +1,15 @@ + + 4.0.0 + + + localhost + dummy-parent2 + 2.0 + + + dummy-with-parent + 1.0 + pom + + diff --git a/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/invoker.properties b/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/invoker.properties new file mode 100644 index 0000000000..3ad4536e87 --- /dev/null +++ b/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = ${project.groupId}:${project.artifactId}:${project.version}:compare-dependencies +invoker.mavenOpts = -DremotePom=localhost:dummy-with-parent:1.0 -DreportMode=false -DprocessParent=true diff --git a/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/pom.xml b/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/pom.xml new file mode 100644 index 0000000000..389dd2b739 --- /dev/null +++ b/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/pom.xml @@ -0,0 +1,15 @@ + + 4.0.0 + + + localhost + dummy-parent2 + 1.0 + + + dummy-with-parent + 1.0-SNAPSHOT + pom + + diff --git a/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/verify.groovy b/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/verify.groovy new file mode 100644 index 0000000000..3271a1899f --- /dev/null +++ b/versions-maven-plugin/src/it/it-compare-dependencies-issue-289/verify.groovy @@ -0,0 +1,2 @@ +def project = new XmlSlurper().parse( new File( basedir, 'pom.xml' ) ) +assert project.parent.version == '2.0' diff --git a/versions-maven-plugin/src/it/it-use-latest-versions-009/verify.bsh b/versions-maven-plugin/src/it/it-use-latest-versions-009/verify.bsh deleted file mode 100644 index afc3f9b043..0000000000 --- a/versions-maven-plugin/src/it/it-use-latest-versions-009/verify.bsh +++ /dev/null @@ -1,33 +0,0 @@ -import java.io.*; -import java.util.regex.*; - -try -{ - File file = new File( basedir, "pom.xml" ); - - BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( file ), "UTF-8" ) ); - StringBuilder buf = new StringBuilder(); - String line = in.readLine(); - while ( line != null ) - { - buf.append( line ); - buf.append( " " ); - line = in.readLine(); - } - - Pattern p = Pattern.compile( "\\Q\\E.*\\Q\\E\\s*3\\.0\\s*\\Q\\E.*\\Q\\E" ); - Matcher m = p.matcher( buf.toString() ); - if ( !m.find() ) - { - System.out.println( "Did not update parent to version 3.0" ); - return false; - } - System.out.println( m.group( 0 ) ); -} -catch( Throwable t ) -{ - t.printStackTrace(); - return false; -} - -return true; diff --git a/versions-maven-plugin/src/it/it-use-latest-versions-009/verify.groovy b/versions-maven-plugin/src/it/it-use-latest-versions-009/verify.groovy new file mode 100644 index 0000000000..954f1b2145 --- /dev/null +++ b/versions-maven-plugin/src/it/it-use-latest-versions-009/verify.groovy @@ -0,0 +1,2 @@ +def project = new XmlSlurper().parse( new File( basedir, 'pom.xml' ) ) +assert project.parent.version == '3.0' diff --git a/versions-maven-plugin/src/it/it-use-latest-versions-010/verify.bsh b/versions-maven-plugin/src/it/it-use-latest-versions-010/verify.bsh deleted file mode 100644 index 204a0b8153..0000000000 --- a/versions-maven-plugin/src/it/it-use-latest-versions-010/verify.bsh +++ /dev/null @@ -1,62 +0,0 @@ -import java.io.*; -import java.util.regex.*; - -try -{ - File file = new File( basedir, "pom.xml" ); - - BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( file ), "UTF-8" ) ); - StringBuilder buf = new StringBuilder(); - String line = in.readLine(); - while ( line != null ) - { - buf.append( line ); - buf.append( " " ); - line = in.readLine(); - } - - Pattern p = Pattern.compile( "\\Q\\E.*\\Q\\E\\s*3\\.0\\s*\\Q\\E.*\\Q\\E" ); - Matcher m = p.matcher( buf.toString() ); - if ( !m.find() ) - { - System.out.println( "Did not update parent to version 3.0" ); - return false; - } - System.out.println( m.group( 0 ) ); -} -catch( Throwable t ) -{ - t.printStackTrace(); - return false; -} - -try -{ - File file = new File( basedir, "pom.xml" ); - - BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( file ), "UTF-8" ) ); - StringBuilder buf = new StringBuilder(); - String line = in.readLine(); - while ( line != null ) - { - buf.append( line ); - buf.append( " " ); - line = in.readLine(); - } - - Pattern p = Pattern.compile( "\\Q\\E\\s*3\\.0\\s*\\Q\\E.*\\Qpom\\E" ); - Matcher m = p.matcher( buf.toString() ); - if ( !m.find() ) - { - System.out.println( "Did not update to version 3.0" ); - return false; - } - System.out.println( m.group( 0 ) ); -} -catch( Throwable t ) -{ - t.printStackTrace(); - return false; -} - -return true; diff --git a/versions-maven-plugin/src/it/it-use-latest-versions-010/verify.groovy b/versions-maven-plugin/src/it/it-use-latest-versions-010/verify.groovy new file mode 100644 index 0000000000..954f1b2145 --- /dev/null +++ b/versions-maven-plugin/src/it/it-use-latest-versions-010/verify.groovy @@ -0,0 +1,2 @@ +def project = new XmlSlurper().parse( new File( basedir, 'pom.xml' ) ) +assert project.parent.version == '3.0' diff --git a/versions-maven-plugin/src/it/it-use-latest-versions-011/verify.bsh b/versions-maven-plugin/src/it/it-use-latest-versions-011/verify.bsh deleted file mode 100644 index c93c575322..0000000000 --- a/versions-maven-plugin/src/it/it-use-latest-versions-011/verify.bsh +++ /dev/null @@ -1,33 +0,0 @@ -import java.io.*; -import java.util.regex.*; - -try -{ - File file = new File( basedir, "pom.xml" ); - - BufferedReader in = new BufferedReader( new InputStreamReader( new FileInputStream( file ), "UTF-8" ) ); - StringBuilder buf = new StringBuilder(); - String line = in.readLine(); - while ( line != null ) - { - buf.append( line ); - buf.append( " " ); - line = in.readLine(); - } - - Pattern p = Pattern.compile( "\\Q\\E.*\\Q\\E\\s*1\\.0\\.0\\s*\\Q\\E.*\\Q\\E" ); - Matcher m = p.matcher( buf.toString() ); - if ( !m.find() ) - { - System.out.println( "Did not update parent to version 1.0.0 from 1.0.0-SNAPSHOT" ); - return false; - } - System.out.println( m.group( 0 ) ); -} -catch( Throwable t ) -{ - t.printStackTrace(); - return false; -} - -return true; diff --git a/versions-maven-plugin/src/it/it-use-latest-versions-011/verify.groovy b/versions-maven-plugin/src/it/it-use-latest-versions-011/verify.groovy new file mode 100644 index 0000000000..09e552dd5d --- /dev/null +++ b/versions-maven-plugin/src/it/it-use-latest-versions-011/verify.groovy @@ -0,0 +1,2 @@ +def project = new XmlSlurper().parse( new File( basedir, 'pom.xml' ) ) +assert project.parent.version == '1.0.0' diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsDependencyUpdaterMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsDependencyUpdaterMojo.java index 571fbdc015..9b8cc5c5cd 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsDependencyUpdaterMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsDependencyUpdaterMojo.java @@ -20,11 +20,13 @@ */ import javax.inject.Inject; +import javax.xml.stream.XMLStreamException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; +import java.util.regex.Pattern; import org.apache.commons.lang3.StringUtils; import org.apache.maven.artifact.Artifact; @@ -41,7 +43,11 @@ import org.apache.maven.repository.RepositorySystem; import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter; import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter; +import org.codehaus.mojo.versions.api.PomHelper; +import org.codehaus.mojo.versions.recording.ChangeRecorder; +import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.mojo.versions.utils.DependencyBuilder; +import org.codehaus.mojo.versions.utils.DependencyComparator; /** * Base class for a mojo that updates dependency versions. @@ -53,11 +59,16 @@ public abstract class AbstractVersionsDependencyUpdaterMojo extends AbstractVersionsUpdaterMojo { - private static final String END_RANGE_CHARS = "])"; private static final String START_RANGE_CHARS = "[("; + /** + * Pattern to match snapshot versions + */ + protected static final Pattern SNAPSHOT_REGEX = Pattern.compile( "^(.+)-((SNAPSHOT)|(\\d{8}\\.\\d{6}-\\d+))$" ); + + /** * A comma separated list of artifact patterns to include. Follows the pattern * "groupId:artifactId:type:classifier:version". Designed to allow specifying the set of includes from the command @@ -104,7 +115,7 @@ public abstract class AbstractVersionsDependencyUpdaterMojo * @since 1.0-alpha-3 */ @Parameter( property = "processDependencies", defaultValue = "true" ) - private boolean processDependencies; + private boolean processDependencies = true; /** * Whether to process the dependencyManagement section of the project. @@ -112,7 +123,7 @@ public abstract class AbstractVersionsDependencyUpdaterMojo * @since 1.0-alpha-3 */ @Parameter( property = "processDependencyManagement", defaultValue = "true" ) - private boolean processDependencyManagement; + private boolean processDependencyManagement = true; /** * Whether to process the parent section of the project. If not set will default to false. @@ -142,7 +153,7 @@ public abstract class AbstractVersionsDependencyUpdaterMojo * @since 1.0-alpha-3 */ @Parameter( property = "excludeReactor", defaultValue = "true" ) - private boolean excludeReactor; + private boolean excludeReactor = true; @Inject protected AbstractVersionsDependencyUpdaterMojo( RepositorySystem repositorySystem, @@ -266,6 +277,20 @@ protected Artifact toArtifact( Parent model ) .build() ); } + /** + * Returns the {@link Dependency} instance for the parent project + * @return {@link Dependency} object for the parent + */ + protected Dependency getParentDependency() + { + return DependencyBuilder.newBuilder() + .withGroupId( getProject().getParent().getGroupId() ) + .withArtifactId( getProject().getParent().getArtifactId() ) + .withVersion( getProject().getParent().getVersion() ) + .withType( "pom" ) + .build(); + } + protected String toString( MavenProject project ) { StringBuilder buf = new StringBuilder(); @@ -507,4 +532,58 @@ private int findFirstChar( final String includeString, final String chars ) } return nextRangeStartDelimiterIndex; } + + /** + * Attempts to update the dependency {@code dep} to the given {@code newVersion}. The dependency can either + * be the parent project or any given dependency. + * + * @param pom {@link ModifiedPomXMLEventReader} instance to update the POM XML document + * @param dep dependency to be updated (can also be a dependency made from the parent) + * @param newVersion new version to update the dependency to + * @param changeRecorderTitle title for the {@link ChangeRecorder} log + * @return {@code true} if an update has been made, {@code false} otherwise + * @throws XMLStreamException thrown if updating the XML doesn't succeed + */ + protected boolean updateDependencyVersion( ModifiedPomXMLEventReader pom, Dependency dep, + String newVersion, String changeRecorderTitle ) + throws XMLStreamException + { + boolean updated = false; + if ( isProcessingParent() + && getProject().getParent() != null + && DependencyComparator.INSTANCE.compare( dep, DependencyBuilder.newBuilder() + .withGroupId( getProject().getParentArtifact().getGroupId() ) + .withArtifactId( getProject().getParentArtifact().getArtifactId() ) + .withVersion( getProject().getParentArtifact().getVersion() ) + .build() ) == 0 + && PomHelper.setProjectParentVersion( pom, newVersion ) ) + { + if ( getLog().isDebugEnabled() ) + { + getLog().debug( "Made parent update from " + dep.getVersion() + " to " + newVersion ); + } + getChangeRecorder().recordUpdate( changeRecorderTitle, + dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), + newVersion ); + updated = true; + } + + if ( PomHelper.setDependencyVersion( pom, + dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), + newVersion, getProject().getModel() ) ) + { + if ( getLog().isInfoEnabled() ) + { + getLog().info( "Updated " + toString( dep ) + " to version " + newVersion ); + } + getChangeRecorder().recordUpdate( changeRecorderTitle, + dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), + newVersion ); + updated = true; + } + + return updated; + } + + // TODO: add an updatePropertyVersion as well??? (like in CompareDependenciesMojo) } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java index 336febe831..26b993dd34 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsReport.java @@ -301,17 +301,13 @@ protected ArtifactVersion findLatestVersion( Artifact artifact, VersionRange ver } } - /** - * @see org.apache.maven.reporting.AbstractMavenReport#getProject() - */ + @Override protected MavenProject getProject() { return project; } - /** - * @see org.apache.maven.reporting.AbstractMavenReport#getOutputDirectory() - */ + @Override protected String getOutputDirectory() { if ( !outputDirectory.isAbsolute() ) @@ -322,25 +318,19 @@ protected String getOutputDirectory() return outputDirectory.getAbsolutePath(); } - /** - * @see org.apache.maven.reporting.AbstractMavenReport#getSiteRenderer() - */ + @Override protected Renderer getSiteRenderer() { return siteRenderer; } - /** - * @see org.apache.maven.reporting.MavenReport#getDescription(java.util.Locale) - */ + @Override public String getDescription( Locale locale ) { return getText( locale, "report.description" ); } - /** - * @see org.apache.maven.reporting.MavenReport#getName(java.util.Locale) - */ + @Override public String getName( Locale locale ) { return getText( locale, "report.title" ); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java index 9a526ca644..9246878421 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java @@ -205,10 +205,11 @@ public abstract class AbstractVersionsUpdaterMojo @Parameter( property = "changeRecorderOutputFile", defaultValue = "${project.build.directory}/versions-changes.xml" ) private File changeRecorderOutputFile; + /** * The change recorder implementation. */ - private ChangeRecorder changeRecorder; + private volatile ChangeRecorder changeRecorder; /** *

Allows specifying the {@linkplain RuleSet} object describing rules @@ -317,12 +318,25 @@ public String getVersion() public void execute() throws MojoExecutionException, MojoFailureException { + validateInput(); File outFile = project.getFile(); process( outFile ); } // -------------------------- OTHER METHODS -------------------------- + /** + * Validates input parameters + * + * @throws MojoExecutionException thrown if any of input parameters is invalid + */ + protected void validateInput() throws MojoExecutionException + { + if ( !"none".equals( changeRecorderFormat ) && !"xml".equals( changeRecorderFormat ) ) + { + throw new MojoExecutionException( "Only 'xml' or 'none' formats are supported for change recordings" ); + } + } /** * Finds the latest version of the specified artifact that matches the version range. * @@ -560,24 +574,21 @@ else if ( PomHelper.setPropertyVersion( pom, version.getProfileId(), property.ge * Configure and return the change recorder. * * @return The change recorder - * @throws MojoExecutionException If the provided change recorder format is not valid */ - - protected ChangeRecorder getChangeRecorder() throws MojoExecutionException + protected ChangeRecorder getChangeRecorder() { if ( changeRecorder == null ) { - if ( "none".equals( this.changeRecorderFormat ) ) - { - changeRecorder = ChangeRecorderNull.create(); - } - else if ( "xml".equals( this.changeRecorderFormat ) ) + synchronized ( this ) { - changeRecorder = ChangeRecorderXML.create(); - } - else - { - throw new MojoExecutionException( "Only 'xml' or 'none' formats are supported for change recordings" ); + if ( changeRecorder == null ) + { + changeRecorder = "none".equals( this.changeRecorderFormat ) + ? new ChangeRecorderNull() + : "xml".equals( this.changeRecorderFormat ) + ? new ChangeRecorderXML() + : null; + } } } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java index 807ebd4c36..1182945f14 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/CompareDependenciesMojo.java @@ -52,6 +52,8 @@ import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.mojo.versions.utils.DependencyBuilder; +import static java.util.Collections.singletonList; + /** * Compare dependency versions of the current project to dependencies or dependency management of a remote repository * project. Can optionally update locally the project instead of reporting the comparison @@ -182,36 +184,56 @@ protected void update( ModifiedPomXMLEventReader pom ) Map remoteDepsMap = new HashMap<>(); if ( !ignoreRemoteDependencyManagement ) { - List remoteProjectDepMgmtDeps = ( remoteMavenProject.getDependencyManagement() == null ) ? null - : remoteMavenProject.getDependencyManagement().getDependencies(); - mapDependencies( remoteDepsMap, remoteProjectDepMgmtDeps ); + List remoteProjectDepMgmtDeps = remoteMavenProject.getDependencyManagement() == null + ? null + : remoteMavenProject.getDependencyManagement().getDependencies(); + if ( remoteProjectDepMgmtDeps != null ) + { + remoteProjectDepMgmtDeps.forEach( dep -> remoteDepsMap.putIfAbsent( dep.getManagementKey(), dep ) ); + } } - if ( !ignoreRemoteDependencies ) + if ( !ignoreRemoteDependencies && remoteMavenProject.getDependencies() != null ) { - List remoteProjectDeps = remoteMavenProject.getDependencies(); - mapDependencies( remoteDepsMap, remoteProjectDeps ); + remoteMavenProject.getDependencies().forEach( dep -> + remoteDepsMap.putIfAbsent( dep.getManagementKey(), dep ) ); } List totalDiffs = new ArrayList<>(); List propertyDiffs = new ArrayList<>(); if ( getProject().getDependencyManagement() != null && isProcessingDependencyManagement() ) { - List depManDiffs = - compareVersions( pom, getProject().getDependencyManagement().getDependencies(), remoteDepsMap ); - totalDiffs.addAll( depManDiffs ); + totalDiffs.addAll( + compareVersions( pom, getProject().getDependencyManagement().getDependencies(), remoteDepsMap ) ); } if ( getProject().getDependencies() != null && isProcessingDependencies() ) { - List depDiffs = compareVersions( pom, getProject().getDependencies(), remoteDepsMap ); - totalDiffs.addAll( depDiffs ); + totalDiffs.addAll( compareVersions( pom, getProject().getDependencies(), remoteDepsMap ) ); } if ( updatePropertyVersions ) { Map versionProperties = this.getHelper().getVersionPropertiesMap( VersionsHelper.VersionPropertiesMapRequest.builder() .withMavenProject( getProject() ).build() ); - List diff = updatePropertyVersions( pom, versionProperties, remoteDepsMap ); - propertyDiffs.addAll( diff ); + propertyDiffs.addAll( updatePropertyVersions( pom, versionProperties, remoteDepsMap ) ); + } + if ( getProject().getParent() != null + && remoteMavenProject.getParent() != null + && isProcessingParent() ) + { + Dependency parent = DependencyBuilder.newBuilder() + .withGroupId( remoteMavenProject.getParentArtifact().getGroupId() ) + .withArtifactId( remoteMavenProject.getParentArtifact().getArtifactId() ) + .withVersion( remoteMavenProject.getParentArtifact().getVersion() ) + .withType( remoteMavenProject.getParentArtifact().getType() ) + .withScope( remoteMavenProject.getParentArtifact().getScope() ) + .withClassifier( remoteMavenProject.getParentArtifact().getClassifier() ) + .build(); + if ( getLog().isDebugEnabled() ) + { + getLog().debug( "Processing parent dependency: " + parent ); + } + remoteDepsMap.putIfAbsent( parent.getManagementKey(), parent ); + totalDiffs.addAll( compareVersions( pom, singletonList( getParentDependency() ), remoteDepsMap ) ); } if ( reportMode ) @@ -271,19 +293,13 @@ private List compareVersions( ModifiedPomXMLEventReader pom, List map, List deps ) - { - if ( deps != null ) - { - for ( Dependency nextDep : deps ) - { - map.put( nextDep.getManagementKey(), nextDep ); - } - } - } - /** * Creates a key that is similar to what {@link Dependency#getManagementKey()} generates for a dependency. */ diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java index da5b9a0b8a..75edfbb470 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/DisplayDependencyUpdatesMojo.java @@ -488,7 +488,6 @@ public void execute() throws MojoExecutionException, MojoFailureException { logInit(); - validateInput(); Set dependencyManagement = new TreeSet<>( DependencyComparator.INSTANCE ); @@ -599,7 +598,8 @@ public void execute() } } - private void validateInput() throws MojoExecutionException + @Override + protected void validateInput() throws MojoExecutionException { validateGAVList( dependencyIncludes, 6, "dependencyIncludes" ); validateGAVList( dependencyExcludes, 6, "dependencyExcludes" ); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ForceReleasesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ForceReleasesMojo.java index 56c9812643..564817c333 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ForceReleasesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/ForceReleasesMojo.java @@ -24,7 +24,6 @@ import java.util.Collection; import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.manager.WagonManager; @@ -32,16 +31,19 @@ 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.VersionRange; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; +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.rewriting.ModifiedPomXMLEventReader; +import static java.util.Collections.singletonList; + /** * Replaces any -SNAPSHOT versions with a release version, older if necessary (if there has been a release). * @@ -52,13 +54,13 @@ public class ForceReleasesMojo extends AbstractVersionsDependencyUpdaterMojo { - - // ------------------------------ FIELDS ------------------------------ - /** - * Pattern to match a snapshot version. + * Whether to fail if a SNAPSHOT could not be replaced + * + * @since 2.14.0 */ - private final Pattern matchSnapshotRegex = Pattern.compile( "^(.+)-((SNAPSHOT)|(\\d{8}\\.\\d{6}-\\d+))$" ); + @Parameter( property = "failIfNotReplaced", defaultValue = "false" ) + protected boolean failIfNotReplaced; // ------------------------------ METHODS -------------------------- @@ -92,6 +94,10 @@ protected void update( ModifiedPomXMLEventReader pom ) { useReleases( pom, getProject().getDependencies() ); } + if ( getProject().getParent() != null && isProcessingParent() ) + { + useReleases( pom, singletonList( getParentDependency() ) ); + } } catch ( ArtifactMetadataRetrievalException e ) { @@ -116,8 +122,7 @@ private void useReleases( ModifiedPomXMLEventReader pom, Collection continue; } - String version = dep.getVersion(); - Matcher versionMatcher = matchSnapshotRegex.matcher( version ); + Matcher versionMatcher = SNAPSHOT_REGEX.matcher( dep.getVersion() ); if ( versionMatcher.matches() ) { String releaseVersion = versionMatcher.group( 1 ); @@ -131,23 +136,24 @@ private void useReleases( ModifiedPomXMLEventReader pom, Collection ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false ); if ( versions.containsVersion( releaseVersion ) ) { - if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, - releaseVersion, getProject().getModel() ) ) - { - getLog().info( "Updated " + toString( dep ) + " to version " + releaseVersion ); - } + updateDependencyVersion( pom, dep, releaseVersion, "forceReleases" ); } else { - ArtifactVersion[] v = versions.getVersions( false ); - if ( v.length == 0 ) + ArtifactVersion newestRelease = versions.getNewestVersion( (VersionRange) null, null, + false, true ); + if ( newestRelease == null ) { getLog().info( "No release of " + toString( dep ) + " to force." ); + if ( failIfNotReplaced ) + { + throw new MojoExecutionException( "No matching release of " + toString( dep ) + + " found for update." ); + } } - else if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, - v[v.length - 1].toString(), getProject().getModel() ) ) + else { - getLog().info( "Reverted " + toString( dep ) + " to version " + v[v.length - 1].toString() ); + updateDependencyVersion( pom, dep, newestRelease.toString(), "forceReleases" ); } } } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/LockSnapshotsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/LockSnapshotsMojo.java index 9e17a35942..1e57f49ba2 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/LockSnapshotsMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/LockSnapshotsMojo.java @@ -59,7 +59,7 @@ public class LockSnapshotsMojo /** * Pattern to match a timestamped snapshot version. For example 1.0-20090128.202731-1 */ - private final Pattern matchSnapshotRegex = Pattern.compile( "-" + Artifact.SNAPSHOT_VERSION ); + private static final Pattern TIMESTAMPED_SNAPSHOT_REGEX = Pattern.compile( "-" + Artifact.SNAPSHOT_VERSION ); // ------------------------------ METHODS -------------------------- @@ -120,7 +120,7 @@ private void lockSnapshots( ModifiedPomXMLEventReader pom, Collection de } String version = dep.getVersion(); - Matcher versionMatcher = matchSnapshotRegex.matcher( version ); + Matcher versionMatcher = TIMESTAMPED_SNAPSHOT_REGEX.matcher( version ); if ( versionMatcher.find() && versionMatcher.end() == version.length() ) { String unlockedVersion = versionMatcher.replaceFirst( "-SNAPSHOT" ); @@ -153,7 +153,7 @@ private void unlockParentSnapshot( ModifiedPomXMLEventReader pom, MavenProject p Artifact parentArtifact = parent.getArtifact(); String parentVersion = parentArtifact.getVersion(); - Matcher versionMatcher = matchSnapshotRegex.matcher( parentVersion ); + Matcher versionMatcher = TIMESTAMPED_SNAPSHOT_REGEX.matcher( parentVersion ); if ( versionMatcher.find() && versionMatcher.end() == parentVersion.length() ) { String unlockedParentVersion = versionMatcher.replaceFirst( "-SNAPSHOT" ); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java index ccd389e0ad..9c6b649c0e 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java @@ -37,9 +37,10 @@ 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; +import static java.util.Collections.singletonList; + /** * Updates a dependency to a specific version. * This can be useful if you have to manage versions for a very large (100+ module) projects where you can’t always use @@ -107,6 +108,11 @@ protected void update( ModifiedPomXMLEventReader pom ) { useDepVersion( pom, getProject().getDependencies() ); } + + if ( getProject().getParent() != null && isProcessingParent() ) + { + useDepVersion( pom, singletonList( getParentDependency() ) ); + } } catch ( ArtifactMetadataRetrievalException e ) { @@ -146,17 +152,7 @@ private void useDepVersion( ModifiedPomXMLEventReader pom, Collection dependencies ) throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException { @@ -172,7 +159,7 @@ private void useLatestReleases( ModifiedPomXMLEventReader pom, Collection !matchSnapshotRegex.matcher( dep.getVersion() ).matches() ); + dep -> !SNAPSHOT_REGEX.matcher( dep.getVersion() ).matches() ); } /** diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java index 8e64ab4915..0e4249a178 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseLatestSnapshotsMojo.java @@ -22,21 +22,15 @@ import javax.inject.Inject; import javax.xml.stream.XMLStreamException; -import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Comparator; import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -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.artifact.versioning.Restriction; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -44,16 +38,13 @@ 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.BoundArtifactVersion; -import org.codehaus.mojo.versions.ordering.VersionComparator; +import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.DependencyBuilder; import org.codehaus.mojo.versions.utils.SegmentUtils; import static java.util.Collections.singletonList; +import static java.util.Optional.empty; /** * Replaces any release versions with the latest snapshot version (if it has been deployed). @@ -63,7 +54,7 @@ */ @Mojo( name = "use-latest-snapshots", threadSafe = true ) public class UseLatestSnapshotsMojo - extends AbstractVersionsDependencyUpdaterMojo + extends UseLatestVersionsMojoBase { /** @@ -93,13 +84,6 @@ public class UseLatestSnapshotsMojo @Parameter( property = "allowIncrementalUpdates", defaultValue = "true" ) protected boolean allowIncrementalUpdates; - // ------------------------------ FIELDS ------------------------------ - - /** - * Pattern to match a snapshot version. - */ - private final Pattern matchSnapshotRegex = Pattern.compile( "^(.+)-((SNAPSHOT)|(\\d{8}\\.\\d{6}-\\d+))$" ); - // ------------------------------ METHODS -------------------------- @Inject @@ -134,12 +118,7 @@ protected void update( ModifiedPomXMLEventReader pom ) } if ( getProject().getParent() != null && isProcessingParent() ) { - useLatestSnapshots( pom, singletonList( DependencyBuilder.newBuilder() - .withGroupId( getProject().getParent().getGroupId() ) - .withArtifactId( getProject().getParent().getArtifactId() ) - .withVersion( getProject().getParent().getVersion() ) - .withType( "pom" ) - .build() ) ); + useLatestSnapshots( pom, singletonList( getParentDependency() ) ); } } catch ( ArtifactMetadataRetrievalException e ) @@ -149,101 +128,27 @@ protected void update( ModifiedPomXMLEventReader pom ) } private void useLatestSnapshots( 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(); - Matcher versionMatcher = matchSnapshotRegex.matcher( version ); - if ( !versionMatcher.matches() ) - { - getLog().debug( "Looking for latest snapshot of " + toString( dep ) ); - Artifact artifact = this.toArtifact( dep ); - if ( !isIncluded( artifact ) ) - { - continue; - } - - ArtifactVersion selectedVersion = new DefaultArtifactVersion( version ); - - ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false ); - final VersionComparator versionComparator = versions.getVersionComparator(); - final DefaultArtifactVersion lowerBound = new DefaultArtifactVersion( version ); - if ( unchangedSegment.isPresent() - && unchangedSegment.get().value() >= versionComparator.getSegmentCount( lowerBound ) ) - { - getLog().info( "Ignoring " + toString( dep ) + " as the version number is too short" ); - continue; - } - ArtifactVersion upperBound = unchangedSegment - .map( s -> - (ArtifactVersion) new BoundArtifactVersion( lowerBound, Segment.of( s.value() + 1 ) ) ) - .orElse( null ); - - getLog().info( "Upper bound: " + ( upperBound == null ? "none" : upperBound.toString() ) ); - Restriction restriction = new Restriction( lowerBound, false, upperBound, false ); - ArtifactVersion[] newer = versions.getVersions( restriction, true ); - getLog().debug( "Candidate versions " + Arrays.asList( newer ) ); - - // TODO consider creating a search + filter in the Details services to get latest snapshot. - String latestVersion; - ArrayList snapshotsOnly = new ArrayList<>(); - - for ( ArtifactVersion artifactVersion : newer ) - { - String newVersion = artifactVersion.toString(); - if ( matchSnapshotRegex.matcher( newVersion ).matches() ) - { - snapshotsOnly.add( artifactVersion ); - } - } - ArtifactVersion[] filteredVersions = snapshotsOnly.toArray( - new ArtifactVersion[snapshotsOnly.size()] ); - if ( filteredVersions.length > 0 ) + useLatestVersions( pom, dependencies, + ( dep, versions ) -> { - latestVersion = 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, latestVersion ) ) - { - getLog().debug( "Made parent update from " + version + " to " + latestVersion ); - - this.getChangeRecorder() - .recordUpdate( "useLatestSnapshots", parentArtifact.getGroupId(), - parentArtifact.getArtifactId(), version, latestVersion ); - } - } + return Arrays.stream( versions.getNewerVersions( dep.getVersion(), unchangedSegment, + true, false ) ) + .filter( v -> SNAPSHOT_REGEX.matcher( v.toString() ).matches() ) + .max( Comparator.naturalOrder() ); } - - if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, - latestVersion, getProject().getModel() ) ) + catch ( InvalidSegmentException e ) { - getLog().info( "Updated " + toString( dep ) + " to version " + latestVersion ); - - this.getChangeRecorder().recordUpdate( "useLatestSnapshots", dep.getGroupId(), - dep.getArtifactId(), version, latestVersion ); + getLog().info( "Ignoring " + toString( dep ) + " as the version number is too short" ); + return empty(); } - } - } - } + }, + "useLatestSnapshots", dep -> !SNAPSHOT_REGEX.matcher( dep.getVersion() ).matches() ); } - } 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 f5009dc2ee..d5fb92067a 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 @@ -42,7 +42,6 @@ import org.codehaus.mojo.versions.api.Segment; import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; -import org.codehaus.mojo.versions.utils.DependencyBuilder; import org.codehaus.mojo.versions.utils.SegmentUtils; import static java.util.Collections.singletonList; @@ -145,12 +144,7 @@ protected void update( ModifiedPomXMLEventReader pom ) } if ( getProject().getParent() != null && isProcessingParent() ) { - useLatestVersions( pom, singletonList( DependencyBuilder.newBuilder() - .withGroupId( getProject().getParent().getGroupId() ) - .withArtifactId( getProject().getParent().getArtifactId() ) - .withVersion( getProject().getParent().getVersion() ) - .withType( "pom" ) - .build() ) ); + useLatestVersions( pom, singletonList( getParentDependency() ) ); } } catch ( ArtifactMetadataRetrievalException | IOException e ) @@ -159,7 +153,6 @@ protected void update( ModifiedPomXMLEventReader pom ) } } - @SuppressWarnings( "unchecked" ) private void useLatestVersions( ModifiedPomXMLEventReader pom, Collection dependencies ) throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException { 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 index 05a657a623..90f0deb7ac 100644 --- 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 @@ -39,7 +39,6 @@ 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; /** @@ -110,37 +109,12 @@ protected final void useLatestVersions( ModifiedPomXMLEventReader pom, 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 ); - } + updateDependencyVersion( pom, dep, newestVer.get().toString(), changeRecorderTitle ); } } } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java index 149cc23f0f..0045193de5 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextReleasesMojo.java @@ -23,25 +23,23 @@ import javax.xml.stream.XMLStreamException; import java.util.Collection; -import java.util.regex.Matcher; import java.util.regex.Pattern; -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.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; 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; +import static java.util.Collections.singletonList; +import static java.util.Optional.of; + /** * Replaces any release versions with the next release version (if it has been released). * @@ -50,7 +48,7 @@ */ @Mojo( name = "use-next-releases", threadSafe = true ) public class UseNextReleasesMojo - extends AbstractVersionsDependencyUpdaterMojo + extends UseLatestVersionsMojoBase { // ------------------------------ FIELDS ------------------------------ @@ -90,53 +88,17 @@ protected void update( ModifiedPomXMLEventReader pom ) { useNextReleases( pom, getProject().getDependencies() ); } + if ( getProject().getParent() != null && isProcessingParent() ) + { + useNextReleases( pom, singletonList( getParentDependency() ) ); + } } private void useNextReleases( ModifiedPomXMLEventReader pom, Collection dependencies ) - throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException + throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException { - 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(); - Matcher versionMatcher = MATCH_SNAPSHOT_REGEX.matcher( version ); - if ( !versionMatcher.matches() ) - { - getLog().debug( "Looking for newer versions of " + toString( dep ) ); - Artifact artifact = this.toArtifact( dep ); - if ( !isIncluded( artifact ) ) - { - continue; - } - - ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false ); - ArtifactVersion[] newer = versions.getNewerVersions( version, false ); - if ( newer.length > 0 ) - { - String newVersion = newer[0].toString(); - if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, - newVersion, getProject().getModel() ) ) - - { - getLog().info( "Updated " + toString( dep ) + " to version " + newVersion ); - - this.getChangeRecorder().recordUpdate( "useNextReleases", dep.getGroupId(), - dep.getArtifactId(), version, newVersion ); - } - } - } - } + useLatestVersions( pom, dependencies, + ( dep, versions ) -> of( versions.getNewerVersions( dep.getVersion(), false )[0] ), + "useNextReleases", dep -> !SNAPSHOT_REGEX.matcher( dep.getVersion() ).matches() ); } - } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java index b7482490ca..3546193a89 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextSnapshotsMojo.java @@ -25,17 +25,11 @@ import java.util.Arrays; import java.util.Collection; import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -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.artifact.versioning.Restriction; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; @@ -43,14 +37,14 @@ 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.BoundArtifactVersion; -import org.codehaus.mojo.versions.ordering.VersionComparator; +import org.codehaus.mojo.versions.ordering.InvalidSegmentException; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.mojo.versions.utils.SegmentUtils; +import static java.util.Collections.singletonList; +import static java.util.Optional.empty; + /** * Replaces any release versions with the next snapshot version (if it has been deployed). * @@ -59,7 +53,7 @@ */ @Mojo( name = "use-next-snapshots", threadSafe = true ) public class UseNextSnapshotsMojo - extends AbstractVersionsDependencyUpdaterMojo + extends UseLatestVersionsMojoBase { /** @@ -89,13 +83,6 @@ public class UseNextSnapshotsMojo @Parameter( property = "allowIncrementalUpdates", defaultValue = "true" ) private boolean allowIncrementalUpdates; - // ------------------------------ FIELDS ------------------------------ - - /** - * Pattern to match a snapshot version. - */ - private final Pattern matchSnapshotRegex = Pattern.compile( "^(.+)-((SNAPSHOT)|(\\d{8}\\.\\d{6}-\\d+))$" ); - // ------------------------------ METHODS -------------------------- @Inject @@ -106,6 +93,8 @@ public UseNextSnapshotsMojo( RepositorySystem repositorySystem, ArtifactResolver artifactResolver ) { super( repositorySystem, projectBuilder, artifactMetadataSource, wagonManager, artifactResolver ); + // the below is necessary for UseLatestVersionsMojoBase.useLatestVersions to select snapshots + allowSnapshots = true; } /** @@ -128,6 +117,10 @@ protected void update( ModifiedPomXMLEventReader pom ) { useNextSnapshots( pom, getProject().getDependencies() ); } + if ( getProject().getParent() != null && isProcessingParent() ) + { + useNextSnapshots( pom, singletonList( getParentDependency() ) ); + } } catch ( ArtifactMetadataRetrievalException e ) { @@ -136,74 +129,28 @@ protected void update( ModifiedPomXMLEventReader pom ) } private void useNextSnapshots( 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(); - Matcher versionMatcher = matchSnapshotRegex.matcher( version ); - if ( !versionMatcher.matches() ) - { - getLog().debug( "Looking for next snapshot of " + toString( dep ) ); - Artifact artifact = this.toArtifact( dep ); - if ( !isIncluded( artifact ) ) - { - continue; - } - - ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false ); - final VersionComparator versionComparator = versions.getVersionComparator(); - final DefaultArtifactVersion lowerBound = new DefaultArtifactVersion( version ); - if ( unchangedSegment.isPresent() - && unchangedSegment.get().value() >= versionComparator.getSegmentCount( lowerBound ) ) - { - getLog().info( "Ignoring " + toString( dep ) + " as the version number is too short" ); - continue; - } - - ArtifactVersion upperBound = unchangedSegment - .map( s -> - (ArtifactVersion) new BoundArtifactVersion( lowerBound, Segment.of( s.value() + 1 ) ) ) - .orElse( null ); - - getLog().info( "Upper bound: " + ( upperBound == null ? "none" : upperBound.toString() ) ); - Restriction restriction = new Restriction( lowerBound, false, upperBound, false ); - ArtifactVersion[] newer = versions.getVersions( restriction, true ); - getLog().debug( "Candidate versions " + Arrays.asList( newer ) ); - for ( ArtifactVersion artifactVersion : newer ) + useLatestVersions( pom, dependencies, + ( dep, versions ) -> { - String newVersion = artifactVersion.toString(); - if ( matchSnapshotRegex.matcher( newVersion ).matches() ) + try { - if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, - newVersion, getProject().getModel() ) ) - { - getLog().info( "Updated " + toString( dep ) + " to version " + newVersion ); - - this.getChangeRecorder().recordUpdate( "useNextSnapshots", dep.getGroupId(), - dep.getArtifactId(), version, newVersion ); - } - break; + return Arrays.stream( versions.getNewerVersions( dep.getVersion(), unchangedSegment, + true, false ) ) + .filter( v -> SNAPSHOT_REGEX.matcher( v.toString() ).matches() ) + .findFirst(); } - } - } - } + catch ( InvalidSegmentException e ) + { + getLog().info( "Ignoring " + toString( dep ) + " as the version number is too short" ); + return empty(); + } + }, + "useNextSnapshots", dep -> !SNAPSHOT_REGEX.matcher( dep.getVersion() ).matches() ); } - } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java index ba0223cf98..81c9fbaa50 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseNextVersionsMojo.java @@ -24,22 +24,21 @@ import java.util.Collection; -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.model.Dependency; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; 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; +import static java.util.Collections.singletonList; +import static java.util.Optional.of; + /** * Replaces any version with the latest version. * @@ -48,7 +47,7 @@ */ @Mojo( name = "use-next-versions", threadSafe = true ) public class UseNextVersionsMojo - extends AbstractVersionsDependencyUpdaterMojo + extends UseLatestVersionsMojoBase { // ------------------------------ METHODS -------------------------- @@ -83,6 +82,10 @@ protected void update( ModifiedPomXMLEventReader pom ) { useNextVersions( pom, getProject().getDependencies() ); } + if ( getProject().getParent() != null && isProcessingParent() ) + { + useNextVersions( pom, singletonList( getParentDependency() ) ); + } } catch ( ArtifactMetadataRetrievalException e ) { @@ -91,45 +94,10 @@ protected void update( ModifiedPomXMLEventReader pom ) } private void useNextVersions( ModifiedPomXMLEventReader pom, Collection dependencies ) - throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException + throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException { - 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; - } - - getLog().debug( "Looking for newer versions of " + toString( dep ) ); - ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false ); - ArtifactVersion[] newer = versions.getNewerVersions( version, Boolean.TRUE.equals( allowSnapshots ) ); - if ( newer.length > 0 ) - { - String newVersion = newer[0].toString(); - if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, newVersion, - getProject().getModel() ) ) - { - getLog().info( "Updated " + toString( dep ) + " to version " + newVersion ); - - this.getChangeRecorder().recordUpdate( "useNextVersions", dep.getGroupId(), - dep.getArtifactId(), version, newVersion ); - } - } - } + useLatestVersions( pom, dependencies, + ( dep, versions ) -> of( versions.getNewerVersions( dep.getVersion(), allowSnapshots )[0] ), + "useNextVersions" ); } - } diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java index 6e71ff0aaa..eac9aac15e 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/UseReleasesMojo.java @@ -22,10 +22,10 @@ import javax.inject.Inject; import javax.xml.stream.XMLStreamException; +import java.util.Arrays; import java.util.Collection; -import java.util.NoSuchElementException; +import java.util.Optional; import java.util.regex.Matcher; -import java.util.regex.Pattern; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.manager.WagonManager; @@ -38,13 +38,13 @@ import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; -import org.apache.maven.project.MavenProject; 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; -import org.codehaus.mojo.versions.utils.DependencyBuilder; + +import static java.util.Collections.singletonList; /** * Replaces any -SNAPSHOT versions with the corresponding release version (if it has been released). @@ -58,7 +58,11 @@ public class UseReleasesMojo { /** - * Whether to check for releases within the range. + *

When set to {@code true}, will use the highest found release version matching a string + * starting with the current version string without {@code -SNAPSHOT}.

+ *

For example, if the current version is {@code 1.1-SNAPSHOT}, will match all versions + * starting with {@code 1.1}, i.e. {@code 1.1}, {@code 1.1.1}, {@code 1.1.2}, {@code 1.1.3.1}, etc., + * and will select the highest found version, i.e. {@code 1.1.3.1}.

* * @since 2.3 */ @@ -71,14 +75,7 @@ public class UseReleasesMojo * @since 2.3 */ @Parameter( property = "failIfNotReplaced", defaultValue = "false" ) - private boolean failIfNotReplaced; - - // ------------------------------ FIELDS ------------------------------ - - /** - * Pattern to match a snapshot version. - */ - private final Pattern matchSnapshotRegex = Pattern.compile( "^(.+)-((SNAPSHOT)|(\\d{8}\\.\\d{6}-\\d+))$" ); + protected boolean failIfNotReplaced; // ------------------------------ METHODS -------------------------- @@ -104,11 +101,6 @@ protected void update( ModifiedPomXMLEventReader pom ) { try { - if ( getProject().getParent() != null && isProcessingParent() ) - { - useReleases( pom, getProject().getParent() ); - } - if ( getProject().getDependencyManagement() != null && isProcessingDependencyManagement() ) { useReleases( pom, PomHelper.readImportedPOMsFromDependencyManagementSection( pom ) ); @@ -118,6 +110,10 @@ protected void update( ModifiedPomXMLEventReader pom ) { useReleases( pom, getProject().getDependencies() ); } + if ( getProject().getParent() != null && isProcessingParent() ) + { + useReleases( pom, singletonList( getParentDependency() ) ); + } } catch ( ArtifactMetadataRetrievalException e ) { @@ -125,86 +121,6 @@ protected void update( ModifiedPomXMLEventReader pom ) } } - private void useReleases( ModifiedPomXMLEventReader pom, MavenProject project ) - throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException - { - String version = project.getVersion(); - Matcher versionMatcher = matchSnapshotRegex.matcher( version ); - if ( versionMatcher.matches() ) - { - String releaseVersion = versionMatcher.group( 1 ); - - final MavenProject parent = getProject().getParent(); - - Artifact artifact = getHelper().createDependencyArtifact( DependencyBuilder.newBuilder() - .withGroupId( parent.getGroupId() ) - .withArtifactId( parent.getArtifactId() ) - .withVersion( releaseVersion ) - .withType( "pom" ) - .build() ); - if ( !isIncluded( artifact ) ) - { - return; - } - - getLog().debug( "Looking for a release of " + toString( project ) ); - // Force releaseVersion version because org.apache.maven.artifact.metadata.MavenMetadataSource does not - // retrieve release version if provided snapshot version. - artifact.setVersion( releaseVersion ); - ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false ); - if ( !allowRangeMatching ) // standard behaviour - { - if ( versions.containsVersion( releaseVersion ) ) - { - if ( PomHelper.setProjectParentVersion( pom, releaseVersion ) ) - { - getLog().info( "Updated " + toString( project ) + " to version " + releaseVersion ); - } - } - else if ( failIfNotReplaced ) - { - throw new NoSuchElementException( "No matching release of " + toString( project ) - + " found for update." ); - } - } - else - { - ArtifactVersion finalVersion = null; - for ( ArtifactVersion proposedVersion : versions.getVersions( false ) ) - { - if ( proposedVersion.toString().startsWith( releaseVersion ) ) - { - getLog().debug( "Found matching version for " + toString( project ) + " to version " - + releaseVersion ); - finalVersion = proposedVersion; - } - } - - if ( finalVersion != null ) - { - if ( PomHelper.setProjectParentVersion( pom, finalVersion.toString() ) ) - { - getLog().info( "Updated " + toString( project ) + " to version " + finalVersion ); - - this.getChangeRecorder().recordUpdate( "useReleases", parent.getGroupId(), - parent.getArtifactId(), version, - finalVersion.toString() ); - } - } - else - { - getLog().info( "No matching release of " + toString( project ) + " to update via rangeMatching." ); - if ( failIfNotReplaced ) - { - throw new NoSuchElementException( "No matching release of " + toString( project ) - + " found for update via rangeMatching." ); - } - } - - } - } - } - private void useReleases( ModifiedPomXMLEventReader pom, Collection dependencies ) throws XMLStreamException, MojoExecutionException, ArtifactMetadataRetrievalException { @@ -228,7 +144,7 @@ private void useReleases( ModifiedPomXMLEventReader pom, Collection getLog().info( "Ignoring dependency with no version: " + toString( dep ) ); continue; } - Matcher versionMatcher = matchSnapshotRegex.matcher( version ); + Matcher versionMatcher = SNAPSHOT_REGEX.matcher( version ); if ( versionMatcher.matches() ) { String releaseVersion = versionMatcher.group( 1 ); @@ -242,72 +158,36 @@ private void useReleases( ModifiedPomXMLEventReader pom, Collection // Force releaseVersion version because org.apache.maven.artifact.metadata.MavenMetadataSource does not // retrieve release version if provided snapshot version. artifact.setVersion( releaseVersion ); - ArtifactVersions versions = getHelper().lookupArtifactVersions( artifact, false ); - if ( !allowRangeMatching ) // standard behaviour + Optional targetVersion = findReleaseVersion( pom, dep, version, releaseVersion, + getHelper().lookupArtifactVersions( artifact, false ) ); + if ( targetVersion.isPresent() ) { - noRangeMatching( pom, dep, version, releaseVersion, versions ); + updateDependencyVersion( pom, dep, targetVersion.get(), "useReleases" ); } else { - rangeMatching( pom, dep, version, releaseVersion, versions ); + getLog().info( "No matching release of " + toString( dep ) + " to update." ); + if ( failIfNotReplaced ) + { + throw new MojoExecutionException( "No matching release of " + toString( dep ) + + " found for update" ); + } } } } } - private void rangeMatching( ModifiedPomXMLEventReader pom, Dependency dep, String version, String releaseVersion, - ArtifactVersions versions ) throws XMLStreamException, MojoExecutionException + private Optional findReleaseVersion( ModifiedPomXMLEventReader pom, Dependency dep, String version, + String releaseVersion, ArtifactVersions versions ) { - ArtifactVersion finalVersion = null; - for ( ArtifactVersion proposedVersion : versions.getVersions( false ) ) - { - if ( proposedVersion.toString().startsWith( releaseVersion ) ) - { - getLog().debug( "Found matching version for " + toString( dep ) + " to version " + releaseVersion ); - finalVersion = proposedVersion; - } - } - - if ( finalVersion != null ) - { - if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, - finalVersion.toString(), getProject().getModel() ) ) - { - getLog().info( "Updated " + toString( dep ) + " to version " + finalVersion ); - - this.getChangeRecorder().recordUpdate( "useReleases", dep.getGroupId(), - dep.getArtifactId(), version, finalVersion.toString() ); - } - } - else - { - getLog().info( "No matching release of " + toString( dep ) + " to update via rangeMatching." ); - if ( failIfNotReplaced ) - { - throw new NoSuchElementException( "No matching release of " + toString( dep ) - + " found for update via rangeMatching." ); - } - } + return !allowRangeMatching + ? versions.containsVersion( releaseVersion ) + ? Optional.of( releaseVersion ) + : Optional.empty() + : Arrays.stream( versions.getVersions( false ) ) + .sorted( ( v1, v2 ) -> -( v1.compareTo( v2 ) ) ) + .filter( v -> v.toString().startsWith( releaseVersion ) ) + .findFirst() + .map( ArtifactVersion::toString ); } - - private void noRangeMatching( ModifiedPomXMLEventReader pom, Dependency dep, String version, String releaseVersion, - ArtifactVersions versions ) throws XMLStreamException, MojoExecutionException - { - if ( versions.containsVersion( releaseVersion ) ) - { - if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), version, releaseVersion, - getProject().getModel() ) ) - { - getLog().info( "Updated " + toString( dep ) + " to version " + releaseVersion ); - - this.getChangeRecorder().recordUpdate( "useReleases", dep.getGroupId(), - dep.getArtifactId(), version, releaseVersion ); - } - } - else if ( failIfNotReplaced ) - { - throw new NoSuchElementException( "No matching release of " + toString( dep ) + " found for update." ); - } - } - } 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 2193ddef18..a43033af52 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 @@ -64,10 +64,6 @@ public abstract class AbstractVersionsReportRenderer extends VersionsReportRe protected ArtifactVersionsCache allUpdatesCache = new ArtifactVersionsCache( AbstractVersionDetails::getAllUpdates ); - /** - * Constructor to be called by the dependency injection framework - * @param i18n i18n object to be injected - */ protected AbstractVersionsReportRenderer( I18N i18n, Sink sink, Locale locale, String bundleName, T model ) { super( sink, i18n, locale, bundleName ); diff --git a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactory.java b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactory.java index c762b2efb8..1b977ecc5c 100644 --- a/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactory.java +++ b/versions-maven-plugin/src/main/java/org/codehaus/mojo/versions/reporting/ReportRendererFactory.java @@ -32,6 +32,7 @@ public interface ReportRendererFactory /** * Creates a new {@linkplain ReportRenderer} instance for the given report renderer name. * + * @param class of the model being rendered * @param concrete class of the report renderer * @param reportName name of the report to generate * @param sink sink to use for rendering diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/ForceReleasesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/ForceReleasesMojoTest.java new file mode 100644 index 0000000000..e1af267f61 --- /dev/null +++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/ForceReleasesMojoTest.java @@ -0,0 +1,199 @@ +package org.codehaus.mojo.versions; + +import javax.xml.stream.XMLStreamException; + +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.model.Model; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.apache.maven.plugin.testing.ArtifactStubFactory; +import org.apache.maven.plugin.testing.stubs.StubArtifactResolver; +import org.apache.maven.project.MavenProject; +import org.codehaus.mojo.versions.api.PomHelper; +import org.codehaus.mojo.versions.change.VersionChange; +import org.codehaus.mojo.versions.utils.DependencyBuilder; +import org.codehaus.mojo.versions.utils.TestChangeRecorder; +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockedStatic; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE; +import static org.codehaus.mojo.versions.utils.MockUtils.mockArtifactMetadataSource; +import static org.codehaus.mojo.versions.utils.MockUtils.mockRepositorySystem; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.startsWith; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mockStatic; + +/* + * 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. + */ + +/** + * Unit tests for {@link ForceReleasesMojo} + */ +public class ForceReleasesMojoTest extends AbstractMojoTestCase +{ + private TestChangeRecorder changeRecorder; + private ForceReleasesMojo mojo; + + @Before + public void setUp() throws IllegalAccessException + { + changeRecorder = new TestChangeRecorder(); + mojo = new ForceReleasesMojo( mockRepositorySystem(), + null, mockArtifactMetadataSource(), + null, new StubArtifactResolver( new ArtifactStubFactory(), + false, false ) ); + setVariableValueToObject( mojo, "reactorProjects", emptyList() ); + setVariableValueToObject( mojo, "changeRecorder", changeRecorder ); + mojo.project = new MavenProject() + {{ + setModel( new Model() + {{ + setGroupId( "default-group" ); + setArtifactId( "default-artifact" ); + setVersion( "1.0.0" ); + }} ); + }}; + } + + @Test + public void testProcessParent() + throws MojoExecutionException, XMLStreamException, MojoFailureException, IllegalAccessException + { + setVariableValueToObject( mojo, "processParent", true ); + mojo.getProject().setParent( new MavenProject( new Model() + {{ + setGroupId( "default-group" ); + setArtifactId( "artifactA" ); + setVersion( "1.0.0-SNAPSHOT" ); + }} ) ); + mojo.getProject().setParentArtifact( new DefaultArtifact( "default-group", "artifactA", + "1.0.0-SNAPSHOT", SCOPE_COMPILE, "pom", "default", null ) ); + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setProjectParentVersion( any(), anyString() ) ) + .thenReturn( true ); + mojo.update( null ); + } + assertThat( changeRecorder.getChanges(), + hasItem( new VersionChange( "default-group", "artifactA", + "1.0.0-SNAPSHOT", "1.0.0" ) ) ); + } + + @Test + public void testReplaceSnapshotWithRelease() + throws MojoExecutionException, XMLStreamException, MojoFailureException + { + mojo.getProject().setDependencies( singletonList( DependencyBuilder.newBuilder() + .withGroupId( "default-group" ) + .withArtifactId( "artifactA" ) + .withVersion( "1.0.0-SNAPSHOT" ) + .build() ) ); + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setDependencyVersion( any(), anyString(), anyString(), anyString(), + anyString(), any( Model.class ) ) ) + .thenReturn( true ); + mojo.update( null ); + } + assertThat( changeRecorder.getChanges(), + hasItem( new VersionChange( "default-group", "artifactA", + "1.0.0-SNAPSHOT", "1.0.0" ) ) ); + } + + @Test + public void testUpgrade() + throws MojoExecutionException, XMLStreamException, MojoFailureException + { + mojo.getProject().setDependencies( singletonList( DependencyBuilder.newBuilder() + .withGroupId( "default-group" ) + .withArtifactId( "artifactA" ) + .withVersion( "1.1.0-SNAPSHOT" ) + .build() ) ); + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setDependencyVersion( any(), anyString(), anyString(), anyString(), + anyString(), any( Model.class ) ) ) + .thenReturn( true ); + mojo.update( null ); + } + assertThat( changeRecorder.getChanges(), + hasItem( new VersionChange( "default-group", "artifactA", + "1.1.0-SNAPSHOT", "2.0.0" ) ) ); + } + + @Test + public void testDowngrade() + throws MojoExecutionException, XMLStreamException, MojoFailureException + { + mojo.getProject().setDependencies( singletonList( DependencyBuilder.newBuilder() + .withGroupId( "default-group" ) + .withArtifactId( "artifactA" ) + .withVersion( "2.1.0-SNAPSHOT" ) + .build() ) ); + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setDependencyVersion( any(), anyString(), anyString(), anyString(), + anyString(), any( Model.class ) ) ) + .thenReturn( true ); + mojo.update( null ); + } + assertThat( changeRecorder.getChanges(), + hasItem( new VersionChange( "default-group", "artifactA", + "2.1.0-SNAPSHOT", "2.0.0" ) ) ); + } + + @Test + public void testFailIfNotReplaced() + throws MojoExecutionException, XMLStreamException, MojoFailureException + { + mojo.artifactMetadataSource = mockArtifactMetadataSource( singletonMap( "test-artifact", + new String[] {} ) ); + mojo.getProject().setDependencies( singletonList( DependencyBuilder.newBuilder() + .withGroupId( "default-group" ) + .withArtifactId( "test-artifact" ) + .withVersion( "1.0.0-SNAPSHOT" ) + .build() ) ); + mojo.failIfNotReplaced = true; + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setDependencyVersion( any(), anyString(), anyString(), anyString(), + anyString(), any( Model.class ) ) ) + .thenReturn( true ); + mojo.update( null ); + fail( "MojoExecutionException is expected" ); + } + catch ( MojoExecutionException e ) + { + assertThat( e.getMessage(), startsWith( "No matching" ) ); + } + } +} diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java index beb93a2b89..5e880c70ed 100644 --- a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java +++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseLatestReleasesMojoTest.java @@ -20,6 +20,7 @@ import org.junit.Test; import org.mockito.MockedStatic; +import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE; import static org.apache.maven.plugin.testing.ArtifactStubFactory.setVariableValueToObject; @@ -59,6 +60,7 @@ public void setUp() throws Exception null, null ) {{ + reactorProjects = emptyList(); MavenProject project = new MavenProject() {{ setModel( new Model() 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 ac0a033d92..98c5a34f1a 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 @@ -24,6 +24,7 @@ import org.junit.Test; import org.mockito.MockedStatic; +import static java.util.Collections.emptyList; import static java.util.Collections.singleton; import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE; import static org.apache.maven.plugin.testing.ArtifactStubFactory.setVariableValueToObject; @@ -71,6 +72,7 @@ public void setUp() throws Exception null, null ) {{ + reactorProjects = emptyList(); MavenProject project = new MavenProject() {{ setModel( new Model() @@ -90,10 +92,10 @@ public void setUp() throws Exception }} ); }}; setProject( project ); - - changeRecorder = new TestChangeRecorder(); - setVariableValueToObject( this, "changeRecorder", changeRecorder ); }}; + changeRecorder = new TestChangeRecorder(); + setVariableValueToObject( mojo, "processDependencyManagement", false ); + setVariableValueToObject( mojo, "changeRecorder", changeRecorder ); } @Test diff --git a/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseReleasesMojoTest.java b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseReleasesMojoTest.java new file mode 100644 index 0000000000..d59da171ab --- /dev/null +++ b/versions-maven-plugin/src/test/java/org/codehaus/mojo/versions/UseReleasesMojoTest.java @@ -0,0 +1,155 @@ +package org.codehaus.mojo.versions; + +import javax.xml.stream.XMLStreamException; + +import org.apache.maven.artifact.DefaultArtifact; +import org.apache.maven.model.Model; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.MojoFailureException; +import org.apache.maven.plugin.testing.AbstractMojoTestCase; +import org.apache.maven.plugin.testing.ArtifactStubFactory; +import org.apache.maven.plugin.testing.stubs.StubArtifactResolver; +import org.apache.maven.project.MavenProject; +import org.codehaus.mojo.versions.api.PomHelper; +import org.codehaus.mojo.versions.change.VersionChange; +import org.codehaus.mojo.versions.utils.DependencyBuilder; +import org.codehaus.mojo.versions.utils.TestChangeRecorder; +import org.junit.Before; +import org.junit.Test; +import org.mockito.MockedStatic; + +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static java.util.Collections.singletonMap; +import static org.apache.maven.artifact.Artifact.SCOPE_COMPILE; +import static org.codehaus.mojo.versions.utils.MockUtils.mockArtifactMetadataSource; +import static org.codehaus.mojo.versions.utils.MockUtils.mockRepositorySystem; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.hasItem; +import static org.hamcrest.Matchers.startsWith; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.mockStatic; + +/* + * 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. + */ + +/** + * Unit tests for {@link UseReleasesMojo} + */ +public class UseReleasesMojoTest extends AbstractMojoTestCase +{ + private TestChangeRecorder changeRecorder; + private UseReleasesMojo mojo; + + @Before + public void setUp() throws IllegalAccessException + { + changeRecorder = new TestChangeRecorder(); + mojo = new UseReleasesMojo( mockRepositorySystem(), + null, mockArtifactMetadataSource(), + null, new StubArtifactResolver( new ArtifactStubFactory(), + false, false ) ); + setVariableValueToObject( mojo, "reactorProjects", emptyList() ); + setVariableValueToObject( mojo, "changeRecorder", changeRecorder ); + mojo.project = new MavenProject() + {{ + setModel( new Model() + {{ + setGroupId( "default-group" ); + setArtifactId( "default-artifact" ); + setVersion( "1.0.0" ); + }} ); + }}; + } + + @Test + public void testProcessParent() + throws MojoExecutionException, XMLStreamException, MojoFailureException, IllegalAccessException + { + setVariableValueToObject( mojo, "processParent", true ); + mojo.getProject().setParent( new MavenProject( new Model() + {{ + setGroupId( "default-group" ); + setArtifactId( "artifactA" ); + setVersion( "1.0.0-SNAPSHOT" ); + }} ) ); + mojo.getProject().setParentArtifact( new DefaultArtifact( "default-group", "artifactA", + "1.0.0-SNAPSHOT", SCOPE_COMPILE, "pom", "default", null ) ); + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setProjectParentVersion( any(), anyString() ) ) + .thenReturn( true ); + mojo.update( null ); + } + assertThat( changeRecorder.getChanges(), + hasItem( new VersionChange( "default-group", "artifactA", + "1.0.0-SNAPSHOT", "1.0.0" ) ) ); + } + + @Test + public void testReplaceSnapshotWithRelease() + throws MojoExecutionException, XMLStreamException, MojoFailureException + { + mojo.getProject().setDependencies( singletonList( DependencyBuilder.newBuilder() + .withGroupId( "default-group" ) + .withArtifactId( "artifactA" ) + .withVersion( "1.0.0-SNAPSHOT" ) + .build() ) ); + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setDependencyVersion( any(), anyString(), anyString(), anyString(), + anyString(), any( Model.class ) ) ) + .thenReturn( true ); + mojo.update( null ); + } + assertThat( changeRecorder.getChanges(), + hasItem( new VersionChange( "default-group", "artifactA", + "1.0.0-SNAPSHOT", "1.0.0" ) ) ); + } + + @Test + public void testFailIfNotReplaced() + throws MojoExecutionException, XMLStreamException, MojoFailureException + { + mojo.artifactMetadataSource = mockArtifactMetadataSource( singletonMap( "test-artifact", + new String[] {} ) ); + mojo.getProject().setDependencies( singletonList( DependencyBuilder.newBuilder() + .withGroupId( "default-group" ) + .withArtifactId( "test-artifact" ) + .withVersion( "1.0.0-SNAPSHOT" ) + .build() ) ); + mojo.failIfNotReplaced = true; + + try ( MockedStatic pomHelper = mockStatic( PomHelper.class ) ) + { + pomHelper.when( () -> PomHelper.setDependencyVersion( any(), anyString(), anyString(), anyString(), + anyString(), any( Model.class ) ) ) + .thenReturn( true ); + mojo.update( null ); + fail( "MojoExecutionException is expected" ); + } + catch ( MojoExecutionException e ) + { + assertThat( e.getMessage(), startsWith( "No matching" ) ); + } + } +}