o Introduced listener to track lifecycle events

git-svn-id: https://svn.apache.org/repos/asf/maven/components/trunk@804940 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Benjamin Bentmann 2009-08-17 11:28:24 +00:00
parent 7f02ae07d2
commit b5cdb0dc74
10 changed files with 629 additions and 43 deletions

View File

@ -23,6 +23,7 @@ import java.util.Properties;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.RepositoryCache;
import org.apache.maven.lifecycle.LifecycleListener;
import org.apache.maven.model.Profile;
import org.apache.maven.project.DefaultProjectBuildingRequest;
import org.apache.maven.project.ProjectBuildingRequest;
@ -118,6 +119,8 @@ public class DefaultMavenExecutionRequest
private List<ArtifactRepository> pluginArtifactRepositories;
private List<LifecycleListener> lifecycleListeners;
/**
* Suppress SNAPSHOT updates.
*
@ -161,6 +164,7 @@ public class DefaultMavenExecutionRequest
copy.setPluginArtifactRepositories( original.getPluginArtifactRepositories() );
copy.setRepositoryCache( original.getRepositoryCache() );
copy.setNoSnapshotUpdates( original.isNoSnapshotUpdates() );
copy.setLifecycleListeners( original.getLifecycleListeners() );
return original;
}
@ -941,4 +945,28 @@ public class DefaultMavenExecutionRequest
return this;
}
public List<LifecycleListener> getLifecycleListeners()
{
if ( lifecycleListeners == null )
{
lifecycleListeners = new ArrayList<LifecycleListener>();
}
return lifecycleListeners;
}
public MavenExecutionRequest setLifecycleListeners( List<LifecycleListener> lifecycleListeners )
{
if ( lifecycleListeners != null )
{
this.lifecycleListeners = new ArrayList<LifecycleListener>( lifecycleListeners );
}
else
{
this.lifecycleListeners = null;
}
return this;
}
}

View File

@ -27,6 +27,7 @@ import java.util.Properties;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.RepositoryCache;
import org.apache.maven.lifecycle.LifecycleListener;
import org.apache.maven.model.Profile;
import org.apache.maven.project.ProjectBuildingRequest;
import org.apache.maven.settings.Settings;
@ -263,5 +264,9 @@ public interface MavenExecutionRequest
File getUserToolchainsFile();
MavenExecutionRequest setUserToolchainsFile( File userToolchainsFile );
List<LifecycleListener> getLifecycleListeners();
MavenExecutionRequest setLifecycleListeners( List<LifecycleListener> lifecycleListeners );
ProjectBuildingRequest getProjectBuildingRequest();
}

View File

@ -0,0 +1,96 @@
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Provides a skeleton implementation for lifecycle listeners. The methods of this class are empty.
*
* @author Benjamin Bentmann
*/
public class AbstractLifecycleListener
implements LifecycleListener
{
public void sessionStarted( LifecycleEvent event )
{
// default does nothing
}
public void sessionEnded( LifecycleEvent event )
{
// default does nothing
}
public void projectSkipped( LifecycleEvent event )
{
// default does nothing
}
public void projectStarted( LifecycleEvent event )
{
// default does nothing
}
public void projectSucceeded( LifecycleEvent event )
{
// default does nothing
}
public void projectFailed( LifecycleEvent event )
{
// default does nothing
}
public void forkStarted( LifecycleEvent event )
{
// default does nothing
}
public void forkSucceeded( LifecycleEvent event )
{
// default does nothing
}
public void forkFailed( LifecycleEvent event )
{
// default does nothing
}
public void mojoSkipped( LifecycleEvent event )
{
// default does nothing
}
public void mojoStarted( LifecycleEvent event )
{
// default does nothing
}
public void mojoSucceeded( LifecycleEvent event )
{
// default does nothing
}
public void mojoFailed( LifecycleEvent event )
{
// default does nothing
}
}

View File

@ -0,0 +1,60 @@
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
/**
* Holds data relevant for a lifecycle event.
*
* @author Benjamin Bentmann
*/
class DefaultLifecycleEvent
implements LifecycleEvent
{
private final MavenSession session;
private final MojoExecution mojoExecution;
public DefaultLifecycleEvent( MavenSession session, MojoExecution mojoExecution )
{
this.session = session;
this.mojoExecution = mojoExecution;
}
public MavenSession getSession()
{
return session;
}
public MavenProject getProject()
{
return session.getCurrentProject();
}
public MojoExecution getMojoExecution()
{
return mojoExecution;
}
}

View File

@ -1,4 +1,4 @@
package org.apache.maven.lifecycle;
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license
@ -122,10 +122,26 @@ public class DefaultLifecycleExecutor
*/
@Requirement
private Map<String, LifecycleMapping> lifecycleMappings;
private void fireEvent( MavenSession session, MojoExecution mojoExecution, LifecycleEventCatapult catapult )
{
List<LifecycleListener> listeners = session.getRequest().getLifecycleListeners();
if ( !listeners.isEmpty() )
{
LifecycleEvent event = new DefaultLifecycleEvent( session, mojoExecution );
for ( LifecycleListener listener : listeners )
{
catapult.fire( listener, event );
}
}
}
public void execute( MavenSession session )
{
// TODO: Use a listener here instead of loggers
fireEvent( session, null, LifecycleEventCatapult.SESSION_STARTED );
logger.info( "Build Order:" );
@ -160,22 +176,26 @@ public class DefaultLifecycleExecutor
for ( MavenProject currentProject : session.getProjects() )
{
if ( session.isBlackListed( currentProject ) )
{
logger.info( "Skipping " + currentProject.getName() );
logger.info( "This project has been banned from the build due to previous failures." );
continue;
}
logger.info( "Building " + currentProject.getName() );
long buildStartTime = System.currentTimeMillis();
try
{
session.setCurrentProject( currentProject );
if ( session.isBlackListed( currentProject ) )
{
fireEvent( session, null, LifecycleEventCatapult.PROJECT_SKIPPED );
logger.info( "Skipping " + currentProject.getName() );
logger.info( "This project has been banned from the build due to previous failures." );
continue;
}
fireEvent( session, null, LifecycleEventCatapult.PROJECT_STARTED );
logger.info( "Building " + currentProject.getName() );
repositoryRequest.setRemoteRepositories( currentProject.getPluginArtifactRepositories() );
populateDefaultConfigurationForPlugins( currentProject.getBuild().getPlugins(), repositoryRequest );
@ -219,6 +239,8 @@ public class DefaultLifecycleExecutor
long buildEndTime = System.currentTimeMillis();
result.addBuildSummary( new BuildSuccess( currentProject, buildEndTime - buildStartTime ) );
fireEvent( session, null, LifecycleEventCatapult.PROJECT_SUCCEEDED );
}
catch ( Exception e )
{
@ -228,6 +250,8 @@ public class DefaultLifecycleExecutor
result.addBuildSummary( new BuildFailure( currentProject, buildEndTime - buildStartTime, e ) );
fireEvent( session, null, LifecycleEventCatapult.PROJECT_FAILED );
if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( session.getReactorFailureBehavior() ) )
{
// continue the build
@ -254,8 +278,10 @@ public class DefaultLifecycleExecutor
Thread.currentThread().setContextClassLoader( oldContextClassLoader );
}
}
}
}
fireEvent( session, null, LifecycleEventCatapult.SESSION_ENDED );
}
private void execute( MavenProject project, MavenSession session, MojoExecution mojoExecution )
throws MojoFailureException, MojoExecutionException, PluginConfigurationException, PluginManagerException
@ -271,6 +297,8 @@ public class DefaultLifecycleExecutor
}
else
{
fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_SKIPPED );
logger.warn( "Goal " + mojoDescriptor.getGoal()
+ " requires online mode for execution but Maven is currently offline, skipping" );
return;
@ -283,37 +311,99 @@ public class DefaultLifecycleExecutor
if ( !forkedExecutions.isEmpty() )
{
if ( logger.isDebugEnabled() )
{
logger.debug( "Forking execution for " + mojoDescriptor.getId() );
}
fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_STARTED );
executionProject = project.clone();
session.setCurrentProject( executionProject );
try
{
for ( MojoExecution forkedExecution : forkedExecutions )
if ( logger.isDebugEnabled() )
{
execute( executionProject, session, forkedExecution );
logger.debug( "Forking execution for " + mojoDescriptor.getId() );
}
executionProject = project.clone();
session.setCurrentProject( executionProject );
try
{
for ( MojoExecution forkedExecution : forkedExecutions )
{
execute( executionProject, session, forkedExecution );
}
}
finally
{
session.setCurrentProject( project );
}
fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_SUCCEEDED );
if ( logger.isDebugEnabled() )
{
logger.debug( "Completed forked execution for " + mojoDescriptor.getId() );
}
}
finally
catch ( MojoFailureException e )
{
session.setCurrentProject( project );
}
fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED );
if ( logger.isDebugEnabled() )
throw e;
}
catch ( MojoExecutionException e )
{
logger.debug( "Completed forked execution for " + mojoDescriptor.getId() );
fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED );
throw e;
}
catch ( PluginConfigurationException e )
{
fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED );
throw e;
}
catch ( PluginManagerException e )
{
fireEvent( session, mojoExecution, LifecycleEventCatapult.FORK_FAILED );
throw e;
}
}
project.setExecutionProject( executionProject );
fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_STARTED );
logger.info( executionDescription( mojoExecution, project ) );
try
{
project.setExecutionProject( executionProject );
pluginManager.executeMojo( session, mojoExecution );
logger.info( executionDescription( mojoExecution, project ) );
pluginManager.executeMojo( session, mojoExecution );
fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_SUCCEEDED );
}
catch ( MojoFailureException e )
{
fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED );
throw e;
}
catch ( MojoExecutionException e )
{
fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED );
throw e;
}
catch ( PluginConfigurationException e )
{
fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED );
throw e;
}
catch ( PluginManagerException e )
{
fireEvent( session, mojoExecution, LifecycleEventCatapult.MOJO_FAILED );
throw e;
}
}
public MavenExecutionPlan calculateExecutionPlan( MavenSession session, String... tasks )
@ -377,7 +467,8 @@ public class DefaultLifecycleExecutor
}
return new MavenExecutionPlan( lifecyclePlan, requiredDependencyResolutionScopes );
}
}
private RepositoryRequest getRepositoryRequest( MavenSession session, MavenProject project )
{
RepositoryRequest request = new DefaultRepositoryRequest();
@ -1074,7 +1165,7 @@ public class DefaultLifecycleExecutor
lifecycleMap.put( lifecycle.getId(), lifecycle );
}
}
}
// These methods deal with construction intact Plugin object that look like they come from a standard
// <plugin/> block in a Maven POM. We have to do some wiggling to pull the sources of information
@ -1125,11 +1216,11 @@ public class DefaultLifecycleExecutor
{
parseLifecyclePhaseDefinitions( plugins, null, goals );
}
}
}
}
return plugins.keySet();
}
}
private void parseLifecyclePhaseDefinitions( Map<Plugin, Plugin> plugins, String phase, String goals )
{
@ -1198,7 +1289,7 @@ public class DefaultLifecycleExecutor
{
populateDefaultConfigurationForPlugin( plugin, repositoryRequest );
}
}
}
private Xpp3Dom getDefaultPluginConfiguration( Plugin plugin, String goal, RepositoryRequest repositoryRequest )
throws LifecycleExecutionException
@ -1232,7 +1323,7 @@ public class DefaultLifecycleExecutor
catch ( InvalidPluginDescriptorException e )
{
throw new LifecycleExecutionException( "Error getting default plugin information for " + plugin.getId(), e );
}
}
return getMojoConfiguration( mojoDescriptor );
}
@ -1335,7 +1426,7 @@ public class DefaultLifecycleExecutor
if ( plugin != null )
{
return plugin;
}
}
}
}
@ -1362,7 +1453,7 @@ public class DefaultLifecycleExecutor
if ( plugin != null )
{
return plugin;
}
}
}
catch ( TransferFailedException e )
{
@ -1374,10 +1465,10 @@ public class DefaultLifecycleExecutor
}
}
}
}
throw new NoPluginFoundForPrefixException( prefix, session.getLocalRepository(), session.getCurrentProject().getPluginArtifactRepositories() );
}
}
// Keep track of the repository that provided the prefix mapping
//
@ -1526,7 +1617,7 @@ public class DefaultLifecycleExecutor
}
}
}
}
}
private void checkRequiredParameters( MojoDescriptor goal, PlexusConfiguration configuration, ExpressionEvaluator expressionEvaluator )
throws PluginConfigurationException
@ -1646,7 +1737,7 @@ public class DefaultLifecycleExecutor
}
}
}
}
}
*/
}

View File

@ -0,0 +1,55 @@
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
/**
* Holds data relevant for a lifecycle event.
*
* @author Benjamin Bentmann
*/
public interface LifecycleEvent
{
/**
* Gets the session from which this event originates.
*
* @return The current session, never {@code null}.
*/
MavenSession getSession();
/**
* Gets the current project (if any).
*
* @return The current project or {@code null} if not applicable.
*/
MavenProject getProject();
/**
* Gets the current mojo execution (if any).
*
* @return The current mojo execution or {@code null} if not applicable.
*/
MojoExecution getMojoExecution();
}

View File

@ -0,0 +1,143 @@
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Assists in firing events from a generic method by abstracting from the actual callback method to be called on the
* listener.
*
* @author Benjamin Bentmann
*/
interface LifecycleEventCatapult
{
/**
* Notifies the specified listener of the given event.
*
* @param listener The listener to notify, must not be {@code null}.
* @param event The event to fire, must not be {@code null}.
*/
void fire( LifecycleListener listener, LifecycleEvent event );
static final LifecycleEventCatapult SESSION_STARTED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.sessionStarted( event );
}
};
static final LifecycleEventCatapult SESSION_ENDED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.sessionEnded( event );
}
};
static final LifecycleEventCatapult PROJECT_SKIPPED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.projectSkipped( event );
}
};
static final LifecycleEventCatapult PROJECT_STARTED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.projectStarted( event );
}
};
static final LifecycleEventCatapult PROJECT_SUCCEEDED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.projectSucceeded( event );
}
};
static final LifecycleEventCatapult PROJECT_FAILED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.projectFailed( event );
}
};
static final LifecycleEventCatapult MOJO_SKIPPED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.mojoSkipped( event );
}
};
static final LifecycleEventCatapult MOJO_STARTED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.mojoStarted( event );
}
};
static final LifecycleEventCatapult MOJO_SUCCEEDED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.mojoSucceeded( event );
}
};
static final LifecycleEventCatapult MOJO_FAILED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.mojoFailed( event );
}
};
static final LifecycleEventCatapult FORK_STARTED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.forkStarted( event );
}
};
static final LifecycleEventCatapult FORK_SUCCEEDED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.forkSucceeded( event );
}
};
static final LifecycleEventCatapult FORK_FAILED = new LifecycleEventCatapult()
{
public void fire( LifecycleListener listener, LifecycleEvent event )
{
listener.forkFailed( event );
}
};
}

View File

@ -0,0 +1,56 @@
package org.apache.maven.lifecycle;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* Defines events that the lifecycle executor fires during a session.
*
* @author Benjamin Bentmann
*/
public interface LifecycleListener
{
void sessionStarted( LifecycleEvent event );
void sessionEnded( LifecycleEvent event );
void projectSkipped( LifecycleEvent event );
void projectStarted( LifecycleEvent event );
void projectSucceeded( LifecycleEvent event );
void projectFailed( LifecycleEvent event );
void mojoSkipped( LifecycleEvent event );
void mojoStarted( LifecycleEvent event );
void mojoSucceeded( LifecycleEvent event );
void mojoFailed( LifecycleEvent event );
void forkStarted( LifecycleEvent event );
void forkSucceeded( LifecycleEvent event );
void forkFailed( LifecycleEvent event );
}

View File

@ -0,0 +1,48 @@
package org.apache.maven.cli;
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import org.apache.maven.embedder.MavenEmbedderLogger;
import org.apache.maven.lifecycle.AbstractLifecycleListener;
/**
* Logs lifecycle events to a user-supplied logger.
*
* @author Benjamin Bentmann
*/
class LifecycleEventLogger
extends AbstractLifecycleListener
{
private final MavenEmbedderLogger logger;
public LifecycleEventLogger( MavenEmbedderLogger logger )
{
if ( logger == null )
{
throw new IllegalArgumentException( "logger missing" );
}
this.logger = logger;
}
// TODO: log the events
}

View File

@ -16,6 +16,7 @@ package org.apache.maven.cli;
*/
import java.io.File;
import java.util.Arrays;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
@ -30,6 +31,7 @@ import org.apache.maven.embedder.MavenEmbedderLogger;
import org.apache.maven.exception.ExceptionSummary;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenExecutionResult;
import org.apache.maven.lifecycle.LifecycleListener;
import org.codehaus.plexus.classworlds.ClassWorld;
import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
@ -120,6 +122,8 @@ public class MavenCli
MavenEmbedderLogger logger = configuration.getMavenEmbedderLogger();
request.setLifecycleListeners( Arrays.<LifecycleListener> asList( new LifecycleEventLogger( logger ) ) );
if ( debug || commandLine.hasOption( CLIManager.SHOW_VERSION ) )
{
CLIReportingUtils.showVersion();