Skip to content

Instantly share code, notes, and snippets.

@swthomas55
Last active December 31, 2021 18:52
Show Gist options
  • Save swthomas55/8efd7fe8317b447f58f7 to your computer and use it in GitHub Desktop.
Save swthomas55/8efd7fe8317b447f58f7 to your computer and use it in GitHub Desktop.
Manage POM versions in multi-module Maven projects
#! /bin/sh
#
# Usage: pom-advance-snapshots.sh
#
# Update the version of every POM to the next patch version, append the git branch name and SNAPSHOT
# unless the POM already has a SNAPSHOT version.
#
# Thus, version 1.3.4 becomes 1.3.5-branch-SNAPSHOT.
#
# Requires xmlstarlet and maven versions plugin. Invokes maven as "mvn".
branch=$(git status -b --porcelain | sed -n '1s/## *\([^.]*\).*/\1/p')
if [ "$branch" == "master" ] ; then
branch=""
else
branch=${branch}-
fi
# Uncomment this line to change only modified POM files.
# $(git status --porcelain | sed 's/^ *M *//'|grep pom.xml)
for i in pom.xml */pom.xml ; do
j=`dirname $i`
v=$(xmlstarlet sel -N x=http://maven.apache.org/POM/4.0.0 -t -m /x:project/x:version -v . $i)
if [ $(expr $v : '.*-SNAPSHOT$') -eq 0 ] ; then
v1=$(perl -e "@v = split(/\./, \"$v\"); @v[2]++; print join(\".\",@v)")
newv=${v1}-${branch}SNAPSHOT
echo Changing version $v to $newv for $i
mvn -q versions:set -DnewVersion=$newv -pl $j | grep -v "^Props: "
fi
done
#!/usr/bin/env bash
# Check all POM files in the project for embedded SNAPSHOT versions.
# Output is a series of XML <pom> elements with non-snapshot versions indicated.
# The <pom> element has a "file" attribute with the POM file name.
# If the pom itself has a snapshot version, it will be indicated with a <version> element as a direct child of the <pom>
# Other elements in the pom with a snapshot version are included as the full parent element of the version,
# such as <dependency> or <parent> elements.
#
# The -v option will print a <pom> element for all POMs, even those with no snapshot versions.
# Sample output
cat <<EOF >/dev/null
<pom file="./pom.xml">
<version>1.1.7-AUTH-967-SNAPSHOT</version>
</pom>
<pom file="./iac-export-service/pom.xml">
<parent>
<groupId>org.ithaka.sequoia</groupId>
<artifactId>iac-export</artifactId>
<version>1.1.7-AUTH-967-SNAPSHOT</version>
</parent>
<version>1.10.7-AUTH-967-SNAPSHOT</version>
<dependency>
<groupId>org.ithaka.sequoia.iac</groupId>
<artifactId>iac-sql-dao</artifactId>
<version>1.11.6-AUTH-967-SNAPSHOT</version>
</dependency>
</pom>
<pom file="./iac-sql-dao/pom.xml">
<parent>
<groupId>org.ithaka.sequoia</groupId>
<artifactId>iac-export</artifactId>
<version>1.1.7-AUTH-967-SNAPSHOT</version>
</parent>
<version>1.11.6-AUTH-967-SNAPSHOT</version>
</pom>
EOF
verbose=false
if [ x$1 == x-v ] ; then
verbose=true
fi
find . -name target -prune -o -name pom.xml -print | \
awk '{path=$0; gsub("[^/]+", "", path); print length(path), $0}' | sort -n | awk '{print $2}' | \
xargs -n 1 xmlstarlet sel -N x="http://maven.apache.org/POM/4.0.0" ="http://maven.apache.org/POM/4.0.0" -t \
-m x:project -e pom -a file -f -b \
-m "descendant::x:version['-SNAPSHOT' = substring(., string-length() - 8)]" \
--if "local-name(..)='project'" -c . -n --else -c .. -n -b \
-b | \
(
echo '<poms xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">'
cat
echo "</poms>"
) |\
if $verbose ; then
cat
else
xmlstarlet ed -N x="http://maven.apache.org/POM/4.0.0" -d "//x:pom[count(child::*)=0]"
fi | \
xmlstarlet fo -o --nsclean | \
sed -e '/<poms/d' -e '/<\/poms>/d'
#!/usr/bin/env bash
#
# Uses the graph-maven-plugin to graph dependencies for a project. At the end it prints the names of the
# dependency graphs it created.
if [[ x$1 == x-h* ]] ; then
echo "Usage $0 [parameters]"
echo "See http://site.kuali.org/maven/plugins/graph-maven-plugin/1.2.3/dependencies-mojo.html for parameter descriptions."
echo "Note that parameter names should be prefixed with 'graph.'"
fi
mvn org.kuali.maven.plugins:graph-maven-plugin:1.2.3:dependencies "-Dgraph.includes=org.cirrostratus*,org.ithaka*" $* | \
egrep 'SUCCESS|FAIL|Building'
find . -name dependencies.png
#! /bin/sh
#
# Usage: pom-release.sh
#
# Removes the SNAPSHOT from the versions of all POMs in the project, in preparation for release.
#
# Requires: xmlstarlet and maven versions plugin
dryRun=$
for i in */pom.xml pom.xml ; do
j=`dirname $i`
v=$(xmlstarlet sel -N x=http://maven.apache.org/POM/4.0.0 -t -m /x:project/x:version -v . $i)
newv=`echo $v|sed "s/-.*SNAPSHOT//"`
if [ $v != $newv ] ; then
echo Changing version $v to $newv for $i
mvn -q versions:set -DnewVersion=$newv -pl $j | grep -v "^Props: "
fi
done
#! /bin/sh
#
# Usage: pom-set-version.sh VERSION pom-or-directory ...
#
# Sets the version number of the specified POM files or the pom.xml in the specified directories to VERSION
#
# Requires: Maven versions plugin
#
# Invokes maven as "mvn"
if [ "$1" = "" ] ; then
echo "Usage: $0 version pom-files..."
exit 0
fi
version=$1
shift
for i in $* ; do
if [ $i = "pom.xml" -o $i = "." ] ; then
mvn -q versions:set -N -DnewVersion=$version | grep -v "^Props: "
else
if [ $(expr a : '.*/pom.xml') -gt 0 ] ; then j=`dirname $i`; else j=$i ; fi
mvn -q versions:set -DnewVersion=$version -pl $j | grep -v "^Props: "
fi
done
#! /bin/sh
#
# Usage: pom-unbranch-versions.sh
#
# Removes the current git branch from the version numbers of the POM files in the project.
# Other versions are left alone.
#
# Requires: xmlstarlet and maven versions plugin
#
# Invokes maven as "mvn"
branch=$(git status -b --porcelain | sed -n '1s/## *\([^.]*\).*/\1/p')
for i in */pom.xml pom.xml ; do
j=`dirname $i`
v=$(xmlstarlet sel -N x=http://maven.apache.org/POM/4.0.0 -t -m /x:project/x:version -v . $i)
newv=`echo $v|sed "s/-$branch-/-/"`
if [ "$v" != "$newv" ] ; then
echo Changing version $v to $newv for $i
mvn -q versions:set -DnewVersion=$newv -pl $j | grep -v "^Props: "
fi
done
#! /bin/sh
#
# Usage: pom-versions.sh [-p]
#
# Print the POM version for all POMs in the project.
# With optional -p argument, also print the version of the parent POM
#
# Assumes a single level of module nesting.
#
# Requires xmlstarlet.
parentargs=(-n)
while getopts p opt ; do
if [ $opt == p ] ; then
parentargs=(-m x:parent -o ' parent:' -v x:version -t -m /x:project -n)
fi
done
xmlstarlet sel -N x=http://maven.apache.org/POM/4.0.0 -t -m /x:project -f -o ' ' -v x:name -o ' ' -v x:version "${parentargs[@]}" \
$(find . \( -type d -name target -prune \) -o -name pom.xml -print | sed 's,^\./,,')
#!/bin/bash
#
# Usage: redeploy-to-nexus.sh
#
# Deploys all the modules with "jar" packaging and the parent POM.
if maven -h >/dev/null 2>&1 ; then
MAVEN=maven
else
MAVEN=mvn
fi
# Deploy the parent POM
$MAVEN deploy -N
# build and deploy all the libraries, but get them in the right order
$MAVEN deploy -U -fn -pl $(echo $(grep -l '<packaging>jar' */pom.xml | sed 's,/.*,,') | sed 's/ /,/g')
@swthomas55
Copy link
Author

This is a set of scripts that I find happy for keeping the multiple modules of a large Maven project in sync, version-wise. The project is configured with all dependencies managed in the parent POM, so most changes require updating the version number of all the module POMs. My usual sequence of actions is:

  • Create a new branch with git.
  • Run pom-advance-snapshots.sh to create SNAPSHOT versions.
  • Use pom-set-version.sh if I need to advance any POM to something other than the next "patch" version.
  • Edit, test, deploy, until it is ready for release.
    • Use redeploy-to-nexus.sh as necessary to keep jar versions up to date in the nexus.
  • Run pom-release.sh to create release versions.
  • Merge back to master.
  • Run redeploy-to-nexus.sh to deploy the release versions of the parent POM and jars.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment