diff --git a/core/src/main/java/hudson/maven/MavenBuild.java b/core/src/main/java/hudson/maven/MavenBuild.java index c183ff3a42dedfe3fef236c81b63dc61e595e591..a99fd548353976ccb59921894a910c5dcabb583f 100644 --- a/core/src/main/java/hudson/maven/MavenBuild.java +++ b/core/src/main/java/hudson/maven/MavenBuild.java @@ -9,6 +9,7 @@ import hudson.remoting.VirtualChannel; import hudson.remoting.Channel; import hudson.util.IOException2; import hudson.FilePath; +import hudson.maven.PluginManagerInterceptor.AbortException; import org.apache.maven.BuildFailureException; import org.apache.maven.plugin.PluginManager; import org.apache.maven.embedder.MavenEmbedderException; @@ -80,9 +81,10 @@ public class MavenBuild extends AbstractBuild { EventMonitor eventMonitor = new DefaultEventMonitor( new PlexusLoggerAdapter( new EmbedderLoggerImpl(listener) ) ); MavenProject p = embedder.readProject(pom); + PluginManagerInterceptor interceptor; try { - PluginManagerInterceptor interceptor = (PluginManagerInterceptor)embedder.getContainer().lookup(PluginManager.class.getName()); + interceptor = (PluginManagerInterceptor)embedder.getContainer().lookup(PluginManager.class.getName()); interceptor.setBuilder(buildProxy,reporters,listener); } catch (ComponentLookupException e) { throw new Error(e); // impossible @@ -97,6 +99,8 @@ public class MavenBuild extends AbstractBuild { new TransferListenerImpl(listener), null, // TODO: allow additional properties to be specified pom.getParentFile()); + + interceptor.fireLeaveModule(); } finally { for (MavenReporter r : reporters) r.postBuild(buildProxy,p,listener); @@ -115,6 +119,9 @@ public class MavenBuild extends AbstractBuild { throw new IOException2(e); } catch (DuplicateProjectException e) { throw new IOException2(e); + } catch (AbortException e) { + listener.error("build aborted"); + return Result.FAILURE; } catch (InterruptedException e) { listener.error("build aborted"); return Result.FAILURE; diff --git a/core/src/main/java/hudson/maven/MavenReporter.java b/core/src/main/java/hudson/maven/MavenReporter.java index 5e7394b19a938cbab52d952cab85f9765957d533..4f2ff3101d47ddda36981f644f816042455cf23d 100644 --- a/core/src/main/java/hudson/maven/MavenReporter.java +++ b/core/src/main/java/hudson/maven/MavenReporter.java @@ -52,6 +52,38 @@ public abstract class MavenReporter implements Describable, Exten return true; } + /** + * Called when the build enters a next {@link MavenProject}. + * + *

+ * When the current build is a multi-module reactor build, every time the build + * moves on to the next module, this method will be invoked. + * + *

+ * Note that as of Maven 2.0.4, Maven does not perform any smart optimization + * on the order of goal executions. Therefore, the same module might be entered more than + * once during the build. + * + * @return + * See {@link #preBuild} + * @throws InterruptedException + * See {@link #preBuild} + * @throws IOException + * See {@link #preBuild} + */ + public boolean enterModule(MavenBuildProxy build, MavenProject pom, BuildListener listener) throws InterruptedException, IOException { + return true; + } + + /** + * Called when the build leaves the current {@link MavenProject}. + * + * @see #enterModule + */ + public boolean leaveModule(MavenBuildProxy build, MavenProject pom, BuildListener listener) throws InterruptedException, IOException { + return true; + } + /** * Called before execution of a single mojo. * diff --git a/core/src/main/java/hudson/maven/PluginManagerInterceptor.java b/core/src/main/java/hudson/maven/PluginManagerInterceptor.java index c7beec24a8d108bb754c85d465e9f82f8d4d3c9c..955f82d2d50f0553949b2f263e9e4fc0a5679c92 100644 --- a/core/src/main/java/hudson/maven/PluginManagerInterceptor.java +++ b/core/src/main/java/hudson/maven/PluginManagerInterceptor.java @@ -39,6 +39,11 @@ public class PluginManagerInterceptor extends DefaultPluginManager { private MavenReporter[] reporters; private BuildListener listener; + /** + * Used to detect when to fire {@link MavenReporter#enterModule} + */ + private MavenProject lastModule; + public PluginManagerInterceptor() { try { this.mergeMojoConfiguration = DefaultPluginManager.class.getDeclaredMethod( @@ -99,8 +104,13 @@ public class PluginManagerInterceptor extends DefaultPluginManager { project, session.getExecutionProperties() ); - try { + if(lastModule!=project) { + // module change + fireLeaveModule(); + fireEnterModule(project); + } + MojoInfo info = new MojoInfo(mojoExecution, mergedConfiguration, eval); for (MavenReporter r : reporters) if(!r.preExecute(buildProxy,project,info,listener)) @@ -118,6 +128,21 @@ public class PluginManagerInterceptor extends DefaultPluginManager { } } + private void fireEnterModule(MavenProject project) throws InterruptedException, IOException, AbortException { + lastModule = project; + for (MavenReporter r : reporters) + if(!r.enterModule(buildProxy,project,listener)) + throw new AbortException(r+" failed"); + } + + /*package*/ void fireLeaveModule() throws InterruptedException, IOException, AbortException { + if(lastModule!=null) { + for (MavenReporter r : reporters) + if(!r.leaveModule(buildProxy,lastModule,listener)) + throw new AbortException(r+" failed"); + } + } + private Xpp3Dom getConfigDom(MojoExecution mojoExecution, MavenProject project) { MojoDescriptor mojoDescriptor = mojoExecution.getMojoDescriptor(); PluginDescriptor pluginDescriptor = mojoDescriptor.getPluginDescriptor();