News and Notes from the Makers of Nexus | Sonatype Blog

Pin the Snapshot Dependency Versions in Your POM

Written by Tim OBrien | August 14, 2007

Occasionally, you might want to pin the versions of snapshot dependencies in your pom.xml to the most recent unique version (referenced by timestamp/buildnumber instead of "-SNAPSHOT"). To show how easy it is to do this, I've written a tiny little plugin to accomplish it. You can grab it from here: http://www.commonjava.org/~jdcasey/maven-misc/plugins/snapshot-pin-maven-plugin.zip, or wait a little while, and I'll put it in the mojo sandbox at http://mojo.codehaus.org.

Essentially, what this plugin does is ask Maven to resolve all of the current project's dependencies (up to the test scope). From here, it re-reads the POM from file, to ensure that the instance we're working with is clean. Then, it maps the resolved artifacts by a version-less key of groupId:artifactId, and iterates through all dependencies (even those declared in dependencyManagement in the current pom.xml) and replaces the dependency version with the resolved one, if it can find one. In some cases, the local POM may declare a managed dependency, but not use it...these may not get pinned. After everything is finished, the mojo checks whether anything has changed in the POM instance, and writes the changes to file if so.

One glaring GOTCHA in this process is a query method that changes the state inside the resolve artifact instances. This method is Artifact.isSnapshot(), and it has the critical effect of changing the output of Artifact.getVersion() from the "-SNAPSHOT" predicated string to one with the timestamp and buildnumber that was resolved earlier in the build. It truly sucks that we have to call a query method in order to expose this information, but at this point it's legacy (released), so we do what we can to get the results we need.

If you've been looking for something like this, enjoy. Otherwise, thanks for tuning in anyway!