From 58f8b7000d6086baabfece89001878b5c3b3eeca Mon Sep 17 00:00:00 2001 From: Mark Raynsford Date: Sun, 7 Jul 2019 16:04:38 +0100 Subject: [PATCH] Provide a "change recorder" for updates This provides a ChangeRecorder interface that logs changes to a machine-readable XML file whenever a pom.xml file is updated. Affects: https://github.com/mojohaus/versions-maven-plugin/issues/356 --- .../invoker.properties | 1 + .../it-changerecord-update-parent-001/pom.xml | 40 ++++++ .../verify.bsh | 22 ++++ .../invoker.properties | 1 + .../pom.xml | 59 +++++++++ .../verify.bsh | 21 ++++ .../invoker.properties | 1 + .../pom.xml | 21 ++++ .../verify.bsh | 21 ++++ .../invoker.properties | 1 + .../pom.xml | 21 ++++ .../verify.bsh | 21 ++++ .../invoker.properties | 1 + .../pom.xml | 21 ++++ .../verify.bsh | 21 ++++ .../invoker.properties | 1 + .../pom.xml | 21 ++++ .../verify.bsh | 21 ++++ .../versions/AbstractVersionsUpdaterMojo.java | 101 +++++++++++++-- .../mojo/versions/UnlockSnapshotsMojo.java | 27 ++-- .../mojo/versions/UpdateParentMojo.java | 24 ++-- .../mojo/versions/UpdatePropertiesMojo.java | 62 ++++++---- .../mojo/versions/UpdatePropertyMojo.java | 13 +- .../mojo/versions/UseDepVersionMojo.java | 40 +++--- .../mojo/versions/UseLatestReleasesMojo.java | 3 + .../mojo/versions/UseLatestSnapshotsMojo.java | 11 +- .../mojo/versions/UseLatestVersionsMojo.java | 8 +- .../mojo/versions/UseNextReleasesMojo.java | 3 + .../mojo/versions/UseNextSnapshotsMojo.java | 3 + .../mojo/versions/UseNextVersionsMojo.java | 3 + .../mojo/versions/UseReleasesMojo.java | 20 ++- .../versions/recording/ChangeRecorder.java | 51 ++++++++ .../recording/ChangeRecorderNull.java | 63 ++++++++++ .../versions/recording/ChangeRecorderXML.java | 116 ++++++++++++++++++ .../mojo/versions/recording/schema-1.0.xsd | 37 ++++++ src/site/apt/examples/recording-changes.apt | 49 ++++++++ src/site/apt/index.apt | 3 + .../recording/ChangeRecorderXMLTest.java | 98 +++++++++++++++ .../mojo/versions/recording/expectedFile.xml | 6 + 39 files changed, 978 insertions(+), 79 deletions(-) create mode 100644 src/it/it-changerecord-update-parent-001/invoker.properties create mode 100644 src/it/it-changerecord-update-parent-001/pom.xml create mode 100644 src/it/it-changerecord-update-parent-001/verify.bsh create mode 100644 src/it/it-changerecord-update-properties-001/invoker.properties create mode 100644 src/it/it-changerecord-update-properties-001/pom.xml create mode 100644 src/it/it-changerecord-update-properties-001/verify.bsh create mode 100644 src/it/it-changerecord-use-latest-releases-001/invoker.properties create mode 100644 src/it/it-changerecord-use-latest-releases-001/pom.xml create mode 100644 src/it/it-changerecord-use-latest-releases-001/verify.bsh create mode 100644 src/it/it-changerecord-use-latest-snapshots-001/invoker.properties create mode 100644 src/it/it-changerecord-use-latest-snapshots-001/pom.xml create mode 100644 src/it/it-changerecord-use-latest-snapshots-001/verify.bsh create mode 100644 src/it/it-changerecord-use-latest-versions-001/invoker.properties create mode 100644 src/it/it-changerecord-use-latest-versions-001/pom.xml create mode 100644 src/it/it-changerecord-use-latest-versions-001/verify.bsh create mode 100644 src/it/it-changerecord-use-next-versions-001/invoker.properties create mode 100644 src/it/it-changerecord-use-next-versions-001/pom.xml create mode 100644 src/it/it-changerecord-use-next-versions-001/verify.bsh create mode 100644 src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorder.java create mode 100644 src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java create mode 100644 src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java create mode 100644 src/main/resources/org/codehaus/mojo/versions/recording/schema-1.0.xsd create mode 100644 src/site/apt/examples/recording-changes.apt create mode 100644 src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java create mode 100644 src/test/resources/org/codehaus/mojo/versions/recording/expectedFile.xml diff --git a/src/it/it-changerecord-update-parent-001/invoker.properties b/src/it/it-changerecord-update-parent-001/invoker.properties new file mode 100644 index 000000000..5ab6491f4 --- /dev/null +++ b/src/it/it-changerecord-update-parent-001/invoker.properties @@ -0,0 +1 @@ +invoker.goals=-DchangeRecorderFormat=xml ${project.groupId}:${project.artifactId}:${project.version}:update-parent diff --git a/src/it/it-changerecord-update-parent-001/pom.xml b/src/it/it-changerecord-update-parent-001/pom.xml new file mode 100644 index 000000000..10de782fb --- /dev/null +++ b/src/it/it-changerecord-update-parent-001/pom.xml @@ -0,0 +1,40 @@ + + 4.0.0 + + + localhost + dummy-parent + 1.0 + + + localhost + it-201 + 1.0 + pom + update-parent basic test + + + + + + maven-clean-plugin + 2.2 + + + maven-deploy-plugin + 2.3 + + + maven-install-plugin + 2.2 + + + maven-site-plugin + 2.0 + + + + + + diff --git a/src/it/it-changerecord-update-parent-001/verify.bsh b/src/it/it-changerecord-update-parent-001/verify.bsh new file mode 100644 index 000000000..29363fa9d --- /dev/null +++ b/src/it/it-changerecord-update-parent-001/verify.bsh @@ -0,0 +1,22 @@ +import java.io.*; +import java.util.regex.*; +import org.codehaus.plexus.util.FileUtils; + +try +{ + File file = new File( basedir, "target/versions-changes.xml" ); + String buf = FileUtils.fileRead( file, "UTF-8" ); + + if ( buf.indexOf( "" ) < 0 ) + { + System.err.println( "Version change recorded" ); + return false; + } +} +catch( Throwable t ) +{ + t.printStackTrace(); + return false; +} + +return true; diff --git a/src/it/it-changerecord-update-properties-001/invoker.properties b/src/it/it-changerecord-update-properties-001/invoker.properties new file mode 100644 index 000000000..0b22a2916 --- /dev/null +++ b/src/it/it-changerecord-update-properties-001/invoker.properties @@ -0,0 +1 @@ +invoker.goals=-DchangeRecorderFormat=xml ${project.groupId}:${project.artifactId}:${project.version}:update-properties diff --git a/src/it/it-changerecord-update-properties-001/pom.xml b/src/it/it-changerecord-update-properties-001/pom.xml new file mode 100644 index 000000000..21aa2d7b8 --- /dev/null +++ b/src/it/it-changerecord-update-properties-001/pom.xml @@ -0,0 +1,59 @@ + + 4.0.0 + + localhost + it-001 + 1.0 + pom + update-properties with one property only + + + 1.0 + + + + + + + maven-clean-plugin + 2.2 + + + maven-deploy-plugin + 2.3 + + + maven-install-plugin + 2.2 + + + maven-site-plugin + 2.0 + + + + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + api + + + localhost + dummy-api + + + + + + + + + + diff --git a/src/it/it-changerecord-update-properties-001/verify.bsh b/src/it/it-changerecord-update-properties-001/verify.bsh new file mode 100644 index 000000000..f1c83a4db --- /dev/null +++ b/src/it/it-changerecord-update-properties-001/verify.bsh @@ -0,0 +1,21 @@ +import java.io.*; +import org.codehaus.plexus.util.FileUtils; + +try +{ + File file = new File( basedir, "target/versions-changes.xml" ); + String buf = FileUtils.fileRead( file, "UTF-8" ); + + if ( buf.indexOf( "" ) < 0 ) + { + System.err.println( "Version change recorded" ); + return false; + } +} +catch( Throwable t ) +{ + t.printStackTrace(); + return false; +} + +return true; diff --git a/src/it/it-changerecord-use-latest-releases-001/invoker.properties b/src/it/it-changerecord-use-latest-releases-001/invoker.properties new file mode 100644 index 000000000..623fbd989 --- /dev/null +++ b/src/it/it-changerecord-use-latest-releases-001/invoker.properties @@ -0,0 +1 @@ +invoker.goals=-DchangeRecorderFormat=xml ${project.groupId}:${project.artifactId}:${project.version}:use-latest-releases diff --git a/src/it/it-changerecord-use-latest-releases-001/pom.xml b/src/it/it-changerecord-use-latest-releases-001/pom.xml new file mode 100644 index 000000000..c6010a488 --- /dev/null +++ b/src/it/it-changerecord-use-latest-releases-001/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + localhost + it-use-latest-releases-001 + 1.0 + pom + Update a dependency to the latest release version + + + + + localhost + dummy-api + 1.1.1-2 + + + + + diff --git a/src/it/it-changerecord-use-latest-releases-001/verify.bsh b/src/it/it-changerecord-use-latest-releases-001/verify.bsh new file mode 100644 index 000000000..8a1cf6004 --- /dev/null +++ b/src/it/it-changerecord-use-latest-releases-001/verify.bsh @@ -0,0 +1,21 @@ +import java.io.*; +import org.codehaus.plexus.util.FileUtils; + +try +{ + File file = new File( basedir, "target/versions-changes.xml" ); + String buf = FileUtils.fileRead( file, "UTF-8" ); + + if ( buf.indexOf( "" ) < 0 ) + { + System.err.println( "Version change recorded" ); + return false; + } +} +catch( Throwable t ) +{ + t.printStackTrace(); + return false; +} + +return true; diff --git a/src/it/it-changerecord-use-latest-snapshots-001/invoker.properties b/src/it/it-changerecord-use-latest-snapshots-001/invoker.properties new file mode 100644 index 000000000..629cea24d --- /dev/null +++ b/src/it/it-changerecord-use-latest-snapshots-001/invoker.properties @@ -0,0 +1 @@ +invoker.goals=-DchangeRecorderFormat=xml ${project.groupId}:${project.artifactId}:${project.version}:use-latest-snapshots -DallowMinorUpdates=true diff --git a/src/it/it-changerecord-use-latest-snapshots-001/pom.xml b/src/it/it-changerecord-use-latest-snapshots-001/pom.xml new file mode 100644 index 000000000..5eab42237 --- /dev/null +++ b/src/it/it-changerecord-use-latest-snapshots-001/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + localhost + it-use-latest-snapshots-001 + 1.0 + pom + Update a release dependency to the latest snapshot version + + + + + localhost + dummy-api + 1.0 + + + + + diff --git a/src/it/it-changerecord-use-latest-snapshots-001/verify.bsh b/src/it/it-changerecord-use-latest-snapshots-001/verify.bsh new file mode 100644 index 000000000..c8050feff --- /dev/null +++ b/src/it/it-changerecord-use-latest-snapshots-001/verify.bsh @@ -0,0 +1,21 @@ +import java.io.*; +import org.codehaus.plexus.util.FileUtils; + +try +{ + File file = new File( basedir, "target/versions-changes.xml" ); + String buf = FileUtils.fileRead( file, "UTF-8" ); + + if ( buf.indexOf( "" ) < 0 ) + { + System.err.println( "Version change recorded" ); + return false; + } +} +catch( Throwable t ) +{ + t.printStackTrace(); + return false; +} + +return true; diff --git a/src/it/it-changerecord-use-latest-versions-001/invoker.properties b/src/it/it-changerecord-use-latest-versions-001/invoker.properties new file mode 100644 index 000000000..2ca3daeb2 --- /dev/null +++ b/src/it/it-changerecord-use-latest-versions-001/invoker.properties @@ -0,0 +1 @@ +invoker.goals=-DchangeRecorderFormat=xml ${project.groupId}:${project.artifactId}:${project.version}:use-latest-versions diff --git a/src/it/it-changerecord-use-latest-versions-001/pom.xml b/src/it/it-changerecord-use-latest-versions-001/pom.xml new file mode 100644 index 000000000..18b67695c --- /dev/null +++ b/src/it/it-changerecord-use-latest-versions-001/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + localhost + it-use-latest-versions-001 + 1.0 + pom + Update a dependency to the next release version + + + + + localhost + dummy-api + 1.1.1-2 + + + + + diff --git a/src/it/it-changerecord-use-latest-versions-001/verify.bsh b/src/it/it-changerecord-use-latest-versions-001/verify.bsh new file mode 100644 index 000000000..9ce59b8bb --- /dev/null +++ b/src/it/it-changerecord-use-latest-versions-001/verify.bsh @@ -0,0 +1,21 @@ +import java.io.*; +import org.codehaus.plexus.util.FileUtils; + +try +{ + File file = new File( basedir, "target/versions-changes.xml" ); + String buf = FileUtils.fileRead( file, "UTF-8" ); + + if ( buf.indexOf( "" ) < 0 ) + { + System.err.println( "Version change recorded" ); + return false; + } +} +catch( Throwable t ) +{ + t.printStackTrace(); + return false; +} + +return true; diff --git a/src/it/it-changerecord-use-next-versions-001/invoker.properties b/src/it/it-changerecord-use-next-versions-001/invoker.properties new file mode 100644 index 000000000..eb678c4be --- /dev/null +++ b/src/it/it-changerecord-use-next-versions-001/invoker.properties @@ -0,0 +1 @@ +invoker.goals=-DchangeRecorderFormat=xml ${project.groupId}:${project.artifactId}:${project.version}:use-next-versions diff --git a/src/it/it-changerecord-use-next-versions-001/pom.xml b/src/it/it-changerecord-use-next-versions-001/pom.xml new file mode 100644 index 000000000..675d67e71 --- /dev/null +++ b/src/it/it-changerecord-use-next-versions-001/pom.xml @@ -0,0 +1,21 @@ + + 4.0.0 + + localhost + it-use-next-versions-001 + 1.0 + pom + Update a dependency to the next versions + + + + + localhost + dummy-api + 1.1.1-2 + + + + + diff --git a/src/it/it-changerecord-use-next-versions-001/verify.bsh b/src/it/it-changerecord-use-next-versions-001/verify.bsh new file mode 100644 index 000000000..659cbeff0 --- /dev/null +++ b/src/it/it-changerecord-use-next-versions-001/verify.bsh @@ -0,0 +1,21 @@ +import java.io.*; +import org.codehaus.plexus.util.FileUtils; + +try +{ + File file = new File( basedir, "target/versions-changes.xml" ); + String buf = FileUtils.fileRead( file, "UTF-8" ); + + if ( buf.indexOf( "" ) < 0 ) + { + System.err.println( "Version change recorded" ); + return false; + } +} +catch( Throwable t ) +{ + t.printStackTrace(); + return false; +} + +return true; diff --git a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java index 75027618a..49489a848 100644 --- a/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/AbstractVersionsUpdaterMojo.java @@ -44,6 +44,9 @@ import org.codehaus.mojo.versions.api.PomHelper; import org.codehaus.mojo.versions.api.PropertyVersions; import org.codehaus.mojo.versions.api.VersionsHelper; +import org.codehaus.mojo.versions.recording.ChangeRecorder; +import org.codehaus.mojo.versions.recording.ChangeRecorderNull; +import org.codehaus.mojo.versions.recording.ChangeRecorderXML; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; import org.codehaus.plexus.util.FileUtils; import org.codehaus.plexus.util.IOUtil; @@ -53,6 +56,7 @@ import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLStreamException; import java.io.File; +import java.io.FileOutputStream; import java.io.IOException; import java.io.Writer; import java.util.List; @@ -191,6 +195,27 @@ public abstract class AbstractVersionsUpdaterMojo @Component protected ArtifactResolver artifactResolver; + /** + * The format used to record changes. If "none" is specified, no changes are recorded. + * + * @since 2.8 + */ + @Parameter( property = "changeRecorderFormat", + defaultValue = "none" ) + private String changeRecorderFormat = "none"; + /** + * The output file used to record changes. + * + * @since 2.8 + */ + @Parameter( property = "changeRecorderOutputFile", + defaultValue = "${project.build.directory}/versions-changes.xml" ) + private File changeRecorderOutputFile; + /** + * The change recorder implementation. + */ + + private ChangeRecorder changeRecorder; // --------------------- GETTER / SETTER METHODS --------------------- @@ -335,6 +360,8 @@ protected void process( File outFile ) } writeFile( outFile, input ); } + + this.saveChangeRecorderResults(); } catch ( IOException | XMLStreamException e ) { @@ -504,16 +531,9 @@ else if ( allowIncrementalUpdates ) return segment; } - protected void updatePropertyToNewestVersion( ModifiedPomXMLEventReader pom, Property property, - PropertyVersions version, String currentVersion ) - throws MojoExecutionException, XMLStreamException - { - updatePropertyToNewestVersion( pom, property, version, currentVersion, false, -1 ); - } - - protected void updatePropertyToNewestVersion( ModifiedPomXMLEventReader pom, Property property, - PropertyVersions version, String currentVersion, - boolean allowDowngrade, int segment ) + protected ArtifactVersion updatePropertyToNewestVersion( ModifiedPomXMLEventReader pom, Property property, + PropertyVersions version, String currentVersion, + boolean allowDowngrade, int segment ) throws MojoExecutionException, XMLStreamException { ArtifactVersion winner = @@ -528,5 +548,66 @@ else if ( PomHelper.setPropertyVersion( pom, version.getProfileId(), property.ge { getLog().info( "Updated ${" + property.getName() + "} from " + currentVersion + " to " + winner ); } + + return winner; + } + + /** + * 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 + { + if ( this.changeRecorder == null ) + { + if ( "none".equals( this.changeRecorderFormat ) ) + { + this.changeRecorder = ChangeRecorderNull.create(); + } + else if ( "xml".equals( this.changeRecorderFormat ) ) + { + this.changeRecorder = ChangeRecorderXML.create(); + } + else + { + throw new MojoExecutionException( "Only 'xml' or 'none' formats are supported for change recordings" ); + } + } + + return this.changeRecorder; + } + + /** + * Save all of the changes recorded by the change recorder. + * + * @throws IOException On I/O errors + */ + + protected void saveChangeRecorderResults() throws IOException + { + /* + * Nobody did anything that required a change recorder. + */ + + if ( this.changeRecorder == null ) + { + return; + } + + if ( "none".equals( this.changeRecorderFormat ) ) + { + return; + } + + this.getLog().debug( "writing change record to " + this.changeRecorderOutputFile ); + + this.changeRecorderOutputFile.getParentFile().mkdirs(); + try ( FileOutputStream outputStream = new FileOutputStream( this.changeRecorderOutputFile ) ) + { + this.changeRecorder.serialize( outputStream ); + } } } diff --git a/src/main/java/org/codehaus/mojo/versions/UnlockSnapshotsMojo.java b/src/main/java/org/codehaus/mojo/versions/UnlockSnapshotsMojo.java index 317eadd75..e6c099f8e 100644 --- a/src/main/java/org/codehaus/mojo/versions/UnlockSnapshotsMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/UnlockSnapshotsMojo.java @@ -42,9 +42,11 @@ * @author Paul Gier * @since 1.0-alpha-3 */ -@Mojo( name = "unlock-snapshots", requiresProject = true, requiresDirectInvocation = true, threadSafe = true ) -public class UnlockSnapshotsMojo - extends AbstractVersionsDependencyUpdaterMojo +@Mojo( name = "unlock-snapshots", + requiresProject = true, + requiresDirectInvocation = true, + threadSafe = true ) +public class UnlockSnapshotsMojo extends AbstractVersionsDependencyUpdaterMojo { // ------------------------------ FIELDS ------------------------------ @@ -59,12 +61,11 @@ public class UnlockSnapshotsMojo /** * @param pom the pom to update. * @throws MojoExecutionException when things go wrong - * @throws MojoFailureException when things go wrong in a very bad way - * @throws XMLStreamException when things go wrong with XML streaming + * @throws MojoFailureException when things go wrong in a very bad way + * @throws XMLStreamException when things go wrong with XML streaming * @see AbstractVersionsUpdaterMojo#update(ModifiedPomXMLEventReader) */ - protected void update( ModifiedPomXMLEventReader pom ) - throws MojoExecutionException, MojoFailureException, XMLStreamException + protected void update( ModifiedPomXMLEventReader pom ) throws MojoExecutionException, MojoFailureException, XMLStreamException { if ( getProject().getDependencyManagement() != null && isProcessingDependencyManagement() ) @@ -81,8 +82,7 @@ protected void update( ModifiedPomXMLEventReader pom ) } } - private void unlockSnapshots( ModifiedPomXMLEventReader pom, List dependencies ) - throws XMLStreamException, MojoExecutionException + private void unlockSnapshots( ModifiedPomXMLEventReader pom, List dependencies ) throws XMLStreamException, MojoExecutionException { for ( Dependency dep : dependencies ) { @@ -109,16 +109,17 @@ private void unlockSnapshots( ModifiedPomXMLEventReader pom, List de { String unlockedVersion = versionMatcher.replaceFirst( "-SNAPSHOT" ); if ( PomHelper.setDependencyVersion( pom, dep.getGroupId(), dep.getArtifactId(), dep.getVersion(), - unlockedVersion, getProject().getModel() ) ) + unlockedVersion, getProject().getModel() ) ) { + this.getChangeRecorder().recordUpdate( "unlockSnapshot", dep.getGroupId(), dep.getArtifactId(), + dep.getVersion(), unlockedVersion ); getLog().info( "Unlocked " + toString( dep ) + " to version " + unlockedVersion ); } } } } - private void unlockParentSnapshot( ModifiedPomXMLEventReader pom, MavenProject parent ) - throws XMLStreamException, MojoExecutionException + private void unlockParentSnapshot( ModifiedPomXMLEventReader pom, MavenProject parent ) throws XMLStreamException, MojoExecutionException { if ( parent == null ) { @@ -143,6 +144,8 @@ private void unlockParentSnapshot( ModifiedPomXMLEventReader pom, MavenProject p { getLog().info( "Unlocked parent " + parentArtifact + " to version " + unlockedParentVersion ); + this.getChangeRecorder().recordUpdate( "unlockParentVersion", parentArtifact.getGroupId(), + parentArtifact.getArtifactId(), parentArtifact.getVersion(), unlockedParentVersion ); } } } diff --git a/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java b/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java index 7d3137950..6b53757f3 100644 --- a/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/UpdateParentMojo.java @@ -39,9 +39,11 @@ * @author Stephen Connolly * @since 1.0-alpha-1 */ -@Mojo( name = "update-parent", requiresProject = true, requiresDirectInvocation = true, threadSafe = true ) -public class UpdateParentMojo - extends AbstractVersionsUpdaterMojo +@Mojo( name = "update-parent", + requiresProject = true, + requiresDirectInvocation = true, + threadSafe = true ) +public class UpdateParentMojo extends AbstractVersionsUpdaterMojo { // ------------------------------ FIELDS ------------------------------ @@ -51,7 +53,8 @@ public class UpdateParentMojo * * @since 1.0-alpha-1 */ - @Parameter( property = "parentVersion", defaultValue = "null" ) + @Parameter( property = "parentVersion", + defaultValue = "null" ) protected String parentVersion = null; /** @@ -67,13 +70,12 @@ public class UpdateParentMojo /** * @param pom the pom to update. * @throws MojoExecutionException when things go wrong - * @throws MojoFailureException when things go wrong in a very bad way - * @throws XMLStreamException when things go wrong with XML streaming + * @throws MojoFailureException when things go wrong in a very bad way + * @throws XMLStreamException when things go wrong with XML streaming * @see AbstractVersionsUpdaterMojo#update(ModifiedPomXMLEventReader) * @since 1.0-alpha-1 */ - protected void update( ModifiedPomXMLEventReader pom ) - throws MojoExecutionException, MojoFailureException, XMLStreamException + protected void update( ModifiedPomXMLEventReader pom ) throws MojoExecutionException, MojoFailureException, XMLStreamException { if ( getProject().getParent() == null ) { @@ -106,8 +108,7 @@ protected void update( ModifiedPomXMLEventReader pom ) } Artifact artifact = artifactFactory.createDependencyArtifact( getProject().getParent().getGroupId(), - getProject().getParent().getArtifactId(), - versionRange, "pom", null, null ); + getProject().getParent().getArtifactId(), versionRange, "pom", null, null ); ArtifactVersion artifactVersion; try @@ -129,6 +130,9 @@ protected void update( ModifiedPomXMLEventReader pom ) if ( PomHelper.setProjectParentVersion( pom, artifactVersion.toString() ) ) { getLog().debug( "Made an update from " + currentVersion + " to " + artifactVersion ); + + this.getChangeRecorder().recordUpdate( "updateParent", artifact.getGroupId(), artifact.getArtifactId(), + currentVersion, artifactVersion.toString() ); } } diff --git a/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojo.java b/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojo.java index f80ae7243..033f6623f 100644 --- a/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/UpdatePropertiesMojo.java @@ -19,6 +19,7 @@ * under the License. */ +import org.apache.maven.artifact.versioning.ArtifactVersion; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugins.annotations.Mojo; @@ -36,9 +37,11 @@ * @author Stephen Connolly * @since 1.0-alpha-1 */ -@Mojo( name = "update-properties", requiresProject = true, requiresDirectInvocation = true, threadSafe = true ) -public class UpdatePropertiesMojo - extends AbstractVersionsDependencyUpdaterMojo +@Mojo( name = "update-properties", + requiresProject = true, + requiresDirectInvocation = true, + threadSafe = true ) +public class UpdatePropertiesMojo extends AbstractVersionsDependencyUpdaterMojo { // ------------------------------ FIELDS ------------------------------ @@ -72,16 +75,18 @@ public class UpdatePropertiesMojo * * @since 1.0-alpha-2 */ - @Parameter( property = "autoLinkItems", defaultValue = "true" ) + @Parameter( property = "autoLinkItems", + defaultValue = "true" ) private boolean autoLinkItems; /** * If a property points to a version like 1.2.3-SNAPSHOT and your repo contains a version like * 1.1.0 without settings this to true the property will not being changed. - * + * * @since 2.4 */ - @Parameter( property = "allowDowngrade", defaultValue = "false" ) + @Parameter( property = "allowDowngrade", + defaultValue = "false" ) private boolean allowDowngrade; /** @@ -89,7 +94,8 @@ public class UpdatePropertiesMojo * * @since 2.4 */ - @Parameter( property = "allowMajorUpdates", defaultValue = "true" ) + @Parameter( property = "allowMajorUpdates", + defaultValue = "true" ) protected boolean allowMajorUpdates; /** @@ -97,7 +103,8 @@ public class UpdatePropertiesMojo * * @since 2.4 */ - @Parameter( property = "allowMinorUpdates", defaultValue = "true" ) + @Parameter( property = "allowMinorUpdates", + defaultValue = "true" ) protected boolean allowMinorUpdates; /** @@ -105,7 +112,8 @@ public class UpdatePropertiesMojo * * @since 2.4 */ - @Parameter( property = "allowIncrementalUpdates", defaultValue = "true" ) + @Parameter( property = "allowIncrementalUpdates", + defaultValue = "true" ) protected boolean allowIncrementalUpdates; // -------------------------- STATIC METHODS -------------------------- @@ -115,17 +123,15 @@ public class UpdatePropertiesMojo /** * @param pom the pom to update. * @throws MojoExecutionException when things go wrong - * @throws MojoFailureException when things go wrong in a very bad way - * @throws XMLStreamException when things go wrong with XML streaming + * @throws MojoFailureException when things go wrong in a very bad way + * @throws XMLStreamException when things go wrong with XML streaming * @see AbstractVersionsUpdaterMojo#update(ModifiedPomXMLEventReader) * @since 1.0-alpha-1 */ - protected void update( ModifiedPomXMLEventReader pom ) - throws MojoExecutionException, MojoFailureException, XMLStreamException + protected void update( ModifiedPomXMLEventReader pom ) throws MojoExecutionException, MojoFailureException, XMLStreamException { - Map propertyVersions = - this.getHelper().getVersionPropertiesMap( getProject(), properties, includeProperties, excludeProperties, - autoLinkItems ); + Map propertyVersions = this.getHelper().getVersionPropertiesMap( getProject(), + properties, includeProperties, excludeProperties, autoLinkItems ); for ( Map.Entry entry : propertyVersions.entrySet() ) { Property property = entry.getKey(); @@ -141,9 +147,8 @@ protected void update( ModifiedPomXMLEventReader pom ) { if ( !( isIncluded( association.getArtifact() ) ) ) { - getLog().info( "Not updating the property ${" + property.getName() - + "} because it is used by artifact " + association.getArtifact().toString() - + " and that artifact is not included in the list of " + " allowed artifacts to be updated." ); + getLog().info( + "Not updating the property ${" + property.getName() + "} because it is used by artifact " + association.getArtifact().toString() + " and that artifact is not included in the list of " + " allowed artifacts to be updated." ); canUpdateProperty = false; break; } @@ -151,9 +156,22 @@ protected void update( ModifiedPomXMLEventReader pom ) if ( canUpdateProperty ) { - int segment = - determineUnchangedSegment( allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates ); - updatePropertyToNewestVersion( pom, property, version, currentVersion, allowDowngrade, segment ); + int segment = determineUnchangedSegment( allowMajorUpdates, allowMinorUpdates, + allowIncrementalUpdates ); + ArtifactVersion targetVersion = updatePropertyToNewestVersion( pom, property, version, currentVersion, + allowDowngrade, segment ); + + if (targetVersion != null) + { + for ( final ArtifactAssociation association : version.getAssociations() ) + { + if ( ( isIncluded( association.getArtifact() ) ) ) + { + this.getChangeRecorder().recordUpdate( "updateProperty", association.getGroupId(), + association.getArtifactId(), currentVersion, targetVersion.toString() ); + } + } + } } } diff --git a/src/main/java/org/codehaus/mojo/versions/UpdatePropertyMojo.java b/src/main/java/org/codehaus/mojo/versions/UpdatePropertyMojo.java index 94f8fb4a3..1e3127aa2 100644 --- a/src/main/java/org/codehaus/mojo/versions/UpdatePropertyMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/UpdatePropertyMojo.java @@ -19,10 +19,12 @@ * under the License. */ +import org.apache.maven.artifact.versioning.ArtifactVersion; 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.codehaus.mojo.versions.api.ArtifactAssociation; import org.codehaus.mojo.versions.api.PropertyVersions; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; @@ -143,8 +145,17 @@ protected void update( ModifiedPomXMLEventReader pom ) } int segment = determineUnchangedSegment( allowMajorUpdates, allowMinorUpdates, allowIncrementalUpdates ); - updatePropertyToNewestVersion( pom, property, version, currentVersion, allowDowngrade, segment ); + ArtifactVersion targetVersion = updatePropertyToNewestVersion( pom, property, version, currentVersion, + allowDowngrade, segment ); + if (targetVersion != null) + { + for ( final ArtifactAssociation association : version.getAssociations() ) + { + this.getChangeRecorder().recordUpdate( "updateProperty", association.getGroupId(), + association.getArtifactId(), currentVersion, targetVersion.toString() ); + } + } } } diff --git a/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java b/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java index 317eba5e9..494b649be 100644 --- a/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java +++ b/src/main/java/org/codehaus/mojo/versions/UseDepVersionMojo.java @@ -34,42 +34,50 @@ import org.codehaus.mojo.versions.api.PomHelper; import org.codehaus.mojo.versions.rewriting.ModifiedPomXMLEventReader; +import javax.xml.stream.XMLStreamException; +import java.util.Collection; + /** * @author Dan Arcari * @since 2.3 */ -@Mojo( name = "use-dep-version", requiresProject = true, requiresDirectInvocation = true, threadSafe = true ) -public class UseDepVersionMojo - extends AbstractVersionsDependencyUpdaterMojo +@Mojo( name = "use-dep-version", + requiresProject = true, + requiresDirectInvocation = true, + threadSafe = true ) +public class UseDepVersionMojo extends AbstractVersionsDependencyUpdaterMojo { /** * The exact version to be applied for the included dependencies */ - @Parameter( property = "depVersion", required = true ) + @Parameter( property = "depVersion", + required = true ) protected String depVersion; /** * If set to true, will use whatever version is supplied without attempting to validate that such a version is * obtainable from the repository chain. */ - @Parameter( property = "forceVersion", defaultValue = "false" ) + @Parameter( property = "forceVersion", + defaultValue = "false" ) protected boolean forceVersion; @SuppressWarnings( "unchecked" ) @Override - protected void update( ModifiedPomXMLEventReader pom ) - throws MojoExecutionException, MojoFailureException, XMLStreamException, ArtifactMetadataRetrievalException + protected void update( ModifiedPomXMLEventReader pom ) throws MojoExecutionException, MojoFailureException, XMLStreamException, ArtifactMetadataRetrievalException { if ( depVersion == null || depVersion.equals( "" ) ) { - throw new IllegalArgumentException( "depVersion must be supplied with use-specific-version, and cannot be blank." ); + throw new IllegalArgumentException( + "depVersion must be supplied with use-specific-version, and cannot be blank." ); } if ( !forceVersion && !hasIncludes() ) { - throw new IllegalArgumentException( "The use-specific-version goal is intended to be used with a single artifact. Please specify a value for the 'includes' parameter, or use -DforceVersion=true to override this check." ); + throw new IllegalArgumentException( + "The use-specific-version goal is intended to be used with a single artifact. Please specify a value for the 'includes' parameter, or use -DforceVersion=true to override this check." ); } try @@ -90,8 +98,7 @@ protected void update( ModifiedPomXMLEventReader pom ) } } - private void useDepVersion( ModifiedPomXMLEventReader pom, Collection dependencies ) - throws MojoExecutionException, XMLStreamException, ArtifactMetadataRetrievalException + private void useDepVersion( ModifiedPomXMLEventReader pom, Collection dependencies ) throws MojoExecutionException, XMLStreamException, ArtifactMetadataRetrievalException { for ( Dependency dep : dependencies ) { @@ -117,18 +124,21 @@ private void useDepVersion( ModifiedPomXMLEventReader pom, Collection } private void rangeMatching( ModifiedPomXMLEventReader pom, Dependency dep, String version, String releaseVersion, - ArtifactVersions versions ) - throws XMLStreamException + ArtifactVersions versions ) throws XMLStreamException, MojoExecutionException { ArtifactVersion finalVersion = null; for ( ArtifactVersion proposedVersion : versions.getVersions( false ) ) @@ -256,6 +259,9 @@ private void rangeMatching( ModifiedPomXMLEventReader pom, Dependency dep, Strin finalVersion.toString(), getProject().getModel() ) ) { getLog().info( "Updated " + toString( dep ) + " to version " + finalVersion ); + + this.getChangeRecorder().recordUpdate( "useReleases", dep.getGroupId(), + dep.getArtifactId(), version, finalVersion.toString() ); } } else @@ -270,8 +276,7 @@ private void rangeMatching( ModifiedPomXMLEventReader pom, Dependency dep, Strin } private void noRangeMatching( ModifiedPomXMLEventReader pom, Dependency dep, String version, String releaseVersion, - ArtifactVersions versions ) - throws XMLStreamException + ArtifactVersions versions ) throws XMLStreamException, MojoExecutionException { if ( versions.containsVersion( releaseVersion ) ) { @@ -279,6 +284,9 @@ private void noRangeMatching( ModifiedPomXMLEventReader pom, Dependency dep, Str getProject().getModel() ) ) { getLog().info( "Updated " + toString( dep ) + " to version " + releaseVersion ); + + this.getChangeRecorder().recordUpdate( "useReleases", dep.getGroupId(), + dep.getArtifactId(), version, releaseVersion ); } } else if ( failIfNotReplaced ) diff --git a/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorder.java b/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorder.java new file mode 100644 index 000000000..32483c490 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorder.java @@ -0,0 +1,51 @@ +package org.codehaus.mojo.versions.recording; + +/* + * 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 java.io.IOException; +import java.io.OutputStream; + +/** + * A recorder of version updates. + */ + +public interface ChangeRecorder +{ + /** + * Record that a dependency was updated. + * + * @param kind The kind of version change + * @param groupId The dependency group ID + * @param artifactId The dependency artifact ID + * @param oldVersion The old version of the dependency + * @param newVersion The new version of the dependency + */ + + void recordUpdate( String kind, String groupId, String artifactId, String oldVersion, String newVersion ); + + /** + * Serialize the current set of changes to the given output stream. + * + * @param outputStream The output stream + * @throws IOException On serialization and/or I/O errors + */ + + void serialize( OutputStream outputStream ) throws IOException; +} diff --git a/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java b/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java new file mode 100644 index 000000000..f023e0df5 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderNull.java @@ -0,0 +1,63 @@ +package org.codehaus.mojo.versions.recording; + +/* + * 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 java.io.IOException; +import java.io.OutputStream; +import java.util.Objects; + +/** + * A recorder that ignores updates. + */ + +public class ChangeRecorderNull implements ChangeRecorder +{ + /** + * Create a new change recorder that serializes to XML. + * + * @return A new change recorder + */ + + public static ChangeRecorder create() + { + return new ChangeRecorderNull(); + } + + private 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 ) throws IOException + { + + } +} diff --git a/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java b/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java new file mode 100644 index 000000000..3f88ccc38 --- /dev/null +++ b/src/main/java/org/codehaus/mojo/versions/recording/ChangeRecorderXML.java @@ -0,0 +1,116 @@ +package org.codehaus.mojo.versions.recording; + +/* + * 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 org.w3c.dom.DOMException; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Objects; + +/** + * A recorder of version updates. + */ + +public class ChangeRecorderXML implements ChangeRecorder +{ + /** + * The XML namespace used for serialized changes. + */ + + public static final String CHANGES_NAMESPACE = "http://www.mojohaus.org/versions-maven-plugin/schema/updates/1.0"; + + private final Document document; + private final Element root; + + /** + * Create a new change recorder that serializes to XML. + * + * @return A new change recorder + */ + + public static ChangeRecorder create() + { + 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.appendChild( root ); + return new ChangeRecorderXML( document, root ); + } + catch ( final ParserConfigurationException | DOMException e ) + { + throw new IllegalStateException( e ); + } + } + + 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 ) + { + Objects.requireNonNull( kind, "kind" ); + Objects.requireNonNull( groupId, "groupId" ); + Objects.requireNonNull( artifactId, "artifactId" ); + Objects.requireNonNull( oldVersion, "oldVersion" ); + Objects.requireNonNull( newVersion, "newVersion" ); + + final Element update = this.document.createElementNS( CHANGES_NAMESPACE, "update" ); + update.setAttribute( "kind", kind ); + update.setAttribute( "groupId", groupId ); + update.setAttribute( "artifactId", artifactId ); + update.setAttribute( "oldVersion", oldVersion ); + update.setAttribute( "newVersion", newVersion ); + this.root.appendChild( update ); + } + + @Override + public final void serialize( final OutputStream outputStream ) throws IOException + { + try + { + final Transformer transformer = TransformerFactory.newInstance().newTransformer(); + final Source source = new DOMSource( this.document ); + transformer.transform( source, new StreamResult( outputStream ) ); + outputStream.flush(); + } + catch ( final TransformerException ex ) + { + throw new IOException( ex ); + } + } +} diff --git a/src/main/resources/org/codehaus/mojo/versions/recording/schema-1.0.xsd b/src/main/resources/org/codehaus/mojo/versions/recording/schema-1.0.xsd new file mode 100644 index 000000000..10d0926b3 --- /dev/null +++ b/src/main/resources/org/codehaus/mojo/versions/recording/schema-1.0.xsd @@ -0,0 +1,37 @@ + + + + + + The 'update' element specifies a single version change. The 'kind' attribute describes the + operation that produced the version update, such as unlocking a snapshot version or upgrading to the next + release. + + + + + + + + + + + + + + + The 'updates' element specifies a set of version changes that occurred. + + + + + + + + + + + \ No newline at end of file diff --git a/src/site/apt/examples/recording-changes.apt b/src/site/apt/examples/recording-changes.apt new file mode 100644 index 000000000..a7b559476 --- /dev/null +++ b/src/site/apt/examples/recording-changes.apt @@ -0,0 +1,49 @@ + ~~ 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. + + ----- + Recording Changes + ----- + Mark Raynsford + ------ + 2020-06-27 + ------ + +Recording Changes + + Here's an example: + +--- +mvn versions:use-latest-releases -DchangeRecorderFormat=xml +--- + + Which writes a file to <<>> that looks something + like: + +--- + + + + +--- + + The contents of this file records the fact that <<>> + was upgraded to <<<3.0>>>. diff --git a/src/site/apt/index.apt b/src/site/apt/index.apt index a694163d3..6b2499ff1 100644 --- a/src/site/apt/index.apt +++ b/src/site/apt/index.apt @@ -164,3 +164,6 @@ Versions Maven Plugin * {{{./examples/use-releases.html}Replacing -SNAPSHOT versions with their corresponding releases}} * {{{./examples/set.html}Changing the project version}} + + * {{{./examples/recording-changes.html}Recording version changes}} + diff --git a/src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java b/src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java new file mode 100644 index 000000000..fdd2c05fc --- /dev/null +++ b/src/test/java/org/codehaus/mojo/versions/recording/ChangeRecorderXMLTest.java @@ -0,0 +1,98 @@ +package org.codehaus.mojo.versions.recording; + +/* + * 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 org.apache.commons.io.IOUtils; +import org.junit.Assert; +import org.junit.Test; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +public final class ChangeRecorderXMLTest +{ + private static void copyResource( final String name, final File output ) throws IOException + { + try ( FileOutputStream outputStream = new FileOutputStream( output ) ) + { + try ( InputStream inputStream = ChangeRecorderXMLTest.class.getResourceAsStream( name ) ) + { + IOUtils.copy( inputStream, outputStream ); + } + } + } + + private static Document parseXML( final File file ) throws ParserConfigurationException, IOException, SAXException + { + final DocumentBuilderFactory documentBuilders = DocumentBuilderFactory.newInstance(); + final DocumentBuilder documentBuilder = documentBuilders.newDocumentBuilder(); + return documentBuilder.parse( file ); + } + + @Test + public void testChanges() throws Exception + { + final File file0 = File.createTempFile( "ChangeRecorderTest", ".xml" ); + final File file1 = File.createTempFile( "ChangeRecorderTest", ".xml" ); + + copyResource( "expectedFile.xml", file0 ); + + final ChangeRecorder recorder = ChangeRecorderXML.create(); + recorder.recordUpdate( "exampleKind", "org.codehaus", "example0", "0.0.1", "0.0.2" ); + recorder.recordUpdate( "exampleKind", "org.codehaus", "example1", "1.0.0", "2.0.0" ); + + try ( FileOutputStream outputStream = new FileOutputStream( file1 ) ) + { + recorder.serialize( outputStream ); + } + + final Document document0 = parseXML( file0 ); + final Document document1 = parseXML( file1 ); + + final NodeList elements0 = document0.getElementsByTagNameNS( ChangeRecorderXML.CHANGES_NAMESPACE, "updated" ); + final NodeList elements1 = document1.getElementsByTagNameNS( ChangeRecorderXML.CHANGES_NAMESPACE, "updated" ); + + Assert.assertEquals( "Correct number of updates", elements0.getLength(), elements1.getLength() ); + + for ( int index = 0; index < elements0.getLength(); ++index ) + { + final Element element0 = (Element) elements0.item( index ); + final Element element1 = (Element) elements1.item( index ); + + Assert.assertEquals( element0.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "artifactId" ), + element1.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "artifactId" ) ); + Assert.assertEquals( element0.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "groupId" ), + element1.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "groupId" ) ); + Assert.assertEquals( element0.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "oldVersion" ), + element1.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "oldVersion" ) ); + Assert.assertEquals( element0.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "newVersion" ), + element1.getAttributeNS( ChangeRecorderXML.CHANGES_NAMESPACE, "newVersion" ) ); + } + } +} diff --git a/src/test/resources/org/codehaus/mojo/versions/recording/expectedFile.xml b/src/test/resources/org/codehaus/mojo/versions/recording/expectedFile.xml new file mode 100644 index 000000000..868b40607 --- /dev/null +++ b/src/test/resources/org/codehaus/mojo/versions/recording/expectedFile.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file