| package org.apache.maven; |
| |
| /* |
| * 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 java.io.File; |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.text.DateFormat; |
| import java.text.SimpleDateFormat; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Date; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Properties; |
| import java.util.Set; |
| import java.util.TimeZone; |
| |
| import org.apache.maven.artifact.manager.DefaultWagonManager; |
| import org.apache.maven.artifact.manager.WagonManager; |
| import org.apache.maven.artifact.manager.WagonProviderMapping; |
| import org.apache.maven.artifact.repository.ArtifactRepository; |
| import org.apache.maven.artifact.resolver.ArtifactResolutionException; |
| import org.apache.maven.artifact.resolver.ArtifactResolver; |
| import org.apache.maven.artifact.resolver.DefaultArtifactResolver; |
| import org.apache.maven.artifact.versioning.ArtifactVersion; |
| import org.apache.maven.artifact.versioning.DefaultArtifactVersion; |
| import org.apache.maven.execution.BuildFailure; |
| import org.apache.maven.execution.DefaultMavenExecutionRequest; |
| import org.apache.maven.execution.MavenExecutionRequest; |
| import org.apache.maven.execution.MavenSession; |
| import org.apache.maven.execution.ReactorManager; |
| import org.apache.maven.execution.RuntimeInformation; |
| import org.apache.maven.lifecycle.LifecycleExecutionException; |
| import org.apache.maven.lifecycle.LifecycleExecutor; |
| import org.apache.maven.model.Profile; |
| import org.apache.maven.monitor.event.DefaultEventDispatcher; |
| import org.apache.maven.monitor.event.EventDispatcher; |
| import org.apache.maven.monitor.event.MavenEvents; |
| import org.apache.maven.profiles.ProfileManager; |
| import org.apache.maven.profiles.activation.ProfileActivationException; |
| import org.apache.maven.project.DuplicateProjectException; |
| import org.apache.maven.project.MavenProject; |
| import org.apache.maven.project.MavenProjectBuilder; |
| import org.apache.maven.project.MissingProjectException; |
| import org.apache.maven.project.ProjectBuildingException; |
| import org.apache.maven.project.artifact.MavenMetadataSource; |
| import org.apache.maven.reactor.MavenExecutionException; |
| import org.apache.maven.settings.Mirror; |
| import org.apache.maven.settings.Proxy; |
| import org.apache.maven.settings.Server; |
| import org.apache.maven.settings.Settings; |
| import org.apache.maven.usability.SystemWarnings; |
| import org.apache.maven.usability.diagnostics.ErrorDiagnostics; |
| import org.codehaus.plexus.PlexusConstants; |
| import org.codehaus.plexus.PlexusContainer; |
| import org.codehaus.plexus.component.repository.exception.ComponentLifecycleException; |
| import org.codehaus.plexus.component.repository.exception.ComponentLookupException; |
| import org.codehaus.plexus.context.Context; |
| import org.codehaus.plexus.context.ContextException; |
| import org.codehaus.plexus.logging.AbstractLogEnabled; |
| import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable; |
| import org.codehaus.plexus.util.FileUtils; |
| import org.codehaus.plexus.util.Os; |
| import org.codehaus.plexus.util.StringUtils; |
| import org.codehaus.plexus.util.dag.CycleDetectedException; |
| import org.codehaus.plexus.util.xml.Xpp3Dom; |
| import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher; |
| import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException; |
| |
| /** |
| * @author <a href="mailto:jason@maven.org">Jason van Zyl </a> |
| * @version $Id$ |
| */ |
| public class DefaultMaven |
| extends AbstractLogEnabled |
| implements Maven, Contextualizable |
| { |
| // ---------------------------------------------------------------------- |
| // Components |
| // ---------------------------------------------------------------------- |
| |
| protected MavenProjectBuilder projectBuilder; |
| |
| protected LifecycleExecutor lifecycleExecutor; |
| |
| protected PlexusContainer container; |
| |
| protected ErrorDiagnostics errorDiagnostics; |
| |
| protected RuntimeInformation runtimeInformation; |
| |
| protected MavenMetadataSource mavenMetadataSource; |
| |
| private static final long MB = 1024 * 1024; |
| |
| private static final int MS_PER_SEC = 1000; |
| |
| private static final int SEC_PER_MIN = 60; |
| |
| // ---------------------------------------------------------------------- |
| // Project execution |
| // ---------------------------------------------------------------------- |
| |
| public void execute( MavenExecutionRequest request ) |
| throws MavenExecutionException |
| { |
| // if ( request.getLocalRepository() == null ) |
| // { |
| // request.setLocalRepository( mavenTools.createLocalRepository( request.getLocalRepositoryPath() ) ); |
| // } |
| |
| EventDispatcher dispatcher = request.getEventDispatcher(); |
| |
| String event = MavenEvents.REACTOR_EXECUTION; |
| |
| dispatcher.dispatchStart( event, request.getBaseDirectory() ); |
| |
| ReactorManager rm; |
| try |
| { |
| rm = doExecute( request, dispatcher ); |
| } |
| catch ( LifecycleExecutionException e ) |
| { |
| dispatcher.dispatchError( event, request.getBaseDirectory(), e ); |
| |
| logError( e, request.isShowErrors() ); |
| |
| stats( request.getStartTime() ); |
| |
| line(); |
| |
| throw new MavenExecutionException( e.getMessage(), e ); |
| } |
| catch ( BuildFailureException e ) |
| { |
| dispatcher.dispatchError( event, request.getBaseDirectory(), e ); |
| |
| logFailure( e, request.isShowErrors() ); |
| |
| stats( request.getStartTime() ); |
| |
| line(); |
| |
| throw new MavenExecutionException( e.getMessage(), e ); |
| } |
| catch ( Throwable t ) |
| { |
| dispatcher.dispatchError( event, request.getBaseDirectory(), t ); |
| |
| logFatal( t ); |
| |
| stats( request.getStartTime() ); |
| |
| line(); |
| |
| throw new MavenExecutionException( "Error executing project within the reactor", t ); |
| } |
| |
| // Either the build was successful, or it was a fail_at_end/fail_never reactor build |
| |
| // TODO: should all the logging be left to the CLI? |
| logReactorSummary( rm ); |
| |
| if ( rm.hasBuildFailures() ) |
| { |
| logErrors( rm, request.isShowErrors() ); |
| |
| if ( !ReactorManager.FAIL_NEVER.equals( rm.getFailureBehavior() ) ) |
| { |
| dispatcher.dispatchError( event, request.getBaseDirectory(), null ); |
| |
| getLogger().info( "BUILD ERRORS" ); |
| |
| line(); |
| |
| stats( request.getStartTime() ); |
| |
| line(); |
| |
| throw new MavenExecutionException( "Some builds failed" ); |
| } |
| else |
| { |
| getLogger().info( " + Ignoring failures" ); |
| } |
| } |
| |
| logSuccess( rm ); |
| |
| stats( request.getStartTime() ); |
| |
| line(); |
| |
| dispatcher.dispatchEnd( event, request.getBaseDirectory() ); |
| } |
| |
| private void logErrors( ReactorManager rm, boolean showErrors ) |
| { |
| for ( Iterator it = rm.getSortedProjects().iterator(); it.hasNext(); ) |
| { |
| MavenProject project = (MavenProject) it.next(); |
| |
| if ( rm.hasBuildFailure( project ) ) |
| { |
| BuildFailure buildFailure = rm.getBuildFailure( project ); |
| |
| getLogger().info( |
| "Error for project: " + project.getName() + " (during " + buildFailure.getTask() + ")" ); |
| |
| line(); |
| |
| logDiagnostics( buildFailure.getCause() ); |
| |
| logTrace( buildFailure.getCause(), showErrors ); |
| } |
| } |
| |
| if ( !showErrors ) |
| { |
| getLogger().info( "For more information, run Maven with the -e switch" ); |
| |
| line(); |
| } |
| |
| } |
| |
| private ReactorManager doExecute( MavenExecutionRequest request, EventDispatcher dispatcher ) |
| throws MavenExecutionException, BuildFailureException, LifecycleExecutionException |
| { |
| try |
| { |
| resolveParameters( request.getSettings(), request.getExecutionProperties() ); |
| } |
| catch ( ComponentLookupException e ) |
| { |
| throw new MavenExecutionException( "Unable to configure Maven for execution", e ); |
| } |
| catch ( ComponentLifecycleException e ) |
| { |
| throw new MavenExecutionException( "Unable to configure Maven for execution", e ); |
| } |
| catch ( SettingsConfigurationException e ) |
| { |
| throw new MavenExecutionException( "Unable to configure Maven for execution", e ); |
| } |
| |
| ProfileManager globalProfileManager = request.getGlobalProfileManager(); |
| |
| globalProfileManager.loadSettingsProfiles( request.getSettings() ); |
| |
| getLogger().info( "Scanning for projects..." ); |
| |
| request.getProjectBuilderConfiguration() |
| .setMetadataSource( new MavenMetadataSource( mavenMetadataSource, request.getProjectBuilderConfiguration() ) ); |
| |
| boolean foundProjects = true; |
| List projects = getProjects( request ); |
| if ( projects.isEmpty() ) |
| { |
| projects.add( getSuperProject( request ) ); |
| foundProjects = false; |
| } |
| |
| ReactorManager rm; |
| try |
| { |
| String resumeFrom = request.getResumeFrom(); |
| |
| List projectList = request.getSelectedProjects(); |
| |
| String makeBehavior = request.getMakeBehavior(); |
| |
| rm = new ReactorManager( projects, projectList, resumeFrom, makeBehavior ); |
| |
| rm.setFailureBehavior( request.getFailureBehavior() ); |
| |
| } |
| catch ( CycleDetectedException e ) |
| { |
| throw new BuildFailureException( |
| "The projects in the reactor contain a cyclic reference: " + e.getMessage(), e ); |
| } |
| catch ( DuplicateProjectException e ) |
| { |
| throw new BuildFailureException( e.getMessage(), e ); |
| } |
| catch ( MissingProjectException e ) |
| { |
| throw new BuildFailureException( e.getMessage(), e ); |
| } |
| |
| // -------------------------------------------------------------------------------- |
| // MNG-3641: print a warning if one of the profiles to be activated explicitly |
| // was not activated |
| |
| validateActivatedProfiles( globalProfileManager, projects ); |
| |
| if ( rm.hasMultipleProjects() ) |
| { |
| getLogger().info( "Reactor build order: " ); |
| |
| for ( Iterator i = rm.getSortedProjects().iterator(); i.hasNext(); ) |
| { |
| MavenProject project = (MavenProject) i.next(); |
| getLogger().info( " " + project.getName() ); |
| } |
| } |
| |
| MavenSession session = createSession( request, rm ); |
| |
| session.setUsingPOMsFromFilesystem( foundProjects ); |
| |
| lifecycleExecutor.execute( session, rm, dispatcher ); |
| |
| return rm; |
| } |
| |
| private void validateActivatedProfiles( ProfileManager globalProfileManager, List projects ) |
| { |
| if ( globalProfileManager != null ) |
| { |
| // get all activated profile ids |
| Set activeProfileIds = new HashSet(); |
| |
| for ( Iterator i = projects.iterator(); i.hasNext(); ) |
| { |
| MavenProject project = (MavenProject) i.next(); |
| |
| do |
| { |
| for ( Iterator j = project.getActiveProfiles().iterator(); j.hasNext(); ) |
| { |
| activeProfileIds.add( ( (Profile) j.next() ).getId() ); |
| } |
| project = project.getParent(); |
| } |
| while ( project != null ); |
| } |
| |
| for ( Iterator i = globalProfileManager.getExplicitlyActivatedIds().iterator(); i.hasNext(); ) |
| { |
| String explicitProfileId = (String) i.next(); |
| |
| if ( !activeProfileIds.contains( explicitProfileId ) ) |
| { |
| getLogger().warn( "\n\tProfile with id: \'" + explicitProfileId + "\' has not been activated.\n" ); |
| } |
| } |
| } |
| } |
| |
| private MavenProject getSuperProject( MavenExecutionRequest request ) |
| throws MavenExecutionException |
| { |
| MavenProject superProject; |
| try |
| { |
| superProject = projectBuilder.buildStandaloneSuperProject( request.getLocalRepository(), request.getGlobalProfileManager() ); |
| |
| } |
| catch ( ProjectBuildingException e ) |
| { |
| throw new MavenExecutionException( e.getMessage(), e ); |
| } |
| return superProject; |
| } |
| |
| private List getProjects( MavenExecutionRequest request ) |
| throws MavenExecutionException, BuildFailureException |
| { |
| List projects; |
| try |
| { |
| List files = getProjectFiles( request ); |
| |
| projects = collectProjects( files, request, !request.isReactorActive() ); |
| |
| } |
| catch ( IOException e ) |
| { |
| throw new MavenExecutionException( "Error processing projects for the reactor: " + e.getMessage(), e ); |
| } |
| catch ( ArtifactResolutionException e ) |
| { |
| throw new MavenExecutionException( e.getMessage(), e ); |
| } |
| catch ( ProjectBuildingException e ) |
| { |
| throw new MavenExecutionException( e.getMessage(), e ); |
| } |
| catch ( ProfileActivationException e ) |
| { |
| throw new MavenExecutionException( e.getMessage(), e ); |
| } |
| return projects; |
| } |
| |
| private void logReactorSummaryLine( String name, String status ) |
| { |
| logReactorSummaryLine( name, status, -1 ); |
| } |
| |
| private void logReactorSummaryLine( String name, String status, long time ) |
| { |
| StringBuffer messageBuffer = new StringBuffer(); |
| |
| messageBuffer.append( name ); |
| |
| int dotCount = 54; |
| |
| dotCount -= name.length(); |
| |
| messageBuffer.append( " " ); |
| |
| for ( int i = 0; i < dotCount; i++ ) |
| { |
| messageBuffer.append( '.' ); |
| } |
| |
| messageBuffer.append( " " ); |
| |
| messageBuffer.append( status ); |
| |
| if ( time >= 0 ) |
| { |
| messageBuffer.append( " [" ); |
| |
| messageBuffer.append( getFormattedTime( time ) ); |
| |
| messageBuffer.append( "]" ); |
| } |
| |
| getLogger().info( messageBuffer.toString() ); |
| } |
| |
| private static String getFormattedTime( long time ) |
| { |
| String pattern = "s.SSS's'"; |
| if ( time / 60000L > 0 ) |
| { |
| pattern = "m:s" + pattern; |
| if ( time / 3600000L > 0 ) |
| { |
| pattern = "H:m" + pattern; |
| } |
| } |
| DateFormat fmt = new SimpleDateFormat( pattern ); |
| fmt.setTimeZone( TimeZone.getTimeZone( "UTC" ) ); |
| return fmt.format( new Date( time ) ); |
| } |
| |
| private List collectProjects( List files, MavenExecutionRequest request, boolean isRoot ) |
| throws ArtifactResolutionException, ProjectBuildingException, ProfileActivationException, |
| MavenExecutionException, BuildFailureException |
| { |
| // .getLocalRepository(), request.isRecursive(), |
| // request.getSettings(), request.getUserProperties(), requ, !request.isReactorActive() |
| List projects = new ArrayList( files.size() ); |
| |
| for ( Iterator iterator = files.iterator(); iterator.hasNext(); ) |
| { |
| File file = (File) iterator.next(); |
| |
| boolean usingReleasePom = false; |
| |
| if ( RELEASE_POMv4.equals( file.getName() ) ) |
| { |
| getLogger().info( "NOTE: Using release-pom: " + file + " in reactor build." ); |
| usingReleasePom = true; |
| } |
| |
| MavenProject project = getProject( file, request ); |
| |
| if ( isRoot ) |
| { |
| project.setExecutionRoot( true ); |
| } |
| |
| if ( ( project.getPrerequisites() != null ) && ( project.getPrerequisites().getMaven() != null ) ) |
| { |
| DefaultArtifactVersion version = new DefaultArtifactVersion( project.getPrerequisites().getMaven() ); |
| if ( runtimeInformation.getApplicationVersion().compareTo( version ) < 0 ) |
| { |
| throw new BuildFailureException( "Unable to build project '" + project.getFile() + |
| "; it requires Maven version " + version.toString() ); |
| } |
| } |
| |
| if ( ( project.getModules() != null ) && !project.getModules().isEmpty() && request.isRecursive() ) |
| { |
| // TODO: Really should fail if it was not? What if it is aggregating - eg "ear"? |
| project.setPackaging( "pom" ); |
| |
| File basedir = file.getParentFile(); |
| |
| // Initial ordering is as declared in the modules section |
| List moduleFiles = new ArrayList( project.getModules().size() ); |
| for ( Iterator i = project.getModules().iterator(); i.hasNext(); ) |
| { |
| String name = (String) i.next(); |
| |
| if ( StringUtils.isEmpty( StringUtils.trim( name ) ) ) |
| { |
| getLogger().warn( |
| "Empty module detected. Please check you don't have any empty module definitions in your POM." ); |
| |
| continue; |
| } |
| |
| File moduleFile = new File( basedir, name ); |
| |
| if ( moduleFile.exists() && moduleFile.isDirectory() ) |
| { |
| if ( usingReleasePom ) |
| { |
| moduleFile = new File( basedir, name + "/" + Maven.RELEASE_POMv4 ); |
| } |
| else |
| { |
| moduleFile = new File( basedir, name + "/" + Maven.POMv4 ); |
| } |
| } |
| |
| if ( Os.isFamily( "windows" ) ) |
| { |
| // we don't canonicalize on unix to avoid interfering with symlinks |
| |
| try |
| { |
| moduleFile = moduleFile.getCanonicalFile(); |
| } |
| catch ( IOException e ) |
| { |
| throw new MavenExecutionException( "Unable to canonicalize file name " + moduleFile, e ); |
| } |
| } |
| else |
| { |
| moduleFile = new File( moduleFile.toURI().normalize() ); |
| } |
| |
| moduleFiles.add( moduleFile ); |
| } |
| |
| List collectedProjects = |
| collectProjects( moduleFiles, request, false ); |
| projects.addAll( collectedProjects ); |
| project.setCollectedProjects( collectedProjects ); |
| } |
| projects.add( project ); |
| } |
| |
| return projects; |
| } |
| |
| /** |
| * @deprecated Use {@link DefaultMaven#getProject(File, MavenExecutionRequest)} instead. |
| */ |
| public MavenProject getProject( File pom, ArtifactRepository localRepository, Settings settings, |
| Properties userProperties, ProfileManager globalProfileManager ) |
| throws ProjectBuildingException, ArtifactResolutionException, ProfileActivationException |
| { |
| MavenExecutionRequest request = new DefaultMavenExecutionRequest( |
| localRepository, |
| settings, |
| new DefaultEventDispatcher(), |
| Collections.EMPTY_LIST, |
| pom.getParentFile() |
| .getAbsolutePath(), |
| globalProfileManager, |
| globalProfileManager.getRequestProperties(), |
| new Properties(), false ); |
| |
| return getProject( pom, request ); |
| } |
| |
| public MavenProject getProject( File pom, MavenExecutionRequest request ) |
| throws ProjectBuildingException, ArtifactResolutionException, ProfileActivationException |
| { |
| if ( pom.exists() ) |
| { |
| if ( pom.length() == 0 ) |
| { |
| throw new ProjectBuildingException( "unknown", "The file " + pom.getAbsolutePath() + |
| " you specified has zero length." ); |
| } |
| } |
| |
| return projectBuilder.build( pom, request.getProjectBuilderConfiguration() ); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Methods used by all execution request handlers |
| // ---------------------------------------------------------------------- |
| |
| //!! We should probably have the execution request handler create the |
| // session as |
| // the session type would be specific to the request i.e. having a project |
| // or not. |
| |
| protected MavenSession createSession( MavenExecutionRequest request, |
| ReactorManager rpm ) |
| { |
| return new MavenSession( container, request, rpm ); |
| } |
| |
| /** |
| * @todo [BP] this might not be required if there is a better way to pass |
| * them in. It doesn't feel quite right. |
| * @todo [JC] we should at least provide a mapping of protocol-to-proxy for |
| * the wagons, shouldn't we? |
| */ |
| private void resolveParameters( Settings settings, Properties executionProperties ) |
| throws ComponentLookupException, ComponentLifecycleException, SettingsConfigurationException |
| { |
| WagonManager wagonManager = (WagonManager) container.lookup( WagonManager.ROLE ); |
| |
| try |
| { |
| if ( settings.isOffline() ) |
| { |
| getLogger().info( SystemWarnings.getOfflineWarning() ); |
| |
| wagonManager.setOnline( false ); |
| } |
| |
| try |
| { |
| DefaultWagonManager wm = (DefaultWagonManager) wagonManager; |
| |
| String oldUserAgent = wm.getHttpUserAgent(); |
| int firstSpace = oldUserAgent == null ? -1 : oldUserAgent.indexOf( " " ); |
| |
| StringBuffer buffer = new StringBuffer(); |
| |
| buffer.append( "Apache-Maven/" ); |
| |
| ArtifactVersion version = runtimeInformation.getApplicationVersion(); |
| if ( version != null ) |
| { |
| buffer.append( version.getMajorVersion() ); |
| buffer.append( '.' ); |
| buffer.append( version.getMinorVersion() ); |
| } |
| else |
| { |
| buffer.append( "unknown" ); |
| } |
| |
| buffer.append( ' ' ); |
| if ( firstSpace > -1 ) |
| { |
| buffer.append( oldUserAgent.substring( firstSpace + 1 ) ); |
| buffer.append( ' ' ); |
| buffer.append( oldUserAgent.substring( 0, firstSpace ) ); |
| } |
| else |
| { |
| buffer.append( oldUserAgent ); |
| } |
| |
| wm.setHttpUserAgent( buffer.toString() ); |
| } |
| catch ( ClassCastException e ) |
| { |
| // ignore |
| } |
| |
| SecDispatcher sd = null; |
| |
| try |
| { |
| Proxy proxy = settings.getActiveProxy(); |
| |
| try |
| { |
| sd = (SecDispatcher) container.lookup( SecDispatcher.ROLE, "maven" ); |
| } |
| catch (Exception e) |
| { |
| getLogger().warn( "Security features are disabled. Cannot find plexus component "+SecDispatcher.ROLE + ":maven" ); |
| |
| line(); |
| } |
| |
| if ( proxy != null ) |
| { |
| if ( proxy.getHost() == null ) |
| { |
| throw new SettingsConfigurationException( "Proxy in settings.xml has no host" ); |
| } |
| |
| String pass = proxy.getPassword(); |
| |
| if ( sd != null ) |
| { |
| try |
| { |
| pass = sd.decrypt( pass ); |
| } |
| catch ( SecDispatcherException e ) |
| { |
| reportSecurityConfigurationError( "password for proxy '" + proxy.getId() + "'", e ); |
| } |
| } |
| |
| wagonManager.addProxy( proxy.getProtocol(), proxy.getHost(), proxy.getPort(), proxy.getUsername(), |
| pass, proxy.getNonProxyHosts() ); |
| } |
| |
| for ( Iterator i = settings.getServers().iterator(); i.hasNext(); ) |
| { |
| Server server = (Server) i.next(); |
| |
| String passWord = server.getPassword(); |
| |
| if ( sd != null ) |
| { |
| try |
| { |
| passWord = sd.decrypt( passWord ); |
| } |
| catch ( SecDispatcherException e ) |
| { |
| reportSecurityConfigurationError( "password for server '" + server.getId() + "'", e ); |
| } |
| } |
| |
| String passPhrase = server.getPassphrase(); |
| |
| if ( sd != null ) |
| { |
| try |
| { |
| passPhrase = sd.decrypt( passPhrase ); |
| } |
| catch ( SecDispatcherException e ) |
| { |
| reportSecurityConfigurationError( "passphrase for server '" + server.getId() + "'", e ); |
| } |
| } |
| |
| wagonManager.addAuthenticationInfo( server.getId(), server.getUsername(), passWord, |
| server.getPrivateKey(), passPhrase ); |
| |
| wagonManager.addPermissionInfo( server.getId(), server.getFilePermissions(), |
| server.getDirectoryPermissions() ); |
| |
| if ( server.getConfiguration() != null ) |
| { |
| wagonManager.addConfiguration( server.getId(), (Xpp3Dom) server.getConfiguration() ); |
| } |
| } |
| |
| for ( Iterator i = settings.getMirrors().iterator(); i.hasNext(); ) |
| { |
| Mirror mirror = (Mirror) i.next(); |
| |
| wagonManager.addMirror( mirror.getId(), mirror.getMirrorOf(), mirror.getUrl() ); |
| } |
| } |
| finally |
| { |
| if ( sd != null ) |
| { |
| container.release( sd ); |
| } |
| } |
| } |
| finally |
| { |
| container.release( wagonManager ); |
| } |
| |
| WagonProviderMapping mapping = (WagonProviderMapping) container.lookup( WagonProviderMapping.ROLE ); |
| try |
| { |
| // set defaults |
| mapping.setWagonProvider( "http", "lightweight" ); |
| mapping.setWagonProvider( "https", "lightweight" ); |
| |
| for ( Object k: executionProperties.keySet() ) |
| { |
| String key = (String) k; |
| if ( key.startsWith( "maven.wagon.provider." ) ) |
| { |
| String provider = executionProperties.getProperty( key ); |
| key = key.substring( "maven.wagon.provider.".length() ); |
| |
| mapping.setWagonProvider( key, provider ); |
| } |
| } |
| } |
| finally |
| { |
| container.release( mapping ); |
| } |
| |
| // Would be better in settings.xml, but it is not extensible yet |
| String numThreads = System.getProperty( "maven.artifact.threads" ); |
| if ( numThreads != null ) |
| { |
| int threads = 0; |
| try |
| { |
| threads = Integer.valueOf( numThreads ).intValue(); |
| |
| if ( threads < 1 ) |
| { |
| getLogger().warn( "Invalid number of threads '" + threads + "' will be ignored" ); |
| } |
| } |
| catch ( NumberFormatException e ) |
| { |
| getLogger().warn( "Invalid number of threads '" + numThreads + "' will be ignored: " + e.getMessage() ); |
| } |
| |
| if ( threads > 0 ) |
| { |
| DefaultArtifactResolver artifactResolver = (DefaultArtifactResolver) container.lookup( ArtifactResolver.ROLE ); |
| try |
| { |
| artifactResolver.configureNumberOfThreads( threads ); |
| getLogger().debug( "Resolution thread pool size set to: " + threads ); |
| } |
| finally |
| { |
| container.release( artifactResolver ); |
| } |
| } |
| } |
| } |
| |
| private void reportSecurityConfigurationError( String affectedConfiguration, SecDispatcherException e ) |
| { |
| Throwable cause = e; |
| |
| String msg = "Not decrypting " + affectedConfiguration + " due to exception in security handler."; |
| |
| // Drop to the actual cause, it wraps multiple times |
| while ( cause.getCause() != null ) |
| { |
| cause = cause.getCause(); |
| } |
| |
| // common cause is missing settings-security.xml |
| if ( cause instanceof FileNotFoundException ) |
| { |
| msg += "\nEnsure that you have configured your master password file (and relocation if appropriate)\nSee the installation instructions for details."; |
| } |
| |
| getLogger().warn( msg + "\nCause: " + cause.getMessage() ); |
| getLogger().debug( "Full trace follows", e ); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Lifecylce Management |
| // ---------------------------------------------------------------------- |
| |
| public void contextualize( Context context ) |
| throws ContextException |
| { |
| container = (PlexusContainer) context.get( PlexusConstants.PLEXUS_KEY ); |
| } |
| |
| // ---------------------------------------------------------------------- |
| // Reporting / Logging |
| // ---------------------------------------------------------------------- |
| |
| protected void logFatal( Throwable error ) |
| { |
| line(); |
| |
| getLogger().error( "FATAL ERROR" ); |
| |
| line(); |
| |
| logDiagnostics( error ); |
| |
| logTrace( error, true ); |
| } |
| |
| protected void logError( Exception e, boolean showErrors ) |
| { |
| line(); |
| |
| getLogger().error( "BUILD ERROR" ); |
| |
| line(); |
| |
| logDiagnostics( e ); |
| |
| logTrace( e, showErrors ); |
| |
| if ( !showErrors ) |
| { |
| getLogger().info( "For more information, run Maven with the -e switch" ); |
| |
| line(); |
| } |
| } |
| |
| protected void logFailure( BuildFailureException e, boolean showErrors ) |
| { |
| line(); |
| |
| getLogger().error( "BUILD FAILURE" ); |
| |
| line(); |
| |
| logDiagnostics( e ); |
| |
| logTrace( e, showErrors ); |
| |
| if ( !showErrors ) |
| { |
| getLogger().info( "For more information, run Maven with the -e switch" ); |
| |
| line(); |
| } |
| } |
| |
| private void logTrace( Throwable t, boolean showErrors ) |
| { |
| if ( getLogger().isDebugEnabled() ) |
| { |
| getLogger().debug( "Trace", t ); |
| |
| line(); |
| } |
| else if ( showErrors ) |
| { |
| getLogger().info( "Trace", t ); |
| |
| line(); |
| } |
| } |
| |
| private void logDiagnostics( Throwable t ) |
| { |
| String message = null; |
| if ( errorDiagnostics != null ) |
| { |
| message = errorDiagnostics.diagnose( t ); |
| } |
| |
| if ( message == null ) |
| { |
| message = t.getMessage(); |
| } |
| |
| getLogger().info( message ); |
| |
| line(); |
| } |
| |
| protected void logSuccess( ReactorManager rm ) |
| { |
| line(); |
| |
| getLogger().info( "BUILD SUCCESSFUL" ); |
| |
| line(); |
| } |
| |
| private void logReactorSummary( ReactorManager rm ) |
| { |
| if ( rm.hasMultipleProjects() && rm.executedMultipleProjects() ) |
| { |
| getLogger().info( "" ); |
| getLogger().info( "" ); |
| |
| // ------------------------- |
| // Reactor Summary: |
| // ------------------------- |
| // o project-name...........FAILED |
| // o project2-name..........SKIPPED (dependency build failed or was skipped) |
| // o project-3-name.........SUCCESS |
| |
| line(); |
| getLogger().info( "Reactor Summary:" ); |
| line(); |
| |
| for ( Iterator it = rm.getSortedProjects().iterator(); it.hasNext(); ) |
| { |
| MavenProject project = (MavenProject) it.next(); |
| |
| if ( rm.hasBuildFailure( project ) ) |
| { |
| logReactorSummaryLine( project.getName(), "FAILED", rm.getBuildFailure( project ).getTime() ); |
| } |
| else if ( rm.isBlackListed( project ) ) |
| { |
| logReactorSummaryLine( project.getName(), "SKIPPED (dependency build failed or was skipped)" ); |
| } |
| else if ( rm.hasBuildSuccess( project ) ) |
| { |
| logReactorSummaryLine( project.getName(), "SUCCESS", rm.getBuildSuccess( project ).getTime() ); |
| } |
| else |
| { |
| logReactorSummaryLine( project.getName(), "NOT BUILT" ); |
| } |
| } |
| line(); |
| } |
| } |
| |
| protected void stats( Date start ) |
| { |
| Date finish = new Date(); |
| |
| long time = finish.getTime() - start.getTime(); |
| |
| getLogger().info( "Total time: " + formatTime( time ) ); |
| |
| getLogger().info( "Finished at: " + finish ); |
| |
| //noinspection CallToSystemGC |
| System.gc(); |
| |
| Runtime r = Runtime.getRuntime(); |
| |
| getLogger().info( |
| "Final Memory: " + ( r.totalMemory() - r.freeMemory() ) / MB + "M/" + r.totalMemory() / MB + "M" ); |
| } |
| |
| protected void line() |
| { |
| getLogger().info( "------------------------------------------------------------------------" ); |
| } |
| |
| protected static String formatTime( long ms ) |
| { |
| long secs = ms / MS_PER_SEC; |
| |
| long min = secs / SEC_PER_MIN; |
| |
| secs = secs % SEC_PER_MIN; |
| |
| String msg = ""; |
| |
| if ( min > 1 ) |
| { |
| msg = min + " minutes "; |
| } |
| else if ( min == 1 ) |
| { |
| msg = "1 minute "; |
| } |
| |
| if ( secs > 1 ) |
| { |
| msg += secs + " seconds"; |
| } |
| else if ( secs == 1 ) |
| { |
| msg += "1 second"; |
| } |
| else if ( min == 0 ) |
| { |
| msg += "< 1 second"; |
| } |
| return msg; |
| } |
| |
| private List getProjectFiles( MavenExecutionRequest request ) |
| throws IOException |
| { |
| List files = Collections.EMPTY_LIST; |
| |
| File userDir = new File( System.getProperty( "user.dir" ) ); |
| if ( request.isReactorActive() ) |
| { |
| // TODO: should we now include the pom.xml in the current directory? |
| // String includes = System.getProperty( "maven.reactor.includes", "**/" + POMv4 ); |
| // String excludes = System.getProperty( "maven.reactor.excludes", POMv4 ); |
| |
| String includes = System.getProperty( "maven.reactor.includes", "**/" + POMv4 + ",**/" + RELEASE_POMv4 ); |
| String excludes = System.getProperty( "maven.reactor.excludes", POMv4 + "," + RELEASE_POMv4 ); |
| |
| files = FileUtils.getFiles( userDir, includes, excludes ); |
| |
| filterOneProjectFilePerDirectory( files ); |
| |
| // make sure there is consistent ordering on all platforms, rather than using the filesystem ordering |
| Collections.sort( files ); |
| } |
| else if ( request.getPomFile() != null ) |
| { |
| File projectFile = new File( request.getPomFile() ).getAbsoluteFile(); |
| |
| if ( projectFile.exists() ) |
| { |
| files = Collections.singletonList( projectFile ); |
| } |
| } |
| else |
| { |
| File projectFile = new File( userDir, RELEASE_POMv4 ); |
| |
| if ( !projectFile.exists() ) |
| { |
| projectFile = new File( userDir, POMv4 ); |
| } |
| |
| if ( projectFile.exists() ) |
| { |
| files = Collections.singletonList( projectFile ); |
| } |
| } |
| |
| return files; |
| } |
| |
| private void filterOneProjectFilePerDirectory( List files ) |
| { |
| List releaseDirs = new ArrayList(); |
| |
| for ( Iterator it = files.iterator(); it.hasNext(); ) |
| { |
| File projectFile = (File) it.next(); |
| |
| if ( RELEASE_POMv4.equals( projectFile.getName() ) ) |
| { |
| releaseDirs.add( projectFile.getParentFile() ); |
| } |
| } |
| |
| for ( Iterator it = files.iterator(); it.hasNext(); ) |
| { |
| File projectFile = (File) it.next(); |
| |
| // remove pom.xml files where there is a sibling release-pom.xml file... |
| if ( !RELEASE_POMv4.equals( projectFile.getName() ) && releaseDirs.contains( projectFile.getParentFile() ) ) |
| { |
| it.remove(); |
| } |
| } |
| } |
| } |