简体   繁体   English

如何从shell脚本中的pom.xml文件中提取GAV

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

I need to extract the Maven GAV (groupId, artifactId, version) from a large number of pom.xml files. 我需要从大量的pom.xml文件中提取Maven GAV(groupId,artifactId,version)。 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. 并非所有POM都具有父POM声明,因此需要考虑父GAV和项目GAV之间的继承。

I'd only like to use tools that can be easily scripted in a linux shell, eg bash. 我只想使用可以在linux shell中轻松编写脚本的工具,例如bash。

The best solution I could find is using an XSL transformation. 我能找到的最佳解决方案是使用XSL转换。 Create a file extract-gav.xsl with the following content: 使用以下内容创建文件extract-gav.xsl

<?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 然后可以在shell中调用此转换(假设您已安装libxslt),并使用命令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. 如果您需要不同的格式,XSL转换应该很容易适应,以便它适合您的需要。 Eg the following transformation writes the GAV as tab-separated plain text: 例如,以下转换将GAV写为制表符分隔的纯文本:

<?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. 我使用了一个名为pom的groovy脚本,我把它放在了PATH上。 It looks like this: 它看起来像这样:

#!/usr/bin/env groovy

def 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 version
pom groupId
pom 'properties."project.build.sourceEncoding"'
pom -n 'modules.module.each { println it }'
pom -n 'dependencyManagement.dependencies.dependency.each { \
    println "${it.groupId}:${it.artifactId}:${it.version}" \
}'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM