Skip to content

Commit

Permalink
Provide a "change recorder" for updates
Browse files Browse the repository at this point in the history
This provides a ChangeRecorder interface that logs changes to a
machine-readable XML file whenever a pom.xml file is updated.

Affects: mojohaus#356
  • Loading branch information
io7m committed Jun 27, 2020
1 parent 0b90014 commit 9f8eb8e
Show file tree
Hide file tree
Showing 20 changed files with 646 additions and 109 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,18 @@
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.artifact.filter.PatternExcludesArtifactFilter;
import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
import org.codehaus.mojo.versions.recording.ChangeRecorder;
import org.codehaus.mojo.versions.recording.ChangeRecorderNull;
import org.codehaus.mojo.versions.recording.ChangeRecorderXML;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

/**
* Base class for a mojo that updates dependency versions.
Expand All @@ -44,30 +56,29 @@
* @author Stephen Connolly
* @since 1.0-alpha-3
*/
public abstract class AbstractVersionsDependencyUpdaterMojo
extends AbstractVersionsUpdaterMojo
public abstract class AbstractVersionsDependencyUpdaterMojo extends AbstractVersionsUpdaterMojo
{

private static final String END_RANGE_CHARS = "])";

private static final String START_RANGE_CHARS = "[(";

/**
* A comma separated list of artifact patterns to include. Follows the pattern
* "groupId:artifactId:type:classifier:version". Designed to allow specifing the set of includes from the command
* line. When specifying includes from the pom, use the {@link #includes} configuration instead. If this property is
* specified then the {@link # include} configuration is ignored.
* A comma separated list of artifact patterns to include. Follows the pattern "groupId:artifactId:type:classifier:version".
* Designed to allow specifing the set of includes from the command line. When specifying includes from the pom, use
* the {@link #includes} configuration instead. If this property is specified then the {@link # include}
* configuration is ignored.
*
* @since 1.0-beta-1
*/
@Parameter( property = "includes" )
private String includesList = null;

/**
* A comma separated list of artifact patterns to exclude. Follows the pattern
* "groupId:artifactId:type:classifier:version". Designed to allow specifing the set of excludes from the command
* line. When specifying excludes from the pom, use the {@link #excludes} configuration instead. If this property is
* specified then the {@link # exclude} configuration is ignored.
* A comma separated list of artifact patterns to exclude. Follows the pattern "groupId:artifactId:type:classifier:version".
* Designed to allow specifing the set of excludes from the command line. When specifying excludes from the pom, use
* the {@link #excludes} configuration instead. If this property is specified then the {@link # exclude}
* configuration is ignored.
*
* @since 1.0-beta-1
*/
Expand Down Expand Up @@ -97,23 +108,26 @@ public abstract class AbstractVersionsDependencyUpdaterMojo
*
* @since 1.0-alpha-3
*/
@Parameter( property = "processDependencies", defaultValue = "true" )
@Parameter( property = "processDependencies",
defaultValue = "true" )
private boolean processDependencies;

/**
* Whether to process the dependencyManagement section of the project.
*
* @since 1.0-alpha-3
*/
@Parameter( property = "processDependencyManagement", defaultValue = "true" )
@Parameter( property = "processDependencyManagement",
defaultValue = "true" )
private boolean processDependencyManagement;

/**
* Whether to process the parent section of the project. If not set will default to false.
*
* @since 2.3
*/
@Parameter( property = "processParent", defaultValue = "false" )
@Parameter( property = "processParent",
defaultValue = "false" )
private boolean processParent = false;

/**
Expand All @@ -135,7 +149,8 @@ public abstract class AbstractVersionsDependencyUpdaterMojo
*
* @since 1.0-alpha-3
*/
@Parameter( property = "excludeReactor", defaultValue = "true" )
@Parameter( property = "excludeReactor",
defaultValue = "true" )
private boolean excludeReactor;

/**
Expand Down Expand Up @@ -227,8 +242,7 @@ protected Artifact findArtifact( Dependency dependency )
* @return Artifact
* @since 1.0-alpha-3
*/
protected Artifact toArtifact( Dependency dependency )
throws MojoExecutionException
protected Artifact toArtifact( Dependency dependency ) throws MojoExecutionException
{
Artifact artifact = findArtifact( dependency );
if ( artifact == null )
Expand All @@ -245,8 +259,7 @@ protected Artifact toArtifact( Dependency dependency )
return artifact;
}

protected Artifact toArtifact( Parent model )
throws MojoExecutionException
protected Artifact toArtifact( Parent model ) throws MojoExecutionException
{
Dependency d = new Dependency();
d.setArtifactId( model.getArtifactId() );
Expand Down Expand Up @@ -311,9 +324,11 @@ protected String toString( Dependency d )
*/
protected boolean isProducedByReactor( Dependency dependency )
{
for ( Object reactorProject : reactorProjects ) {
for ( Object reactorProject : reactorProjects )
{
MavenProject project = (MavenProject) reactorProject;
if ( compare(project, dependency) ) {
if ( compare( project, dependency ) )
{
return true;
}
}
Expand All @@ -325,7 +340,7 @@ protected boolean isProducedByReactor( Dependency dependency )
* Compare a project to a dependency. Returns true only if the groupId and artifactId are all equal.
*
* @param project the project
* @param dep the dependency
* @param dep the dependency
* @return true if project and dep refer to the same artifact
*/
private boolean compare( MavenProject project, Dependency dep )
Expand Down Expand Up @@ -399,7 +414,7 @@ protected boolean isIncluded( Artifact artifact )

/**
* Indicates whether any includes were specified via the 'includes' or 'includesList' options.
*
*
* @return true if includes were specified, false otherwise.
*/
protected boolean hasIncludes()
Expand Down Expand Up @@ -512,5 +527,4 @@ private int findFirstChar( final String includeString, final String chars )
}
return nextRangeStartDelimiterIndex;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 ---------------------

Expand Down Expand Up @@ -335,6 +360,8 @@ protected void process( File outFile )
}
writeFile( outFile, input );
}

this.saveChangeRecorderResults();
}
catch ( IOException e )
{
Expand Down Expand Up @@ -488,16 +515,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 =
Expand All @@ -512,5 +532,63 @@ 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;
}

try ( FileOutputStream outputStream = new FileOutputStream( this.changeRecorderOutputFile ) )
{
this.changeRecorder.serialize( outputStream );
}
}
}
32 changes: 18 additions & 14 deletions src/main/java/org/codehaus/mojo/versions/UnlockSnapshotsMojo.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 ------------------------------
Expand All @@ -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() )
Expand All @@ -81,8 +82,7 @@ protected void update( ModifiedPomXMLEventReader pom )
}
}

private void unlockSnapshots( ModifiedPomXMLEventReader pom, List<Dependency> dependencies )
throws XMLStreamException, MojoExecutionException
private void unlockSnapshots( ModifiedPomXMLEventReader pom, List<Dependency> dependencies ) throws XMLStreamException, MojoExecutionException
{
for ( Dependency dep : dependencies )
{
Expand All @@ -109,16 +109,17 @@ private void unlockSnapshots( ModifiedPomXMLEventReader pom, List<Dependency> 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 )
{
Expand All @@ -141,8 +142,11 @@ private void unlockParentSnapshot( ModifiedPomXMLEventReader pom, MavenProject p
String unlockedParentVersion = versionMatcher.replaceFirst( "-SNAPSHOT" );
if ( PomHelper.setProjectParentVersion( pom, unlockedParentVersion ) )
{
getLog().info( "Unlocked parent " + parentArtifact.toString() + " to version "
+ unlockedParentVersion );
this.getChangeRecorder().recordUpdate( "unlockParentVersion", parentArtifact.getGroupId(),
parentArtifact.getArtifactId(), parentArtifact.getVersion(), unlockedParentVersion );

getLog().info(
"Unlocked parent " + parentArtifact.toString() + " to version " + unlockedParentVersion );
}
}
}
Expand Down
Loading

0 comments on commit 9f8eb8e

Please sign in to comment.