2008-09-25 10 views
10

Tengo un MOJO que me gustaría ejecutar una vez, y una vez después de la fase de prueba del último proyecto en el reactor para ejecutar.¿Cómo fuerza a un maven MOJO a ejecutarse solo una vez al final de una compilación?

Usando:

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

al comienzo del método execute() significa que mi mojo es ejecutado una vez, sin embargo, en el comienzo de la construcción - antes de todos los demás módulos del niño.

+0

Déjame asegurarme de que te entendemos. Tienes un proyecto principal y algunos hijos. Desea que este mojo se ejecute después de la prueba en el último proyecto secundario. ¿Derecha? – sblundy

+0

Además, ¿necesita garantizar que funcione? – sblundy

+0

~ 9 años después ... para Maven 3x vea @Konrad Windszus respuesta re: 'org.apache.maven.AbstractMavenLifecycleParticipant' – earcam

Respuesta

-1

Normalmente, esto es una cuestión de configuración. Es posible que deba configurar un proyecto solo para el mojo y hacerlo dependiente de todos los otros proyectos. O bien, podría forzar que uno de los proyectos secundarios sea el último al hacerlo dependiente de todos los otros niños.

1

creo que podría obtener lo que necesita si se utiliza el @aggregator etiqueta y se unen a su mojo una de las siguientes fases del ciclo de vida:

  • preparar paquete
  • paquete
  • pre -integración prueba
  • la integración de la prueba
  • posterior a la integración de la prueba
  • verificar
  • instalación
  • desplegar
+0

Eso puede funcionar, sin embargo, el MOJO debe ejecutarse después de la fase de prueba. ie: mvn test debe ejecutar todas las pruebas en todos los submódulos y luego ejecutar el MOJO de la raíz de ejecución. – npellow

+0

Además, tenga cuidado con @aggregator cuando se enlace a las fases del ciclo de vida. "Cuando se une a un ciclo de vida, un agregador mojo puede tener algunos efectos secundarios desagradables. Puede forzar la ejecución de la ... fase del ciclo de vida para ejecutarse antes de tiempo, y puede dar como resultado compilaciones que terminan ejecutando la ... fase dos veces." [ref] (http://www.sonatype.com/books/mvnref-book/reference/assemblies-sect-basics.html) – seanf

+0

+1 Tu respuesta en realidad me ahorró mucho tiempo. Gracias por mencionar la etiqueta @aggregator. –

8

La mejor solución que he encontrado para esto es:

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

Esto parece funcionar en las pequeñas jerarquías de construcción que he probado con.

+0

+1 Esto realmente funciona, pero parece una solución para mí. Mojo todavía se ejecuta para cada proyecto que se informa por maven. Es un pequeño detalle cuando tienes 5 proyectos, pero se convierte en un defecto cuando tienes muchos. –

2

Hay un Sonatype blog entry que describe cómo hacerlo. El último proyecto que se ejecutará será el proyecto raíz, ya que contendrá referencias de módulos al resto. Thereforec necesita una prueba en su mojo para comprobar si el directorio del proyecto actual es el mismo que el directorio desde donde se lanzó Maven:

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

En la entrada de referencia no es un ejemplo bastante completa de cómo utilizar esto en tu mojo

0

Salida maven-monitor API

Se puede añadir una EventMonitor al despachador, y luego atrapar el final del evento 'reactor de ejecutar': esto se distribuye después de todo lo que se ha completado, es decir, incluso después de ver la creación satisfactoria/FALLA salida.

Así es como he usado recientemente para imprimir un resumen justo al final:

/** 
* 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() 
{ 
    ... 
} 
+0

Obtengo un puntero nulo cuando llamo a session.getEventDispatcher() – h3xStream

1

La solución con el uso de session.getEventDispatcher() ya no funciona desde Maven 3.x.Todo el concurso completo se ha eliminado en este commit: https://github.com/apache/maven/commit/505423e666b9a8814e1c1aa5d50f4e73b8d710f4

+0

Upvoted pero esta no es una respuesta - debe ser un comentario o una edición o una respuesta de @Konrad Windszus (que es lo que he estado tratando de encontrar durante años y válido en Maven 3.5.0) – earcam

Cuestiones relacionadas