我有一个 MOJO 我想执行一次,并且只有在反应堆中最后一个项目的测试阶段之后才能运行一次。
使用:
if (!getProject().isExecutionRoot()) {
return ;
}
在 execute() 方法的开头意味着我的 mojo 被执行一次,但是在构建的最开始 - 在所有其他子模块之前。
我有一个 MOJO 我想执行一次,并且只有在反应堆中最后一个项目的测试阶段之后才能运行一次。
使用:
if (!getProject().isExecutionRoot()) {
return ;
}
在 execute() 方法的开头意味着我的 mojo 被执行一次,但是在构建的最开始 - 在所有其他子模块之前。
我为此找到的最佳解决方案是:
/**
* The projects in the reactor.
*
* @parameter expression="${reactorProjects}"
* @readonly
*/
private List reactorProjects;
public void execute() throws MojoExecutionException {
// only execute this mojo once, on the very last project in the reactor
final int size = reactorProjects.size();
MavenProject lastProject = (MavenProject) reactorProjects.get(size - 1);
if (lastProject != getProject()) {
return;
}
// do work
...
}
这似乎适用于我测试过的小型构建层次结构。
最好的解决方案是通过扩展您的类来依赖生命周期扩展org.apache.maven.AbstractMavenLifecycleParticipant
(另请参见https://maven.apache.org/examples/maven-3-lifecycle-extensions.htmlafterSessionEnd
),其中添加了一个方法https://issues .apache.org/jira/browse/MNG-5640(在 Maven 3.2.2 中修复)。
有一个Sonatype 博客条目描述了如何执行此操作。最后一个要运行的项目将是根项目,因为它将包含对其余项目的模块引用。因此,您需要在 mojo 中进行测试,以检查当前项目的目录是否与启动 Maven 的目录相同:
boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());
在引用的条目中有一个非常全面的示例,说明如何在您的 mojo 中使用它。
如果您使用@aggregator标签并将您的 mojo 绑定到以下生命周期阶段之一,我认为您可能会得到您需要的东西:
自 Maven 3.x 以来,使用 session.getEventDispatcher() 的解决方案不再有效。整个事件已在此提交中删除:https ://github.com/apache/maven/commit/505423e666b9a8814e1c1aa5d50f4e73b8d710f4
您可以将 EventMonitor 添加到调度程序,然后捕获 'reactor-execute' 事件的 END:这是在一切完成后调度的,即即使在您看到 BUILD SUCCESSFUL/FAILED 输出之后。
这是我最近使用它在最后打印摘要的方式:
/**
* The Maven Project Object
*
* @parameter expression="${project}"
* @required
* @readonly
*/
protected MavenProject project;
/**
* The Maven Session.
*
* @parameter expression="${session}"
* @required
* @readonly
*/
protected MavenSession session;
...
@Override
public void execute() throws MojoExecutionException, MojoFailureException
{
//Register the event handler right at the start only
if (project.isExecutionRoot())
registerEventMonitor();
...
}
/**
* Register an {@link EventMonitor} with Maven so that we can respond to certain lifecycle events
*/
protected void registerEventMonitor()
{
session.getEventDispatcher().addEventMonitor(
new EventMonitor() {
@Override
public void endEvent(String eventName, String target, long arg2) {
if (eventName.equals("reactor-execute"))
printSummary();
}
@Override
public void startEvent(String eventName, String target, long arg2) {}
@Override
public void errorEvent(String eventName, String target, long arg2, Throwable arg3) {}
}
);
}
/**
* Print summary at end
*/
protected void printSummary()
{
...
}
你可以使用 mavensession 来解决这个问题
public boolean isThisTheLastProject() {
return session.getProjectDependencyGraph().getSortedProjects().
get(session.getProjectDependencyGraph().getSortedProjects().size()-1).getArtifactId().equalsIgnoreCase(project.getArtifactId());
}
通常,这是配置问题。您可能必须为 mojo 设置一个项目,并使其依赖于所有其他项目。或者,您可以通过使其依赖于所有其他子项目来强制其中一个子项目位于最后。