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。它仅允许用户从周围的&lt;execution&gt; 元素中省略&lt;phase&gt; 元素。

如需进一步确认,请参阅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 -- 生命周期与插件

避免maven package 打包时执行 mybatis-generator-maven-plugin 插件

在 wordpress 中自动执行插件而不激活它们?

maven项目打包插件:将maven项目打包成一个可执行的jar(瘦jar)

无法将 Groovy Maven 插件作为目标执行

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