How to extract the GAV from a pom.xml file in a shell script How to extract the GAV from a pom.xml file in a shell script shell shell

How to extract the GAV from a pom.xml file in a shell script


The best solution I could find is using an XSL transformation. Create a file extract-gav.xsl with the following content:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0"    xmlns:pom="http://maven.apache.org/POM/4.0.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    <xsl:output indent="yes" omit-xml-declaration="yes"/>    <xsl:strip-space elements="*"/>    <xsl:template match="/pom:project">        <!-- this XML element just serves as a bracket and may be omitted -->        <xsl:element name="artifact">            <xsl:text>&#10;</xsl:text>            <!-- process coordinates declared at project and project/parent -->            <xsl:apply-templates select="pom:groupId|pom:parent/pom:groupId" mode="copy-coordinate"/>            <xsl:apply-templates select="pom:artifactId|pom:parent/pom:artifactId" mode="copy-coordinate"/>            <xsl:apply-templates select="pom:version|pom:parent/pom:version" mode="copy-coordinate"/>        </xsl:element>    </xsl:template>    <xsl:template match="*" mode="copy-coordinate">        <!-- omit parent coordinate if same coordinate is explicitly specified on project level -->        <xsl:if test="not(../../*[name(.)=name(current())])">            <!-- write coordinate as XML element without namespace declarations -->            <xsl:element name="{local-name()}">               <xsl:value-of select="."/>            </xsl:element>            <xsl:text>&#10;</xsl:text>        </xsl:if>    </xsl:template></xsl:stylesheet>

This transformation can then be invoked in a shell (assuming that you have the libxslt installed) with th command xsltproc extract-gav.xsl pom.xml

This produces the output in the following format:

<artifact>  <groupId>org.example.group</groupId>  <artifactId>example-artifact</artifactId>  <version>1.2.0</version></artifact>

If you need a different format, the XSL transformation should be easy enough to adapt so that it suits your needs. E.g. the following transformation writes the GAV as tab-separated plain text:

<?xml version="1.0" encoding="UTF-8"?><xsl:stylesheet version="1.0"    xmlns:pom="http://maven.apache.org/POM/4.0.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">    <xsl:output method="text"/>    <xsl:strip-space elements="*"/>    <xsl:template match="/pom:project">        <!-- process coordinates declared at project and project/parent -->        <xsl:apply-templates select="pom:groupId|pom:parent/pom:groupId" mode="copy-coordinate"/>        <xsl:apply-templates select="pom:artifactId|pom:parent/pom:artifactId" mode="copy-coordinate"/>        <xsl:apply-templates select="pom:version|pom:parent/pom:version" mode="copy-coordinate"/>        <xsl:text>&#10;</xsl:text>    </xsl:template>    <xsl:template match="*" mode="copy-coordinate">        <xsl:if test="not(../../*[name(.)=name(current())])">            <xsl:value-of select="."/>            <xsl:text>&#9;</xsl:text>        </xsl:if>    </xsl:template></xsl:stylesheet>


grep -v '\[' <( mvn help:evaluate -Dexpression="project.groupId" 2>/dev/null &&     mvn help:evaluate -Dexpression="project.artifactId" 2>/dev/null &&     mvn help:evaluate -Dexpression="project.version" 2>/dev/null )


I use a groovy script called pom that I placed on PATH. It looks like this:

#!/usr/bin/env groovydef cli = new CliBuilder(usage:'pom')cli.h('print usage')cli.n('do not auto-print output')cli.p(args:1, argName:'pom', 'the POM file to use')def options = cli.parse(args)def arguments = options.arguments()if (options.h || arguments.size() == 0 ) {    println cli.usage()} else {    def fileName = options.p ? options.p : "pom.xml"    def script = arguments[0]    def output = Eval.x(new XmlSlurper().parse(new File(fileName)), "x.${script}")    if (!options.n) println output}

Now you can extract values like this:

pom versionpom groupIdpom 'properties."project.build.sourceEncoding"'pom -n 'modules.module.each { println it }'pom -n 'dependencyManagement.dependencies.dependency.each { \    println "${it.groupId}:${it.artifactId}:${it.version}" \}'