aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java')
-rw-r--r--framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java1610
1 files changed, 1610 insertions, 0 deletions
diff --git a/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
new file mode 100644
index 00000000..39660956
--- /dev/null
+++ b/framework/src/maven/apache-maven-3.3.3/maven-embedder/src/main/java/org/apache/maven/cli/MavenCli.java
@@ -0,0 +1,1610 @@
+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 java.io.BufferedInputStream;
+import java.io.Console;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+import java.util.StringTokenizer;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.ParseException;
+import org.apache.commons.cli.UnrecognizedOptionException;
+import org.apache.maven.BuildAbort;
+import org.apache.maven.InternalErrorException;
+import org.apache.maven.Maven;
+import org.apache.maven.building.FileSource;
+import org.apache.maven.building.Problem;
+import org.apache.maven.building.Source;
+import org.apache.maven.cli.configuration.ConfigurationProcessor;
+import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor;
+import org.apache.maven.cli.event.DefaultEventSpyContext;
+import org.apache.maven.cli.event.ExecutionEventLogger;
+import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
+import org.apache.maven.cli.internal.extension.model.CoreExtension;
+import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader;
+import org.apache.maven.cli.logging.Slf4jConfiguration;
+import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
+import org.apache.maven.cli.logging.Slf4jLoggerManager;
+import org.apache.maven.cli.logging.Slf4jStdoutLogger;
+import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
+import org.apache.maven.cli.transfer.QuietMavenTransferListener;
+import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
+import org.apache.maven.eventspy.internal.EventSpyDispatcher;
+import org.apache.maven.exception.DefaultExceptionHandler;
+import org.apache.maven.exception.ExceptionHandler;
+import org.apache.maven.exception.ExceptionSummary;
+import org.apache.maven.execution.DefaultMavenExecutionRequest;
+import org.apache.maven.execution.ExecutionListener;
+import org.apache.maven.execution.MavenExecutionRequest;
+import org.apache.maven.execution.MavenExecutionRequestPopulationException;
+import org.apache.maven.execution.MavenExecutionRequestPopulator;
+import org.apache.maven.execution.MavenExecutionResult;
+import org.apache.maven.extension.internal.CoreExports;
+import org.apache.maven.extension.internal.CoreExtensionEntry;
+import org.apache.maven.lifecycle.LifecycleExecutionException;
+import org.apache.maven.model.building.ModelProcessor;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.properties.internal.EnvironmentUtils;
+import org.apache.maven.properties.internal.SystemProperties;
+import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
+import org.apache.maven.toolchain.building.ToolchainsBuilder;
+import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
+import org.codehaus.plexus.ContainerConfiguration;
+import org.codehaus.plexus.DefaultContainerConfiguration;
+import org.codehaus.plexus.DefaultPlexusContainer;
+import org.codehaus.plexus.PlexusConstants;
+import org.codehaus.plexus.PlexusContainer;
+import org.codehaus.plexus.classworlds.ClassWorld;
+import org.codehaus.plexus.classworlds.realm.ClassRealm;
+import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
+import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
+import org.codehaus.plexus.logging.LoggerManager;
+import org.codehaus.plexus.util.IOUtil;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.eclipse.aether.transfer.TransferListener;
+import org.slf4j.ILoggerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
+import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
+import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
+import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
+import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
+
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import com.google.inject.AbstractModule;
+
+// TODO: push all common bits back to plexus cli and prepare for transition to Guice. We don't need 50 ways to make CLIs
+
+/**
+ * @author Jason van Zyl
+ * @noinspection UseOfSystemOutOrSystemErr,ACCESS_STATIC_VIA_INSTANCE
+ */
+public class MavenCli
+{
+ public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";
+
+ public static final String THREADS_DEPRECATED = "maven.threads.experimental";
+
+ public static final String MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory";
+
+ @SuppressWarnings( "checkstyle:constantname" )
+ public static final String userHome = System.getProperty( "user.home" );
+
+ @SuppressWarnings( "checkstyle:constantname" )
+ public static final File userMavenConfigurationHome = new File( userHome, ".m2" );
+
+ /**
+ * @deprecated use {@link SettingsXmlConfigurationProcessor#DEFAULT_USER_SETTINGS_FILE}
+ */
+ public static final File DEFAULT_USER_SETTINGS_FILE = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE;
+
+ /**
+ * @deprecated use {@link SettingsXmlConfigurationProcessor#DEFAULT_GLOBAL_SETTINGS_FILE}
+ */
+ public static final File DEFAULT_GLOBAL_SETTINGS_FILE =
+ SettingsXmlConfigurationProcessor.DEFAULT_GLOBAL_SETTINGS_FILE;
+
+ public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
+
+ public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE =
+ new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/toolchains.xml" );
+
+ private static final String EXT_CLASS_PATH = "maven.ext.class.path";
+
+ private static final String EXTENSIONS_FILENAME = ".mvn/extensions.xml";
+
+ private ClassWorld classWorld;
+
+ private LoggerManager plexusLoggerManager;
+
+ private ILoggerFactory slf4jLoggerFactory;
+
+ private Logger slf4jLogger;
+
+ private EventSpyDispatcher eventSpyDispatcher;
+
+ private ModelProcessor modelProcessor;
+
+ private Maven maven;
+
+ private MavenExecutionRequestPopulator executionRequestPopulator;
+
+ private ToolchainsBuilder toolchainsBuilder;
+
+ private DefaultSecDispatcher dispatcher;
+
+ private Map<String, ConfigurationProcessor> configurationProcessors;
+
+ public MavenCli()
+ {
+ this( null );
+ }
+
+ // This supports painless invocation by the Verifier during embedded execution of the core ITs
+ public MavenCli( ClassWorld classWorld )
+ {
+ this.classWorld = classWorld;
+ }
+
+ public static void main( String[] args )
+ {
+ int result = main( args, null );
+
+ System.exit( result );
+ }
+
+ /** @noinspection ConfusingMainMethod */
+ public static int main( String[] args, ClassWorld classWorld )
+ {
+ MavenCli cli = new MavenCli();
+ return cli.doMain( new CliRequest( args, classWorld ) );
+ }
+
+ // TODO: need to externalize CliRequest
+ public static int doMain( String[] args, ClassWorld classWorld )
+ {
+ MavenCli cli = new MavenCli();
+ return cli.doMain( new CliRequest( args, classWorld ) );
+ }
+
+ // This supports painless invocation by the Verifier during embedded execution of the core ITs
+ public int doMain( String[] args, String workingDirectory, PrintStream stdout, PrintStream stderr )
+ {
+ PrintStream oldout = System.out;
+ PrintStream olderr = System.err;
+
+ final Set<String> realms;
+ if ( classWorld != null )
+ {
+ realms = new HashSet<String>();
+ for ( ClassRealm realm : classWorld.getRealms() )
+ {
+ realms.add( realm.getId() );
+ }
+ }
+ else
+ {
+ realms = Collections.emptySet();
+ }
+
+ try
+ {
+ if ( stdout != null )
+ {
+ System.setOut( stdout );
+ }
+ if ( stderr != null )
+ {
+ System.setErr( stderr );
+ }
+
+ CliRequest cliRequest = new CliRequest( args, classWorld );
+ cliRequest.workingDirectory = workingDirectory;
+
+ return doMain( cliRequest );
+ }
+ finally
+ {
+ if ( classWorld != null )
+ {
+ for ( ClassRealm realm : new ArrayList<ClassRealm>( classWorld.getRealms() ) )
+ {
+ String realmId = realm.getId();
+ if ( !realms.contains( realmId ) )
+ {
+ try
+ {
+ classWorld.disposeRealm( realmId );
+ }
+ catch ( NoSuchRealmException ignored )
+ {
+ // can't happen
+ }
+ }
+ }
+ }
+ System.setOut( oldout );
+ System.setErr( olderr );
+ }
+ }
+
+ // TODO: need to externalize CliRequest
+ public int doMain( CliRequest cliRequest )
+ {
+ PlexusContainer localContainer = null;
+ try
+ {
+ initialize( cliRequest );
+ cli( cliRequest );
+ logging( cliRequest );
+ version( cliRequest );
+ properties( cliRequest );
+ localContainer = container( cliRequest );
+ commands( cliRequest );
+ configure( cliRequest );
+ toolchains( cliRequest );
+ populateRequest( cliRequest );
+ encryption( cliRequest );
+ repository( cliRequest );
+ return execute( cliRequest );
+ }
+ catch ( ExitException e )
+ {
+ return e.exitCode;
+ }
+ catch ( UnrecognizedOptionException e )
+ {
+ // pure user error, suppress stack trace
+ return 1;
+ }
+ catch ( BuildAbort e )
+ {
+ CLIReportingUtils.showError( slf4jLogger, "ABORTED", e, cliRequest.showErrors );
+
+ return 2;
+ }
+ catch ( Exception e )
+ {
+ CLIReportingUtils.showError( slf4jLogger, "Error executing Maven.", e, cliRequest.showErrors );
+
+ return 1;
+ }
+ finally
+ {
+ if ( localContainer != null )
+ {
+ localContainer.dispose();
+ }
+ }
+ }
+
+ void initialize( CliRequest cliRequest )
+ throws ExitException
+ {
+ if ( cliRequest.workingDirectory == null )
+ {
+ cliRequest.workingDirectory = System.getProperty( "user.dir" );
+ }
+
+ if ( cliRequest.multiModuleProjectDirectory == null )
+ {
+ String basedirProperty = System.getProperty( MULTIMODULE_PROJECT_DIRECTORY );
+ if ( basedirProperty == null )
+ {
+ System.err.format( "-D%s system propery is not set."
+ + " Check $M2_HOME environment variable and mvn script match.", MULTIMODULE_PROJECT_DIRECTORY );
+ throw new ExitException( 1 );
+ }
+ File basedir = basedirProperty != null ? new File( basedirProperty ) : new File( "" );
+ try
+ {
+ cliRequest.multiModuleProjectDirectory = basedir.getCanonicalFile();
+ }
+ catch ( IOException e )
+ {
+ cliRequest.multiModuleProjectDirectory = basedir.getAbsoluteFile();
+ }
+ }
+
+ //
+ // Make sure the Maven home directory is an absolute path to save us from confusion with say drive-relative
+ // Windows paths.
+ //
+ String mavenHome = System.getProperty( "maven.home" );
+
+ if ( mavenHome != null )
+ {
+ System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
+ }
+ }
+
+ void cli( CliRequest cliRequest )
+ throws Exception
+ {
+ //
+ // Parsing errors can happen during the processing of the arguments and we prefer not having to check if
+ // the logger is null and construct this so we can use an SLF4J logger everywhere.
+ //
+ slf4jLogger = new Slf4jStdoutLogger();
+
+ CLIManager cliManager = new CLIManager();
+
+ List<String> args = new ArrayList<String>();
+
+ try
+ {
+ File configFile = new File( cliRequest.multiModuleProjectDirectory, ".mvn/maven.config" );
+
+ if ( configFile.isFile() )
+ {
+ for ( String arg : Files.toString( configFile, Charsets.UTF_8 ).split( "\\s+" ) )
+ {
+ args.add( arg );
+ }
+
+ CommandLine config = cliManager.parse( args.toArray( new String[args.size()] ) );
+ List<?> unrecongized = config.getArgList();
+ if ( !unrecongized.isEmpty() )
+ {
+ throw new ParseException( "Unrecognized maven.config entries: " + unrecongized );
+ }
+ }
+ }
+ catch ( ParseException e )
+ {
+ System.err.println( "Unable to parse maven.config: " + e.getMessage() );
+ cliManager.displayHelp( System.out );
+ throw e;
+ }
+
+ try
+ {
+ args.addAll( 0, Arrays.asList( cliRequest.args ) );
+ cliRequest.commandLine = cliManager.parse( args.toArray( new String[args.size()] ) );
+ }
+ catch ( ParseException e )
+ {
+ System.err.println( "Unable to parse command line options: " + e.getMessage() );
+ cliManager.displayHelp( System.out );
+ throw e;
+ }
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
+ {
+ cliManager.displayHelp( System.out );
+ throw new ExitException( 0 );
+ }
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
+ {
+ System.out.println( CLIReportingUtils.showVersion() );
+ throw new ExitException( 0 );
+ }
+ }
+
+ /**
+ * configure logging
+ */
+ private void logging( CliRequest cliRequest )
+ {
+ cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
+ cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
+ cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );
+
+ slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
+ Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration( slf4jLoggerFactory );
+
+ if ( cliRequest.debug )
+ {
+ cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
+ slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.DEBUG );
+ }
+ else if ( cliRequest.quiet )
+ {
+ cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
+ slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.ERROR );
+ }
+ // else fall back to default log level specified in conf
+ // see http://jira.codehaus.org/browse/MNG-2570
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
+ {
+ File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
+ logFile = resolveFile( logFile, cliRequest.workingDirectory );
+
+ // redirect stdout and stderr to file
+ try
+ {
+ PrintStream ps = new PrintStream( new FileOutputStream( logFile ) );
+ System.setOut( ps );
+ System.setErr( ps );
+ }
+ catch ( FileNotFoundException e )
+ {
+ //
+ // Ignore
+ //
+ }
+ }
+
+ slf4jConfiguration.activate();
+
+ plexusLoggerManager = new Slf4jLoggerManager();
+ slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
+ }
+
+ private void version( CliRequest cliRequest )
+ {
+ if ( cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.SHOW_VERSION ) )
+ {
+ System.out.println( CLIReportingUtils.showVersion() );
+ }
+ }
+
+ private void commands( CliRequest cliRequest )
+ {
+ if ( cliRequest.showErrors )
+ {
+ slf4jLogger.info( "Error stacktraces are turned on." );
+ }
+
+ if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
+ {
+ slf4jLogger.info( "Disabling strict checksum verification on all artifact downloads." );
+ }
+ else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
+ {
+ slf4jLogger.info( "Enabling strict checksum verification on all artifact downloads." );
+ }
+ }
+
+ private void properties( CliRequest cliRequest )
+ {
+ populateProperties( cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties );
+ }
+
+ private PlexusContainer container( CliRequest cliRequest )
+ throws Exception
+ {
+ if ( cliRequest.classWorld == null )
+ {
+ cliRequest.classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
+ }
+
+ ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
+ if ( coreRealm == null )
+ {
+ coreRealm = cliRequest.classWorld.getRealms().iterator().next();
+ }
+
+ List<File> extClassPath = parseExtClasspath( cliRequest );
+
+ CoreExtensionEntry coreEntry = CoreExtensionEntry.discoverFrom( coreRealm );
+ List<CoreExtensionEntry> extensions =
+ loadCoreExtensions( cliRequest, coreRealm, coreEntry.getExportedArtifacts() );
+
+ ClassRealm containerRealm = setupContainerRealm( cliRequest.classWorld, coreRealm, extClassPath, extensions );
+
+ ContainerConfiguration cc = new DefaultContainerConfiguration()
+ .setClassWorld( cliRequest.classWorld )
+ .setRealm( containerRealm )
+ .setClassPathScanning( PlexusConstants.SCANNING_INDEX )
+ .setAutoWiring( true )
+ .setName( "maven" );
+
+ Set<String> exportedArtifacts = new HashSet<String>( coreEntry.getExportedArtifacts() );
+ Set<String> exportedPackages = new HashSet<String>( coreEntry.getExportedPackages() );
+ for ( CoreExtensionEntry extension : extensions )
+ {
+ exportedArtifacts.addAll( extension.getExportedArtifacts() );
+ exportedPackages.addAll( extension.getExportedPackages() );
+ }
+
+ final CoreExports exports = new CoreExports( containerRealm, exportedArtifacts, exportedPackages );
+
+ DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
+ {
+ @Override
+ protected void configure()
+ {
+ bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
+ bind( CoreExports.class ).toInstance( exports );
+ }
+ } );
+
+ // NOTE: To avoid inconsistencies, we'll use the TCCL exclusively for lookups
+ container.setLookupRealm( null );
+
+ container.setLoggerManager( plexusLoggerManager );
+
+ for ( CoreExtensionEntry extension : extensions )
+ {
+ container.discoverComponents( extension.getClassRealm() );
+ }
+
+ customizeContainer( container );
+
+ container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
+
+ Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
+
+ eventSpyDispatcher = container.lookup( EventSpyDispatcher.class );
+
+ DefaultEventSpyContext eventSpyContext = new DefaultEventSpyContext();
+ Map<String, Object> data = eventSpyContext.getData();
+ data.put( "plexus", container );
+ data.put( "workingDirectory", cliRequest.workingDirectory );
+ data.put( "systemProperties", cliRequest.systemProperties );
+ data.put( "userProperties", cliRequest.userProperties );
+ data.put( "versionProperties", CLIReportingUtils.getBuildProperties() );
+ eventSpyDispatcher.init( eventSpyContext );
+
+ // refresh logger in case container got customized by spy
+ slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
+
+ maven = container.lookup( Maven.class );
+
+ executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
+
+ modelProcessor = createModelProcessor( container );
+
+ configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
+
+ toolchainsBuilder = container.lookup( ToolchainsBuilder.class );
+
+ dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
+
+ return container;
+ }
+
+ private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm,
+ Set<String> providedArtifacts )
+ {
+ if ( cliRequest.multiModuleProjectDirectory == null )
+ {
+ return Collections.emptyList();
+ }
+
+ File extensionsFile = new File( cliRequest.multiModuleProjectDirectory, EXTENSIONS_FILENAME );
+ if ( !extensionsFile.isFile() )
+ {
+ return Collections.emptyList();
+ }
+
+ try
+ {
+ List<CoreExtension> extensions = readCoreExtensionsDescriptor( extensionsFile );
+ if ( extensions.isEmpty() )
+ {
+ return Collections.emptyList();
+ }
+
+ ContainerConfiguration cc = new DefaultContainerConfiguration() //
+ .setClassWorld( cliRequest.classWorld ) //
+ .setRealm( containerRealm ) //
+ .setClassPathScanning( PlexusConstants.SCANNING_INDEX ) //
+ .setAutoWiring( true ) //
+ .setName( "maven" );
+
+ DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
+ {
+ @Override
+ protected void configure()
+ {
+ bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
+ }
+ } );
+
+ try
+ {
+ container.setLookupRealm( null );
+
+ container.setLoggerManager( plexusLoggerManager );
+
+ container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
+
+ Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
+
+ executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
+
+ configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
+
+ configure( cliRequest );
+
+ MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request );
+
+ request = populateRequest( cliRequest, request );
+
+ request = executionRequestPopulator.populateDefaults( request );
+
+ BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
+
+ return resolver.loadCoreExtensions( request, providedArtifacts, extensions );
+ }
+ finally
+ {
+ executionRequestPopulator = null;
+ container.dispose();
+ }
+ }
+ catch ( RuntimeException e )
+ {
+ // runtime exceptions are most likely bugs in maven, let them bubble up to the user
+ throw e;
+ }
+ catch ( Exception e )
+ {
+ slf4jLogger.warn( "Failed to read extensions descriptor " + extensionsFile + ": " + e.getMessage() );
+ }
+ return Collections.emptyList();
+ }
+
+ private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile )
+ throws IOException, XmlPullParserException
+ {
+ CoreExtensionsXpp3Reader parser = new CoreExtensionsXpp3Reader();
+ InputStream is = null;
+ try
+ {
+ is = new BufferedInputStream( new FileInputStream( extensionsFile ) );
+ return parser.read( is ).getExtensions();
+ }
+ finally
+ {
+ IOUtil.close( is );
+ }
+ }
+
+ private ClassRealm setupContainerRealm( ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath,
+ List<CoreExtensionEntry> extensions )
+ throws Exception
+ {
+ if ( !extClassPath.isEmpty() || !extensions.isEmpty() )
+ {
+ ClassRealm extRealm = classWorld.newRealm( "maven.ext", null );
+
+ extRealm.setParentRealm( coreRealm );
+
+ slf4jLogger.debug( "Populating class realm " + extRealm.getId() );
+
+ for ( File file : extClassPath )
+ {
+ slf4jLogger.debug( " Included " + file );
+
+ extRealm.addURL( file.toURI().toURL() );
+ }
+
+ for ( CoreExtensionEntry entry : reverse( extensions ) )
+ {
+ Set<String> exportedPackages = entry.getExportedPackages();
+ ClassRealm realm = entry.getClassRealm();
+ for ( String exportedPackage : exportedPackages )
+ {
+ extRealm.importFrom( realm, exportedPackage );
+ }
+ if ( exportedPackages.isEmpty() )
+ {
+ // sisu uses realm imports to establish component visibility
+ extRealm.importFrom( realm, realm.getId() );
+ }
+ }
+
+ return extRealm;
+ }
+
+ return coreRealm;
+ }
+
+ private static <T> List<T> reverse( List<T> list )
+ {
+ List<T> copy = new ArrayList<T>( list );
+ Collections.reverse( copy );
+ return copy;
+ }
+
+ private List<File> parseExtClasspath( CliRequest cliRequest )
+ {
+ String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
+ if ( extClassPath == null )
+ {
+ extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
+ }
+
+ List<File> jars = new ArrayList<File>();
+
+ if ( StringUtils.isNotEmpty( extClassPath ) )
+ {
+ for ( String jar : StringUtils.split( extClassPath, File.pathSeparator ) )
+ {
+ File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
+
+ slf4jLogger.debug( " Included " + file );
+
+ jars.add( file );
+ }
+ }
+
+ return jars;
+ }
+
+ //
+ // This should probably be a separate tool and not be baked into Maven.
+ //
+ private void encryption( CliRequest cliRequest )
+ throws Exception
+ {
+ if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
+ {
+ String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
+
+ if ( passwd == null )
+ {
+ Console cons = System.console();
+ char[] password = ( cons == null ) ? null : cons.readPassword( "Master password: " );
+ if ( password != null )
+ {
+ // Cipher uses Strings
+ passwd = String.copyValueOf( password );
+
+ // Sun/Oracle advises to empty the char array
+ java.util.Arrays.fill( password, ' ' );
+ }
+ }
+
+ DefaultPlexusCipher cipher = new DefaultPlexusCipher();
+
+ System.out.println( cipher.encryptAndDecorate( passwd,
+ DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
+
+ throw new ExitException( 0 );
+ }
+ else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
+ {
+ String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
+
+ if ( passwd == null )
+ {
+ Console cons = System.console();
+ char[] password = ( cons == null ) ? null : cons.readPassword( "Password: " );
+ if ( password != null )
+ {
+ // Cipher uses Strings
+ passwd = String.copyValueOf( password );
+
+ // Sun/Oracle advises to empty the char array
+ java.util.Arrays.fill( password, ' ' );
+ }
+ }
+
+ String configurationFile = dispatcher.getConfigurationFile();
+
+ if ( configurationFile.startsWith( "~" ) )
+ {
+ configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
+ }
+
+ String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
+
+ String master = null;
+
+ SettingsSecurity sec = SecUtil.read( file, true );
+ if ( sec != null )
+ {
+ master = sec.getMaster();
+ }
+
+ if ( master == null )
+ {
+ throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
+ }
+
+ DefaultPlexusCipher cipher = new DefaultPlexusCipher();
+ String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
+ System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
+
+ throw new ExitException( 0 );
+ }
+ }
+
+ private void repository( CliRequest cliRequest )
+ throws Exception
+ {
+ if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY )
+ || Boolean.getBoolean( "maven.legacyLocalRepo" ) )
+ {
+ cliRequest.request.setUseLegacyLocalRepository( true );
+ }
+ }
+
+ private int execute( CliRequest cliRequest ) throws MavenExecutionRequestPopulationException
+ {
+ MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request );
+
+ eventSpyDispatcher.onEvent( request );
+
+ MavenExecutionResult result = maven.execute( request );
+
+ eventSpyDispatcher.onEvent( result );
+
+ eventSpyDispatcher.close();
+
+ if ( result.hasExceptions() )
+ {
+ ExceptionHandler handler = new DefaultExceptionHandler();
+
+ Map<String, String> references = new LinkedHashMap<String, String>();
+
+ MavenProject project = null;
+
+ for ( Throwable exception : result.getExceptions() )
+ {
+ ExceptionSummary summary = handler.handleException( exception );
+
+ logSummary( summary, references, "", cliRequest.showErrors );
+
+ if ( project == null && exception instanceof LifecycleExecutionException )
+ {
+ project = ( (LifecycleExecutionException) exception ).getProject();
+ }
+ }
+
+ slf4jLogger.error( "" );
+
+ if ( !cliRequest.showErrors )
+ {
+ slf4jLogger.error( "To see the full stack trace of the errors, re-run Maven with the -e switch." );
+ }
+ if ( !slf4jLogger.isDebugEnabled() )
+ {
+ slf4jLogger.error( "Re-run Maven using the -X switch to enable full debug logging." );
+ }
+
+ if ( !references.isEmpty() )
+ {
+ slf4jLogger.error( "" );
+ slf4jLogger.error( "For more information about the errors and possible solutions"
+ + ", please read the following articles:" );
+
+ for ( Map.Entry<String, String> entry : references.entrySet() )
+ {
+ slf4jLogger.error( entry.getValue() + " " + entry.getKey() );
+ }
+ }
+
+ if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) )
+ {
+ slf4jLogger.error( "" );
+ slf4jLogger.error( "After correcting the problems, you can resume the build with the command" );
+ slf4jLogger.error( " mvn <goals> -rf :" + project.getArtifactId() );
+ }
+
+ if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) )
+ {
+ slf4jLogger.info( "Build failures were ignored." );
+
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ private void logSummary( ExceptionSummary summary, Map<String, String> references, String indent,
+ boolean showErrors )
+ {
+ String referenceKey = "";
+
+ if ( StringUtils.isNotEmpty( summary.getReference() ) )
+ {
+ referenceKey = references.get( summary.getReference() );
+ if ( referenceKey == null )
+ {
+ referenceKey = "[Help " + ( references.size() + 1 ) + "]";
+ references.put( summary.getReference(), referenceKey );
+ }
+ }
+
+ String msg = summary.getMessage();
+
+ if ( StringUtils.isNotEmpty( referenceKey ) )
+ {
+ if ( msg.indexOf( '\n' ) < 0 )
+ {
+ msg += " -> " + referenceKey;
+ }
+ else
+ {
+ msg += "\n-> " + referenceKey;
+ }
+ }
+
+ String[] lines = msg.split( "(\r\n)|(\r)|(\n)" );
+
+ for ( int i = 0; i < lines.length; i++ )
+ {
+ String line = indent + lines[i].trim();
+
+ if ( ( i == lines.length - 1 )
+ && ( showErrors || ( summary.getException() instanceof InternalErrorException ) ) )
+ {
+ slf4jLogger.error( line, summary.getException() );
+ }
+ else
+ {
+ slf4jLogger.error( line );
+ }
+ }
+
+ indent += " ";
+
+ for ( ExceptionSummary child : summary.getChildren() )
+ {
+ logSummary( child, references, indent, showErrors );
+ }
+ }
+
+ @SuppressWarnings( "checkstyle:methodlength" )
+ private void configure( CliRequest cliRequest )
+ throws Exception
+ {
+ //
+ // This is not ideal but there are events specifically for configuration from the CLI which I don't
+ // believe are really valid but there are ITs which assert the right events are published so this
+ // needs to be supported so the EventSpyDispatcher needs to be put in the CliRequest so that
+ // it can be accessed by configuration processors.
+ //
+ cliRequest.request.setEventSpyDispatcher( eventSpyDispatcher );
+
+ //
+ // We expect at most 2 implementations to be available. The SettingsXmlConfigurationProcessor implementation
+ // is always available in the core and likely always will be, but we may have another ConfigurationProcessor
+ // present supplied by the user. The rule is that we only allow the execution of one ConfigurationProcessor.
+ // If there is more than one then we execute the one supplied by the user, otherwise we execute the
+ // the default SettingsXmlConfigurationProcessor.
+ //
+ int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;
+
+ if ( userSuppliedConfigurationProcessorCount == 0 )
+ {
+ //
+ // Our settings.xml source is historically how we have configured Maven from the CLI so we are going to
+ // have to honour its existence forever. So let's run it.
+ //
+ configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest );
+ }
+ else if ( userSuppliedConfigurationProcessorCount == 1 )
+ {
+ //
+ // Run the user supplied ConfigurationProcessor
+ //
+ for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
+ {
+ String hint = entry.getKey();
+ if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
+ {
+ ConfigurationProcessor configurationProcessor = entry.getValue();
+ configurationProcessor.process( cliRequest );
+ }
+ }
+ }
+ else if ( userSuppliedConfigurationProcessorCount > 1 )
+ {
+ //
+ // There are too many ConfigurationProcessors so we don't know which one to run so report the error.
+ //
+ StringBuffer sb = new StringBuffer(
+ String.format( "\nThere can only be one user supplied ConfigurationProcessor, there are %s:\n\n",
+ userSuppliedConfigurationProcessorCount ) );
+ for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
+ {
+ String hint = entry.getKey();
+ if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
+ {
+ ConfigurationProcessor configurationProcessor = entry.getValue();
+ sb.append( String.format( "%s\n", configurationProcessor.getClass().getName() ) );
+ }
+ }
+ sb.append( String.format( "\n" ) );
+ throw new Exception( sb.toString() );
+ }
+ }
+
+ @SuppressWarnings( "checkstyle:methodlength" )
+ private void toolchains( CliRequest cliRequest )
+ throws Exception
+ {
+ File userToolchainsFile;
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
+ {
+ userToolchainsFile =
+ new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
+ userToolchainsFile = resolveFile( userToolchainsFile, cliRequest.workingDirectory );
+
+ if ( !userToolchainsFile.isFile() )
+ {
+ throw new FileNotFoundException( "The specified user toolchains file does not exist: "
+ + userToolchainsFile );
+ }
+ }
+ else
+ {
+ userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
+ }
+
+ File globalToolchainsFile;
+
+ if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) )
+ {
+ globalToolchainsFile =
+ new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) );
+ globalToolchainsFile = resolveFile( globalToolchainsFile, cliRequest.workingDirectory );
+
+ if ( !globalToolchainsFile.isFile() )
+ {
+ throw new FileNotFoundException( "The specified global toolchains file does not exist: "
+ + globalToolchainsFile );
+ }
+ }
+ else
+ {
+ globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
+ }
+
+ cliRequest.request.setGlobalToolchainsFile( globalToolchainsFile );
+ cliRequest.request.setUserToolchainsFile( userToolchainsFile );
+
+ DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
+ if ( globalToolchainsFile.isFile() )
+ {
+ toolchainsRequest.setGlobalToolchainsSource( new FileSource( globalToolchainsFile ) );
+ }
+ if ( userToolchainsFile.isFile() )
+ {
+ toolchainsRequest.setUserToolchainsSource( new FileSource( userToolchainsFile ) );
+ }
+
+ eventSpyDispatcher.onEvent( toolchainsRequest );
+
+ slf4jLogger.debug( "Reading global toolchains from "
+ + getLocation( toolchainsRequest.getGlobalToolchainsSource(), globalToolchainsFile ) );
+ slf4jLogger.debug( "Reading user toolchains from "
+ + getLocation( toolchainsRequest.getUserToolchainsSource(), userToolchainsFile ) );
+
+ ToolchainsBuildingResult toolchainsResult = toolchainsBuilder.build( toolchainsRequest );
+
+ eventSpyDispatcher.onEvent( toolchainsRequest );
+
+ executionRequestPopulator.populateFromToolchains( cliRequest.request,
+ toolchainsResult.getEffectiveToolchains() );
+
+ if ( !toolchainsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
+ {
+ slf4jLogger.warn( "" );
+ slf4jLogger.warn( "Some problems were encountered while building the effective toolchains" );
+
+ for ( Problem problem : toolchainsResult.getProblems() )
+ {
+ slf4jLogger.warn( problem.getMessage() + " @ " + problem.getLocation() );
+ }
+
+ slf4jLogger.warn( "" );
+ }
+ }
+
+ private Object getLocation( Source source, File defaultLocation )
+ {
+ if ( source != null )
+ {
+ return source.getLocation();
+ }
+ return defaultLocation;
+ }
+
+ private MavenExecutionRequest populateRequest( CliRequest cliRequest )
+ {
+ return populateRequest( cliRequest, cliRequest.request );
+ }
+
+ private MavenExecutionRequest populateRequest( CliRequest cliRequest, MavenExecutionRequest request )
+ {
+ CommandLine commandLine = cliRequest.commandLine;
+ String workingDirectory = cliRequest.workingDirectory;
+ boolean quiet = cliRequest.quiet;
+ boolean showErrors = cliRequest.showErrors;
+
+ String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
+ for ( String deprecatedOption : deprecatedOptions )
+ {
+ if ( commandLine.hasOption( deprecatedOption ) )
+ {
+ slf4jLogger.warn( "Command line option -" + deprecatedOption
+ + " is deprecated and will be removed in future Maven versions." );
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // Now that we have everything that we need we will fire up plexus and
+ // bring the maven component to life for use.
+ // ----------------------------------------------------------------------
+
+ if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
+ {
+ request.setInteractiveMode( false );
+ }
+
+ boolean noSnapshotUpdates = false;
+ if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
+ {
+ noSnapshotUpdates = true;
+ }
+
+ // ----------------------------------------------------------------------
+ //
+ // ----------------------------------------------------------------------
+
+ @SuppressWarnings( "unchecked" )
+ List<String> goals = commandLine.getArgList();
+
+ boolean recursive = true;
+
+ // this is the default behavior.
+ String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
+
+ if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
+ {
+ recursive = false;
+ }
+
+ if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
+ {
+ reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
+ }
+ else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
+ {
+ reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
+ }
+ else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
+ {
+ reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
+ }
+
+ if ( commandLine.hasOption( CLIManager.OFFLINE ) )
+ {
+ request.setOffline( true );
+ }
+
+ boolean updateSnapshots = false;
+
+ if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
+ {
+ updateSnapshots = true;
+ }
+
+ String globalChecksumPolicy = null;
+
+ if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
+ {
+ globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
+ }
+ else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
+ {
+ globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
+ }
+
+ File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
+
+ // ----------------------------------------------------------------------
+ // Profile Activation
+ // ----------------------------------------------------------------------
+
+ List<String> activeProfiles = new ArrayList<String>();
+
+ List<String> inactiveProfiles = new ArrayList<String>();
+
+ if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
+ {
+ String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
+ if ( profileOptionValues != null )
+ {
+ for ( String profileOptionValue : profileOptionValues )
+ {
+ StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );
+
+ while ( profileTokens.hasMoreTokens() )
+ {
+ String profileAction = profileTokens.nextToken().trim();
+
+ if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
+ {
+ inactiveProfiles.add( profileAction.substring( 1 ) );
+ }
+ else if ( profileAction.startsWith( "+" ) )
+ {
+ activeProfiles.add( profileAction.substring( 1 ) );
+ }
+ else
+ {
+ activeProfiles.add( profileAction );
+ }
+ }
+ }
+ }
+ }
+
+ TransferListener transferListener;
+
+ if ( quiet )
+ {
+ transferListener = new QuietMavenTransferListener();
+ }
+ else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
+ {
+ //
+ // If we're logging to a file then we don't want the console transfer listener as it will spew
+ // download progress all over the place
+ //
+ transferListener = getConsoleTransferListener();
+ }
+ else
+ {
+ transferListener = getBatchTransferListener();
+ }
+
+ ExecutionListener executionListener = new ExecutionEventLogger();
+ if ( eventSpyDispatcher != null )
+ {
+ executionListener = eventSpyDispatcher.chainListener( executionListener );
+ }
+
+ String alternatePomFile = null;
+ if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
+ {
+ alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
+ }
+
+ File userToolchainsFile;
+ if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
+ {
+ userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
+ userToolchainsFile = resolveFile( userToolchainsFile, workingDirectory );
+ }
+ else
+ {
+ userToolchainsFile = MavenCli.DEFAULT_USER_TOOLCHAINS_FILE;
+ }
+
+ request.setBaseDirectory( baseDirectory ).setGoals( goals )
+ .setSystemProperties( cliRequest.systemProperties )
+ .setUserProperties( cliRequest.userProperties )
+ .setReactorFailureBehavior( reactorFailureBehaviour ) // default: fail fast
+ .setRecursive( recursive ) // default: true
+ .setShowErrors( showErrors ) // default: false
+ .addActiveProfiles( activeProfiles ) // optional
+ .addInactiveProfiles( inactiveProfiles ) // optional
+ .setExecutionListener( executionListener )
+ .setTransferListener( transferListener ) // default: batch mode which goes along with interactive
+ .setUpdateSnapshots( updateSnapshots ) // default: false
+ .setNoSnapshotUpdates( noSnapshotUpdates ) // default: false
+ .setGlobalChecksumPolicy( globalChecksumPolicy ) // default: warn
+ .setMultiModuleProjectDirectory( cliRequest.multiModuleProjectDirectory );
+
+ if ( alternatePomFile != null )
+ {
+ File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
+ if ( pom.isDirectory() )
+ {
+ pom = new File( pom, "pom.xml" );
+ }
+
+ request.setPom( pom );
+ }
+ else if ( modelProcessor != null )
+ {
+ File pom = modelProcessor.locatePom( baseDirectory );
+
+ if ( pom.isFile() )
+ {
+ request.setPom( pom );
+ }
+ }
+
+ if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
+ {
+ request.setBaseDirectory( request.getPom().getParentFile() );
+ }
+
+ if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
+ {
+ request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
+ }
+
+ if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
+ {
+ String[] projectOptionValues = commandLine.getOptionValues( CLIManager.PROJECT_LIST );
+
+ List<String> inclProjects = new ArrayList<String>();
+ List<String> exclProjects = new ArrayList<String>();
+
+ if ( projectOptionValues != null )
+ {
+ for ( String projectOptionValue : projectOptionValues )
+ {
+ StringTokenizer projectTokens = new StringTokenizer( projectOptionValue, "," );
+
+ while ( projectTokens.hasMoreTokens() )
+ {
+ String projectAction = projectTokens.nextToken().trim();
+
+ if ( projectAction.startsWith( "-" ) || projectAction.startsWith( "!" ) )
+ {
+ exclProjects.add( projectAction.substring( 1 ) );
+ }
+ else if ( projectAction.startsWith( "+" ) )
+ {
+ inclProjects.add( projectAction.substring( 1 ) );
+ }
+ else
+ {
+ inclProjects.add( projectAction );
+ }
+ }
+ }
+ }
+
+ request.setSelectedProjects( inclProjects );
+ request.setExcludedProjects( exclProjects );
+ }
+
+ if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
+ && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
+ {
+ request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
+ }
+ else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
+ && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
+ {
+ request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
+ }
+ else if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
+ && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
+ {
+ request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
+ }
+
+ String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
+
+ if ( localRepoProperty == null )
+ {
+ localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
+ }
+
+ if ( localRepoProperty != null )
+ {
+ request.setLocalRepositoryPath( localRepoProperty );
+ }
+
+ request.setCacheNotFound( true );
+ request.setCacheTransferError( false );
+
+ //
+ // Builder, concurrency and parallelism
+ //
+ // We preserve the existing methods for builder selection which is to look for various inputs in the threading
+ // configuration. We don't have an easy way to allow a pluggable builder to provide its own configuration
+ // parameters but this is sufficient for now. Ultimately we want components like Builders to provide a way to
+ // extend the command line to accept its own configuration parameters.
+ //
+ final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS )
+ ? commandLine.getOptionValue( CLIManager.THREADS )
+ : request.getSystemProperties().getProperty(
+ MavenCli.THREADS_DEPRECATED ); // TODO: Remove this setting. Note that the int-tests use it
+
+ if ( threadConfiguration != null )
+ {
+ //
+ // Default to the standard multithreaded builder
+ //
+ request.setBuilderId( "multithreaded" );
+
+ if ( threadConfiguration.contains( "C" ) )
+ {
+ request.setDegreeOfConcurrency( calculateDegreeOfConcurrencyWithCoreMultiplier( threadConfiguration ) );
+ }
+ else
+ {
+ request.setDegreeOfConcurrency( Integer.valueOf( threadConfiguration ) );
+ }
+ }
+
+ //
+ // Allow the builder to be overriden by the user if requested. The builders are now pluggable.
+ //
+ if ( commandLine.hasOption( CLIManager.BUILDER ) )
+ {
+ request.setBuilderId( commandLine.getOptionValue( CLIManager.BUILDER ) );
+ }
+
+ return request;
+ }
+
+ int calculateDegreeOfConcurrencyWithCoreMultiplier( String threadConfiguration )
+ {
+ int procs = Runtime.getRuntime().availableProcessors();
+ return (int) ( Float.valueOf( threadConfiguration.replace( "C", "" ) ) * procs );
+ }
+
+ static File resolveFile( File file, String workingDirectory )
+ {
+ if ( file == null )
+ {
+ return null;
+ }
+ else if ( file.isAbsolute() )
+ {
+ return file;
+ }
+ else if ( file.getPath().startsWith( File.separator ) )
+ {
+ // drive-relative Windows path
+ return file.getAbsoluteFile();
+ }
+ else
+ {
+ return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
+ }
+ }
+
+ // ----------------------------------------------------------------------
+ // System properties handling
+ // ----------------------------------------------------------------------
+
+ static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
+ {
+ EnvironmentUtils.addEnvVars( systemProperties );
+
+ // ----------------------------------------------------------------------
+ // Options that are set on the command line become system properties
+ // and therefore are set in the session properties. System properties
+ // are most dominant.
+ // ----------------------------------------------------------------------
+
+ if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
+ {
+ String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
+
+ if ( defStrs != null )
+ {
+ for ( String defStr : defStrs )
+ {
+ setCliProperty( defStr, userProperties );
+ }
+ }
+ }
+
+ SystemProperties.addSystemProperties( systemProperties );
+
+ // ----------------------------------------------------------------------
+ // Properties containing info about the currently running version of Maven
+ // These override any corresponding properties set on the command line
+ // ----------------------------------------------------------------------
+
+ Properties buildProperties = CLIReportingUtils.getBuildProperties();
+
+ String mavenVersion = buildProperties.getProperty( CLIReportingUtils.BUILD_VERSION_PROPERTY );
+ systemProperties.setProperty( "maven.version", mavenVersion );
+
+ String mavenBuildVersion = CLIReportingUtils.createMavenVersionString( buildProperties );
+ systemProperties.setProperty( "maven.build.version", mavenBuildVersion );
+ }
+
+ private static void setCliProperty( String property, Properties properties )
+ {
+ String name;
+
+ String value;
+
+ int i = property.indexOf( "=" );
+
+ if ( i <= 0 )
+ {
+ name = property.trim();
+
+ value = "true";
+ }
+ else
+ {
+ name = property.substring( 0, i ).trim();
+
+ value = property.substring( i + 1 );
+ }
+
+ properties.setProperty( name, value );
+
+ // ----------------------------------------------------------------------
+ // I'm leaving the setting of system properties here as not to break
+ // the SystemPropertyProfileActivator. This won't harm embedding. jvz.
+ // ----------------------------------------------------------------------
+
+ System.setProperty( name, value );
+ }
+
+ static class ExitException
+ extends Exception
+ {
+ @SuppressWarnings( "checkstyle:visibilitymodifier" )
+ public int exitCode;
+
+ public ExitException( int exitCode )
+ {
+ this.exitCode = exitCode;
+ }
+ }
+
+ //
+ // Customizations available via the CLI
+ //
+
+ protected TransferListener getConsoleTransferListener()
+ {
+ return new ConsoleMavenTransferListener( System.out );
+ }
+
+ protected TransferListener getBatchTransferListener()
+ {
+ return new Slf4jMavenTransferListener();
+ }
+
+ protected void customizeContainer( PlexusContainer container )
+ {
+ }
+
+ protected ModelProcessor createModelProcessor( PlexusContainer container )
+ throws ComponentLookupException
+ {
+ return container.lookup( ModelProcessor.class );
+ }
+}