Maven:将插件执行绑定到另一个插件的执行,而不是生命周期阶段
Posted
技术标签:
【中文标题】Maven:将插件执行绑定到另一个插件的执行,而不是生命周期阶段【英文标题】:Maven: Bind plugin execution to the execution of another plugin, not to a lifecycle phase 【发布时间】:2013-04-28 14:47:52 【问题描述】:关于已接受答案的说明:我接受了该答案,因为有强有力的间接证据。尽管如此,这是间接证据,所以请持保留态度。
当用户运行插件目标而不是生命周期阶段时,如何触发插件? (这个has been asked之前,但答案是使用生命周期阶段。)
举个例子:我需要release:branch
调用regex-plugin
来生成一个以当前版本为名称的分支,减去 -SNAPSHOT 后缀。这就是我所拥有的,这需要开发人员激活配置文件并调用verify
阶段。我需要开发人员简单地调用release:branch
,这反过来会导致regex-plugin
运行。有点与 Gitflow 的结合。
<profile>
<id>Release Branch</id>
<build>
<plugins>
<!-- On validate, compute the current version without -SNAPSHOT. -->
<!-- Put the result in a property. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>regex-property</goal>
</goals>
<configuration>
<value>$project.version</value>
<regex>^(.*)-SNAPSHOT$</regex>
<replacement>$1</replacement>
<name>project.unqualifiedVersion</name>
</configuration>
</execution>
</executions>
</plugin>
<!-- Also on validate, run the branch plugin, and use -->
<!-- the non-SNAPSHOT version thus computed in the branch name. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>branch</goal>
</goals>
<configuration>
<branchName>release/$project.unqualifiedVersion</branchName>
<updateWorkingCopyVersions>true</updateWorkingCopyVersions>
<updateBranchVersions>false</updateBranchVersions>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
目的是让release:branch
将当前快照版本(例如1.0.5-SNAPSHOT
)移动到新分支中,该分支应以版本命名,但没有多余的-SNAPSHOT
后缀(1.0.5
)。然后当前分支应该采用新的快照版本(1.1.0-SNAPSHOT
,而不是 1.0.6-SNAPSHOT
,因为我们希望发布 1.0.x
有空间用于修补程序,所以我们为分支保留它)(我没有自动下一个快照版本的计算尚未确定,因此,如果您使用validate
运行上面的 Maven 配置,则必须在提示符下输入)。
【问题讨论】:
我支持你的评论,它不能完成,但我正在等待惊讶:) 是的,看起来不太好。这是另一个声称它不可行的答案:***.com/a/15185774/1569108。听起来像是自定义生命周期的工作,或者我应该完全从 Maven 中拿走它,而改用 Ant 之类的东西,因为 Maven 对这种情况非常不友好。如果他们有一个始终运行的虚拟阶段,即使我们只运行一个插件目标,也足以解决这个问题而不会让人头疼。 整个 Maven 发布插件甚至可能是您通常不会绑定到生命周期阶段的目标。因此,它们可能在设计时专门考虑了在命令行上传递参数。奇怪的是,prepare
目标支持 preparationGoals
,这听起来就像您想要的 branch
目标一样。
这样就可以了,虽然我不喜欢preparationGoals
,因为它在其他高度结构化的文件格式中缺乏结构。
我认为在这种情况下它不会完成这项工作,因为它与branch
目标(而不是prepare
目标)无关。
【参考方案1】:
不,您不能将一个插件绑定到另一个插件。只到一个阶段。
在 Maven 内部术语中,“Mojo”是可以工作的东西。 “插件”是封装的 mojo 集合,因此您可以从 POM 中引用它们。 Mojos 仅绑定到阶段。
来自plugin development documentation:
在插件描述符中指定的每个 Mojo 都必须提供以下内容
...
phase ... 如果用户未在 POM 中明确设置阶段,则定义一个默认阶段以将 mojo 执行绑定到。注意:当插件声明添加到 POM 时,此注释不会自动运行 mojo。它仅允许用户从周围的
<execution>
元素中省略<phase>
元素。
如需进一步确认,请参阅MojoExecution 的来源(此类的JavaDoc 没有帮助)并注意列举了两种可能的执行来源:
源自从 CLI 直接调用目标的执行
和
源自绑定到生命周期阶段的目标的执行
没有其他启动执行的方法意味着您不走运(除非采取特殊措施,例如推出您自己的插件,该插件结合了您要链接的两个插件的效果,然后使用您的自定义插件)。
【讨论】:
您似乎是正确的,没有标准的直接方法可以在不编写插件的情况下实现我所需要的,但是像jetspeed:mvn
这样的预先存在的“聚合器”插件怎么样?该网站还很好地解释了标准的链接方式。 portals.apache.org/jetspeed-2/buildguide/…
有强有力的间接证据表明你是对的,但你的回答仍然不能证明这一点。首先,默认阶段仅与阶段绑定执行有关,与 CLI 执行无关。该要求并不排除从 CLI 调用执行多个目标,就像它排除从 CLI 调用执行单个目标一样。其次,源代码提到直接调用 a 目标,而不是所讨论的目标。谁说由 CLI 触发的多个目标不是由相同的 Source
表示?
@MihaiDanila 是的,这就是我最后对冲一点的原因。我的假设是您希望使用 插件而不是开发它们。你可以编写新的插件,或者获取一个插件来调用一些外部脚本,然后运行另一个 Maven 实例,等等。但是当你到达这一点时,你可能真的应该使用 Ant 或其他东西,而不是构建一堆Maven 之上的杂物。【参考方案2】:
目前提供的证据相当间接。我自己做了一些研究,所以最好在这里分享一下。以下是更多相同的“不可能”,或者是替代方案的构建块。
jetspeed:mvn plugin --- 运行指定序列的插件;要运行的配置可以通过系统属性进行更改; IDE 集成问题
Executing goals before plugin runs (***) --- 在自定义 Mojo 的上下文中回答了相同的问题
Make Mojo run other goals (***) --- 再次,来自自定义 Mojo 的上下文
Configuring default Mojo executions --- 描述 Mojos 如何运行的 Maven 页面 - 更多间接证据
Triggering phases before goal execution (***) --- 迂回解决我的问题,不幸的回答是否定的
有趣:Guide to Ant plugin development --- 吸引我,因为虽然它需要编写自定义插件,但都是 Ant + Maven 配置,无需编译代码;可能进入门槛较低
Creating a parallel lifecycle --- 吸引人的方法,因为我可以完全控制生命周期的内容到它将使用 Gitflow 动词的位置;不清楚 IDE 将如何集成它;存在学习曲线和采用障碍问题
【讨论】:
以上是关于Maven:将插件执行绑定到另一个插件的执行,而不是生命周期阶段的主要内容,如果未能解决你的问题,请参考以下文章
避免maven package 打包时执行 mybatis-generator-maven-plugin 插件