在 Maven 中,如何在运行时动态构建属性值?

Posted

技术标签:

【中文标题】在 Maven 中,如何在运行时动态构建属性值?【英文标题】:In Maven, how can I dynamically build a property value at runtime? 【发布时间】:2012-08-13 16:19:36 【问题描述】:

在 maven 中,使用以下语法在 pom 中设置属性非常容易:

...
<properties>
  <myValue>4.06.17.6</myValue>
 </properties>
...

现在我需要构建一个取决于我的 pom 版本的属性。为了创建属性,我想要执行以下操作(java 伪代码):

String[] parts = version.split("\\.");
String.format("V%s_%s_%s_P%s", splitted[0],  splitted[1],splitted[2],splitted[3]);
// example: 4.06.17.6 => V_4_06_17_P6

它应该是动态的,因为它在我们的存储库中用作标签名称,并且必须始终与工件的版本同步。

任何想法如何创建“动态”属性?

【问题讨论】:

【参考方案1】:

Mojo 的 Build-Helper Maven 插件可以在这里为您提供帮助。

有许多目标可用于帮助转换属性。

build-helper:regex-property

build-helper:parse-version

build-helper:released-version

regex-property 可能是您想要的,但如果您的版本号符合“标准”,其他两个可能会节省您的时间。

要使用regex-property 目标,您可以执行类似的操作

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.7</version>
        <executions>
          <execution>
            <id>regex-property</id>
            <goals>
              <goal>regex-property</goal>
            </goals>
            <configuration>
              <name>tag.version</name>
              <value>$project.version</value>
              <regex>^([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+)\.(-SNAPSHOT)?$</regex>
              <replacement>V$1_$2_$3_P$4</replacement>
              <failIfNoMatch>true</failIfNoMatch>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

注意:我的正则表达式可能略有偏差,因此您应该测试上述内容。

注意:属性值仅可用于在此执行绑定到的阶段之后的执行。它绑定到的默认阶段是validate,但如果您处于不同的生命周期(例如站点生命周期),则该值将不可用。

【讨论】:

如果我没有将插件绑定到一个阶段。我正在使用 Maven 发布插件并调用目标发布:准备。如何在此处提供它? 如果不指定阶段,默认绑定到validate阶段,所以上面的代码sn-p会在验证阶段激活时执行目标。当您直接调用目标时,例如release:prepare,发生的事情是 maven 运行目标直接跳过任何生命周期阶段,因此 release:prepare 目标本身不会看到属性 生命周期 forked by @ 987654332@ 会看到。所以release:prepare 将无法使用该属性来标记 SCM,但该属性将出现在发布插件运行的分叉构建中 如果您想要基于属性的 SCM 标签(您应该更新您的问题以反映这是您的目标,或者开始第二个问题),那么您可能需要使用类似 @987654326 @ 虽然这不会给你你想要的_ 替换,也不会给你_P 注入。我建议更改标签名称要求,而不是尝试弯曲 Maven ;-) 好的。我创建了一个新问题。也许运气更好。我无法更改标记名称定义,因为对许多部门而言,必须更改标记行为。 :-( 哇... 24 行 XML 替换了 2 行 Java。有没有少一点……冗长的选项?【参考方案2】:

您可以使用 maven build-helper 插件,尤其是它的regex-property mojo。查看usage examples(滚动到通过对值应用正则表达式替换来设置属性部分)。

基本上,您希望在您的 pom 中使用类似的东西来获取从 myValue 推断的 myVersionTag 属性:

<project>
  ...
  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>build-helper-maven-plugin</artifactId>
        <version>1.7</version>
        <executions>
          <execution>
            <id>regex-property</id>
            <goals>
              <goal>regex-property</goal>
            </goals>
            <configuration>
              <name>myVersionTag</name>
              <value>$\myValue</value>
              <regex>(\d+)\.(\d+)\.(\d+)\.(\d+)</regex>
              <replacement>V_$1_$2_$3_P$4</replacement>
            </configuration>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>
  ...
</project>

【讨论】:

我也会将此答案标记为已接受,因为它与上面的答案相同。谢谢。 不完全。 Ihor 的示例在 元素中的 '$' 和 '' 之间放置了一个 '\'。这就是 Codehaus 文档所说的这样做,但这是错误的。 regex-property 目标不能与反斜杠一起使用,并且在没有它的情况下也可以。 Codehaus 倒闭了。 @SteveCohen 如果文档有误,请打开问题github.com/mojohaus/build-helper-maven-plugin/issues【参考方案3】:

Ihor Kaharlichenko 的回答基本上是正确的,只是它从Codehaus documentation 复制了一个错误。 '$' 和'' 之间不应有'\'。 mojo 在没有它的情况下也可以工作,但在使用它时也不能工作。确实,对 regex 和 Maven 有基本的了解,我看不出反斜杠应该做什么,而且确实是错误的。 p>

斯蒂芬康诺利的答案正确地省略了反斜杠。小心。 这个错误在整个 SO 中激增,Codehaus 倒闭可能永远不会得到修复。

【讨论】:

以上是关于在 Maven 中,如何在运行时动态构建属性值?的主要内容,如果未能解决你的问题,请参考以下文章

为啥maven在构建过程中不复制属性文件?

在 Maven 中发布时的私有构建信息(db 等)?

如何使用 maven mvn test 命令行运行动态 testng.xml?

在 Eclipse 中构建可执行 jar 时如何排除属性?

如何使用不同的属性两次执行 Maven 插件

即使在添加类路径和主类之后也没有主清单属性 maven 构建