Extract a maven module version with XPath and ansible

Because this took me entire too long to figure out: how can you extract the version of a maven module from a pom.xml using XPath, such as with ansible?

The problem is the default namespace and because XPath was designed by committee. You would expect /project/version to work, or maybe /project/version/text(). But it won’t work. Instead, the XPath expression you need is:

/*[namespace-uri()='http://maven.apache.org/POM/4.0.0' and local-name()='project']/*[namespace-uri()='http://maven.apache.org/POM/4.0.0' and local-name()='version']/text()

Yep. Annoying, right?

The current version of ansible (and the ansible-xml module) returns a fairly helpless error:

Can't process Xpath / in order to spawn nodes!

Even if you use the correct XPath expression, you still get a variant on that message. Instead, you need to just use a command:

    - name: get module version
      command: xmllint --xpath "/*[namespace-uri()='http://maven.apache.org/POM/4.0.0' and local-name()='project']/*[namespace-uri()='http://maven.apache.org/POM/4.0.0' and local-name()='version']/text()" path/to/module/pom.xml
      register: pomVersion
    - debug:
        var: pomVersion.stdout

Presuming you then do a maven build, you’ll probably end up with something like:

    - name: mvn clean
      command: mvn clean
        chdir: path/to/module
    - name: mvn package
      command: mvn -DskipTests=true package
        chdir: path/to/module
        creates: "target/module-{{ pomVersion.stdout }}.jar"