【问题标题】:How to extract the GAV from a pom.xml file in a shell script如何从 shell 脚本中的 pom.xml 文件中提取 GAV
【发布时间】:2013-04-08 13:44:09
【问题描述】:

我需要从大量pom.xml 文件中提取Maven GAV(groupId、artifactId、version)。并非所有 POM 都有父 POM 声明,因此需要考虑父 GAV 和项目 GAV 之间的继承。

我只想使用可以在 linux shell 中轻松编写脚本的工具,例如重击。

【问题讨论】:

    标签: shell maven


    【解决方案1】:
    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 )
    

    【讨论】:

    • 虽然这段代码 sn-p 可以解决问题,但including an explanation 确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而这些人可能不知道您提出代码建议的原因。
    • 这不是批评,只是建议让您的单线求解器对未来的 SO 用户更有用和更有价值。
    • 要求依赖项已经更新(即没有“Downloading”/“Downloaded”消息),但效果很好!
    • 当 Maven 执行时,它提供了大量的信息标准输出。此脚本通过使用 grep exclude 从 Maven 输出中排除信息性 STDOUT 来工作。 (Maven STDOUT 包含记录键,例如“[INFO]”,它们被 '\' 排除。)剩下的唯一部分是帮助插件的实际命令输出。 (帮助插件的评估目标只是执行“-Dexpression=”命令行标志中提供的表达式评估。)
    • 实际上可以在没有 maven-help-plugin 版本 3.1.0 中的 grep 的情况下执行此操作。它现在包含一个参数“forceStdout”,您可以将其与 maven“-q”开关一起使用,以仅打印您想要的结果。例如mvn help:evaluate -Dexpression="project.groupId" -q -DforceStdout
    【解决方案2】:

    我能找到的最佳解决方案是使用 XSL 转换。创建一个文件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>
    

    然后可以在 shell 中调用此转换(假设您已安装 libxslt),使用命令 xsltproc extract-gav.xsl pom.xml

    这会产生以下格式的输出:

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

    如果您需要不同的格式,XSL 转换应该很容易适应,以便满足您的需要。例如。以下转换将 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>
    

    【讨论】:

      【解决方案3】:

      我使用了一个名为 pom 的 groovy 脚本,它放在 PATH 上。它看起来像这样:

      #!/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
      }
      

      现在您可以像这样提取值:

      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}" \
      }'
      

      【讨论】:

        猜你喜欢
        • 2015-08-16
        • 2011-09-08
        • 2021-06-15
        • 1970-01-01
        • 1970-01-01
        • 2012-09-17
        • 1970-01-01
        • 2022-11-14
        • 1970-01-01
        相关资源
        最近更新 更多