如何强制 Maven MOJO 在构建结束时仅执行一次?

发布于 2024-07-07 05:28:19 字数 212 浏览 10 评论 0原文

我有一个 MOJO,我想执行一次,并且仅在反应堆中运行的最后一个项目的测试阶段之后执行一次。

使用:

if (!getProject().isExecutionRoot()) {
        return ;
}

在execute()方法的开始意味着我的mojo被执行一次,但是在构建的一开始——在所有其他子模块之前。

I have a MOJO I would like executed once, and once only after the test phase of the last project in the reactor to run.

Using:

if (!getProject().isExecutionRoot()) {
        return ;
}

at the start of the execute() method means my mojo gets executed once, however at the very beginning of the build - before all other child modules.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

莫多说 2024-07-14 05:28:19

我为此找到的最佳解决方案是:

/**
 * 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
   ...
}

这似乎适用于我测试过的小型构建层次结构。

The best solution I have found for this is:

/**
 * 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
   ...
}

This appears to work on the small build hierarchies I've tested with.

清风疏影 2024-07-14 05:28:19

最好的解决方案是通过从 org.apache.maven.AbstractMavenLifecycleParticipant 扩展类来依赖生命周期扩展(另请参阅https://maven.apache.org/examples/maven-3-lifecycle-extensions.html) 得到了一个方法 afterSessionEnd 添加 https://issues.apache.org/jira/browse/MNG-5640 (在 Maven 3.2.2 中修复)。

The best solution is relying on a lifecycle extension by extending your class from org.apache.maven.AbstractMavenLifecycleParticipant (see also https://maven.apache.org/examples/maven-3-lifecycle-extensions.html) which got a method afterSessionEnd added with https://issues.apache.org/jira/browse/MNG-5640 (fixed in Maven 3.2.2).

爱*していゐ 2024-07-14 05:28:19

有一个 Sonatype 博客条目 描述了如何执行此操作。 最后运行的项目将是根项目,因为它将包含对其余项目的模块引用。 因此,您需要在 mojo 中进行测试,以检查当前项目的目录是否与启动 Maven 的目录相同:

boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());

在引用的条目中,有一个非常全面的示例,说明如何在 mojo 中使用它。

There is a Sonatype blog entry that describes how to do this. The last project to be run will be the root project as it will contain module references to the rest. Thereforec you need a test in your mojo to check if the current project's directory is the same as the directory from where Maven was launched:

boolean result = mavenSession.getExecutionRootDirectory().equalsIgnoreCase(basedir.toString());

In the referenced entry there is a pretty comprehensive example of how to use this in your mojo.

清秋悲枫 2024-07-14 05:28:19

我认为如果您使用 @aggregator 标签并将您的 mojo 绑定到以下生命周期阶段之一,您可能会得到您需要的东西:

  • 准备包包
  • 集成-测试
  • 集成-测试
  • 集成后-测试
  • 验证
  • 安装
  • 部署

I think you might get what you need if you use the @aggregator tag and bind your mojo to one of the following lifecycle phases:

  • prepare-package
  • package
  • pre-integration-test
  • integration-test
  • post-integration-test
  • verify
  • install
  • deploy
难理解 2024-07-14 05:28:19

从 Maven 3.x 开始,使用 session.getEventDispatcher() 的解决方案不再有效。 整个事件已在此提交中删除: https://github.com/apache/maven/commit /505423e666b9a8814e1c1aa5d50f4e73b8d710f4

The solution with using session.getEventDispatcher() no longer works since Maven 3.x. The whole eventing has been removed in this commit: https://github.com/apache/maven/commit/505423e666b9a8814e1c1aa5d50f4e73b8d710f4

眸中客 2024-07-14 05:28:19

查看 maven-monitor API

您可以将 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()
{
    ...
}

Check out maven-monitor API

You can add an EventMonitor to the dispatcher, and then trap the END of the 'reactor-execute' event: this is dispatched after everything is completed, i.e. even after you see the BUILD SUCCESSFUL/FAILED output.

Here's how I used it recently to print a summary right at the end:

/**
 * 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()
{
    ...
}
痴骨ら 2024-07-14 05:28:19

你可以使用mavensession来解决这个问题

public boolean isThisTheLastProject() {
        return session.getProjectDependencyGraph().getSortedProjects().
                get(session.getProjectDependencyGraph().getSortedProjects().size()-1).getArtifactId().equalsIgnoreCase(project.getArtifactId());
    }

you can use mavensession to solve this

public boolean isThisTheLastProject() {
        return session.getProjectDependencyGraph().getSortedProjects().
                get(session.getProjectDependencyGraph().getSortedProjects().size()-1).getArtifactId().equalsIgnoreCase(project.getArtifactId());
    }
小霸王臭丫头 2024-07-14 05:28:19

通常,这是配置问题。 您可能必须只为 mojo 设置一个项目,并使其依赖于所有其他项目。 或者,您可以通过使其依赖于所有其他子项目来强制其中一个子项目成为最后一个。

Normally, this is a matter of configuration. You might have to setup a project just for the mojo and make it dependent on all of the other projects. Or you could force one of the child projects to be last by making it dependent on all of the other children.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文