使用Maven配置文件控制构建执行

42

我需要修改大型项目的Maven构建,以便在典型的开发构建过程中跳过某些步骤(例如不要构建*-source.jar文件)。我已经搜索了Maven的"条件执行",但没有找到相关内容。

Dev配置文件似乎是完成这个需求的直观方法,但我不知道Maven有多直观。配置文件的文档列出了如何为不同的配置文件设置不同的属性(例如数据库连接参数)。我可以设置一个属性,然后测试maven-source-plugin - executions - execution标记中是否设置了该属性。

这是在Maven中进行条件执行的正确方法吗?

在Maven中完成此操作的“正确”方法是什么?

3个回答

54

你的想法有些反过来了:让“配置文件”启用这种行为,而不是禁用它。这正是配置文件最擅长的,并且也正是你的情况:你只想在特定情况下运行这些步骤。所以你可以像这样:

<profile>
  <id>source-jars</id>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        ...

实际上,在maven-source-plugin使用页面上有一个类似于这样的示例。当您需要生成您的构件时,请使用mvn -P source-jars(或其他)。就是这样!如果您只需要在发布时执行此操作,则发布插件甚至提供了一种在发布插件配置中定义要使用的配置文件的方法。


我们的 POM 文件通常是写在默认运行 maven-source-plugin 的位置,因此我需要按照您的建议进行重构。 - Dean Schulze
4
许多情况下,插件默认启用并通过配置文件禁用是可取的。我认为这个回答没有解决问题,只是避开了它。 - Kevin
1
@Mowgli 但是Maven配置文件系统并不适合这种情况:它只有一个“激活”机制,而没有“停用”机制。一些插件通过构建自己的停用机制(例如surefire插件的skipTests)来处理此问题。 - Zac Thompson
1
这就是Maven病的精髓。 “不,你实际上并不想要一个有条件的构建,你真正想要的是这个颠倒过来的东西,需要你重新调整整个构建系统!看,这不是很棒吗?” 不是针对答案,我+1了它。 - wberry
@wberry 嗯,也许吧。就像我上面说的,Maven 配置文件系统可以很好地进行有条件的构建...通过有条件的启用内容。如果你想有条件地启用 禁用内容,我认为你的构建系统随着时间的推移将需要增加维护工作。现在,大多数对 Maven 的反对意见听起来像是:“我想创建自己的构建系统!”不过还是谢谢支持 :) - Zac Thompson

14
您可以通过向POM添加两个配置文件来实现默认启用源代码插件的实际目标。Maven配置文件文档指出,您可以在activation部分中添加元素<activeByDefault>true</activeByDefault>并声明:

此配置文件将自动对所有构建进行激活,除非使用先前描述的某种方法之一激活了同一POM中的其他配置文件

因此,您可以添加两个配置文件,其中一个是activeByDefault,其中包括相关插件,另一个则可以通过任何标准方式(例如从命令行使用-P)激活以防止运行默认配置文件。因此,pom.xml(或Maven设置或其他)中的profiles部分可能如下所示:

<profile>
  <id>source-jars</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-source-plugin</artifactId>
        ...
      </plugin>
    </plugins>
  </build>
</profile>
<profile>
   <!-- active this profile to disable the source-jars plugin -->
   <id>no-optional-plugins</id>
</profile>

很遗憾,我看不到一种方法可以使该方法适用于控制多个插件 - 我认为您需要O(n^2)个配置文件来控制n个插件,但对于这种简单情况,它应该可以正常工作。

Maven ≥ 2.0.10的另一个可能更简单的选择是只使用上面的source-jars配置文件(仍然是activeByDefault),并在需要时通过在-P CLI标志后加上-!来手动停用配置文件(链接):

$ mvn -P !source-jars

这种方法在使用多个插件时不会出现相同的O(n^2)问题,但也不够灵活,因为无法通过系统属性、环境变量、JDK版本等来触发停用。

0

总是有一个技巧,涉及系统属性,例如您可能会像我一样拥有一个带有Java和React/JavaScript/NPM/-GUI代码的GUI Maven模块。如果我的pom.xml看起来像这样:

  <profile>
  <id>ui</id>
  <activation>
    <activeByDefault>true</activeByDefault>
    <!-- Only build the UI if the skipUI system prop is not set -->
    <property>
      <name>!skipUI</name>
    </property>
  </activation>
  <build>
    <plugins>
      <plugin>
      ..

然后我可以像这样构建它

# mvn clean install

将会构建整个事物

# mvn -DskipUI clean install

我会跳过这部分,这样我就不必每次等待两千年的npm东西了,比如在我的情况下 - 显然不是一个“只通过配置文件”的解决方案,接受的答案描述了这个功能。但是如果你可以注入系统属性,这就是我通常做的。

另外,也许这是不言自明的,但无论如何,如果你将项目结构化,使得你有一个主要的父POM在子模块之上,那么在这个pom.xml中你可以说一些像

  <modules>
    <module>apa</module>
    <module>bepa</module>
    <module>cepa</module>
    ..
  </modules>
  
  <profiles>
    <profile>
      <id>additions</id>
      <activation>
        <activeByDefault>false</activeByDefault>
      </activation>
      <modules>
        <module>epa</module>
        <module>fepa</module>
        ..
      </modules>
    </profile>
    ..

这意味着在“主要”模块部分中,apa、bepa、cepa和其他模块将始终被构建,但如果您提供了“附加”配置文件,那么只有在这种情况下,epa和fepa也会被构建。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接