Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

shell

maven

I need to extract the Maven GAV (groupId, artifactId, version) from a large number of pom.xml files. Not all of the POMs have a parent POM declaration, so the inheritance between parent GAV and project GAV needs to be taken into account.

I'd only like to use tools that can be easily scripted in a linux shell, e.g. bash.

like image 208
oberlies Avatar asked Apr 08 '13 13:04

oberlies


People also ask

What does GAV mean in POM xml?

The GAV coordinate standard is the foundation for Maven's ability to manage dependencies. This set of coordinates is often referred to as a GAV coordinate, which is short for “Group, Artifact, Version coordinate.”"

What are the contents of the POM xml file?

The pom. xml file contains information of project and configuration information for the maven to build the project such as dependencies, build directory, source directory, test source directory, plugin, goals etc.

Where is POM xml stored?

The POM file is named pom. xml and should be located in the root directory of your project. A project divided into subprojects will typically have one POM file for the parent project, and one POM file for each subproject.


2 Answers

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 )
like image 74
ingyhere Avatar answered Oct 22 '22 08:10

ingyhere


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>
like image 28
oberlies Avatar answered Oct 22 '22 09:10

oberlies