1 package org.apache.maven.cli;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import com.google.inject.AbstractModule;
23 import org.apache.commons.cli.CommandLine;
24 import org.apache.commons.cli.Option;
25 import org.apache.commons.cli.ParseException;
26 import org.apache.commons.cli.UnrecognizedOptionException;
27 import org.apache.maven.BuildAbort;
28 import org.apache.maven.InternalErrorException;
29 import org.apache.maven.Maven;
30 import org.apache.maven.building.FileSource;
31 import org.apache.maven.building.Problem;
32 import org.apache.maven.building.Source;
33 import org.apache.maven.cli.configuration.ConfigurationProcessor;
34 import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor;
35 import org.apache.maven.cli.event.DefaultEventSpyContext;
36 import org.apache.maven.cli.event.ExecutionEventLogger;
37 import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
38 import org.apache.maven.cli.internal.extension.model.CoreExtension;
39 import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader;
40 import org.apache.maven.cli.logging.Slf4jConfiguration;
41 import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
42 import org.apache.maven.cli.logging.Slf4jLoggerManager;
43 import org.apache.maven.cli.logging.Slf4jStdoutLogger;
44 import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
45 import org.apache.maven.cli.transfer.QuietMavenTransferListener;
46 import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
47 import org.apache.maven.eventspy.internal.EventSpyDispatcher;
48 import org.apache.maven.exception.DefaultExceptionHandler;
49 import org.apache.maven.exception.ExceptionHandler;
50 import org.apache.maven.exception.ExceptionSummary;
51 import org.apache.maven.execution.DefaultMavenExecutionRequest;
52 import org.apache.maven.execution.ExecutionListener;
53 import org.apache.maven.execution.MavenExecutionRequest;
54 import org.apache.maven.execution.MavenExecutionRequestPopulationException;
55 import org.apache.maven.execution.MavenExecutionRequestPopulator;
56 import org.apache.maven.execution.MavenExecutionResult;
57 import org.apache.maven.execution.scope.internal.MojoExecutionScopeModule;
58 import org.apache.maven.extension.internal.CoreExports;
59 import org.apache.maven.extension.internal.CoreExtensionEntry;
60 import org.apache.maven.lifecycle.LifecycleExecutionException;
61 import org.apache.maven.model.building.ModelProcessor;
62 import org.apache.maven.project.MavenProject;
63 import org.apache.maven.properties.internal.EnvironmentUtils;
64 import org.apache.maven.properties.internal.SystemProperties;
65 import org.apache.maven.session.scope.internal.SessionScopeModule;
66 import org.apache.maven.shared.utils.logging.MessageBuilder;
67 import org.apache.maven.shared.utils.logging.MessageUtils;
68 import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
69 import org.apache.maven.toolchain.building.ToolchainsBuilder;
70 import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
71 import org.codehaus.plexus.ContainerConfiguration;
72 import org.codehaus.plexus.DefaultContainerConfiguration;
73 import org.codehaus.plexus.DefaultPlexusContainer;
74 import org.codehaus.plexus.PlexusConstants;
75 import org.codehaus.plexus.PlexusContainer;
76 import org.codehaus.plexus.classworlds.ClassWorld;
77 import org.codehaus.plexus.classworlds.realm.ClassRealm;
78 import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
79 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
80 import org.codehaus.plexus.logging.LoggerManager;
81 import org.codehaus.plexus.util.StringUtils;
82 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
83 import org.eclipse.aether.transfer.TransferListener;
84 import org.slf4j.ILoggerFactory;
85 import org.slf4j.Logger;
86 import org.slf4j.LoggerFactory;
87 import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
88 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
89 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
90 import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
91 import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
92
93 import java.io.BufferedInputStream;
94 import java.io.Console;
95 import java.io.File;
96 import java.io.FileInputStream;
97 import java.io.FileNotFoundException;
98 import java.io.FileOutputStream;
99 import java.io.IOException;
100 import java.io.InputStream;
101 import java.io.PrintStream;
102 import java.nio.file.Files;
103 import java.util.ArrayList;
104 import java.util.Collections;
105 import java.util.HashSet;
106 import java.util.LinkedHashMap;
107 import java.util.List;
108 import java.util.Map;
109 import java.util.Map.Entry;
110 import java.util.Properties;
111 import java.util.Set;
112 import java.util.StringTokenizer;
113 import java.util.regex.Matcher;
114 import java.util.regex.Pattern;
115
116 import static org.apache.maven.cli.ResolveFile.resolveFile;
117 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
118
119
120
121
122
123
124 public class MavenCli
125 {
126 public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";
127
128 public static final String MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory";
129
130 public static final String USER_HOME = System.getProperty( "user.home" );
131
132 public static final File USER_MAVEN_CONFIGURATION_HOME = new File( USER_HOME, ".m2" );
133
134 public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( USER_MAVEN_CONFIGURATION_HOME, "toolchains.xml" );
135
136 public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE =
137 new File( System.getProperty( "maven.conf" ), "toolchains.xml" );
138
139 private static final String EXT_CLASS_PATH = "maven.ext.class.path";
140
141 private static final String EXTENSIONS_FILENAME = ".mvn/extensions.xml";
142
143 private static final String MVN_MAVEN_CONFIG = ".mvn/maven.config";
144
145 public static final String STYLE_COLOR_PROPERTY = "style.color";
146
147 private ClassWorld classWorld;
148
149 private LoggerManager plexusLoggerManager;
150
151 private ILoggerFactory slf4jLoggerFactory;
152
153 private Logger slf4jLogger;
154
155 private EventSpyDispatcher eventSpyDispatcher;
156
157 private ModelProcessor modelProcessor;
158
159 private Maven maven;
160
161 private MavenExecutionRequestPopulator executionRequestPopulator;
162
163 private ToolchainsBuilder toolchainsBuilder;
164
165 private DefaultSecDispatcher dispatcher;
166
167 private Map<String, ConfigurationProcessor> configurationProcessors;
168
169 public MavenCli()
170 {
171 this( null );
172 }
173
174
175 public MavenCli( ClassWorld classWorld )
176 {
177 this.classWorld = classWorld;
178 }
179
180 public static void main( String[] args )
181 {
182 int result = main( args, null );
183
184 System.exit( result );
185 }
186
187 public static int main( String[] args, ClassWorld classWorld )
188 {
189 MavenCli cli = new MavenCli();
190
191 MessageUtils.systemInstall();
192 MessageUtils.registerShutdownHook();
193 int result = cli.doMain( new CliRequest( args, classWorld ) );
194 MessageUtils.systemUninstall();
195
196 return result;
197 }
198
199
200 public static int doMain( String[] args, ClassWorld classWorld )
201 {
202 MavenCli cli = new MavenCli();
203 return cli.doMain( new CliRequest( args, classWorld ) );
204 }
205
206
207
208
209
210
211 public int doMain( String[] args, String workingDirectory, PrintStream stdout, PrintStream stderr )
212 {
213 PrintStream oldout = System.out;
214 PrintStream olderr = System.err;
215
216 final Set<String> realms;
217 if ( classWorld != null )
218 {
219 realms = new HashSet<>();
220 for ( ClassRealm realm : classWorld.getRealms() )
221 {
222 realms.add( realm.getId() );
223 }
224 }
225 else
226 {
227 realms = Collections.emptySet();
228 }
229
230 try
231 {
232 if ( stdout != null )
233 {
234 System.setOut( stdout );
235 }
236 if ( stderr != null )
237 {
238 System.setErr( stderr );
239 }
240
241 CliRequest cliRequest = new CliRequest( args, classWorld );
242 cliRequest.workingDirectory = workingDirectory;
243
244 return doMain( cliRequest );
245 }
246 finally
247 {
248 if ( classWorld != null )
249 {
250 for ( ClassRealm realm : new ArrayList<>( classWorld.getRealms() ) )
251 {
252 String realmId = realm.getId();
253 if ( !realms.contains( realmId ) )
254 {
255 try
256 {
257 classWorld.disposeRealm( realmId );
258 }
259 catch ( NoSuchRealmException ignored )
260 {
261
262 }
263 }
264 }
265 }
266 System.setOut( oldout );
267 System.setErr( olderr );
268 }
269 }
270
271
272 public int doMain( CliRequest cliRequest )
273 {
274 PlexusContainer localContainer = null;
275 try
276 {
277 initialize( cliRequest );
278 cli( cliRequest );
279 properties( cliRequest );
280 logging( cliRequest );
281 version( cliRequest );
282 localContainer = container( cliRequest );
283 commands( cliRequest );
284 configure( cliRequest );
285 toolchains( cliRequest );
286 populateRequest( cliRequest );
287 encryption( cliRequest );
288 repository( cliRequest );
289 return execute( cliRequest );
290 }
291 catch ( ExitException e )
292 {
293 return e.exitCode;
294 }
295 catch ( UnrecognizedOptionException e )
296 {
297
298 return 1;
299 }
300 catch ( BuildAbort e )
301 {
302 CLIReportingUtils.showError( slf4jLogger, "ABORTED", e, cliRequest.showErrors );
303
304 return 2;
305 }
306 catch ( Exception e )
307 {
308 CLIReportingUtils.showError( slf4jLogger, "Error executing Maven.", e, cliRequest.showErrors );
309
310 return 1;
311 }
312 finally
313 {
314 if ( localContainer != null )
315 {
316 localContainer.dispose();
317 }
318 }
319 }
320
321 void initialize( CliRequest cliRequest )
322 throws ExitException
323 {
324 if ( cliRequest.workingDirectory == null )
325 {
326 cliRequest.workingDirectory = System.getProperty( "user.dir" );
327 }
328
329 if ( cliRequest.multiModuleProjectDirectory == null )
330 {
331 String basedirProperty = System.getProperty( MULTIMODULE_PROJECT_DIRECTORY );
332 if ( basedirProperty == null )
333 {
334 System.err.format(
335 "-D%s system property is not set.", MULTIMODULE_PROJECT_DIRECTORY );
336 throw new ExitException( 1 );
337 }
338 File basedir = basedirProperty != null ? new File( basedirProperty ) : new File( "" );
339 try
340 {
341 cliRequest.multiModuleProjectDirectory = basedir.getCanonicalFile();
342 }
343 catch ( IOException e )
344 {
345 cliRequest.multiModuleProjectDirectory = basedir.getAbsoluteFile();
346 }
347 }
348
349
350
351
352
353 String mavenHome = System.getProperty( "maven.home" );
354
355 if ( mavenHome != null )
356 {
357 System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
358 }
359 }
360
361 void cli( CliRequest cliRequest )
362 throws Exception
363 {
364
365
366
367
368 slf4jLogger = new Slf4jStdoutLogger();
369
370 CLIManager cliManager = new CLIManager();
371
372 List<String> args = new ArrayList<>();
373 CommandLine mavenConfig = null;
374 try
375 {
376 File configFile = new File( cliRequest.multiModuleProjectDirectory, MVN_MAVEN_CONFIG );
377
378 if ( configFile.isFile() )
379 {
380 for ( String arg : new String( Files.readAllBytes( configFile.toPath() ) ).split( "\\s+" ) )
381 {
382 if ( !arg.isEmpty() )
383 {
384 args.add( arg );
385 }
386 }
387
388 mavenConfig = cliManager.parse( args.toArray( new String[0] ) );
389 List<?> unrecongized = mavenConfig.getArgList();
390 if ( !unrecongized.isEmpty() )
391 {
392 throw new ParseException( "Unrecognized maven.config entries: " + unrecongized );
393 }
394 }
395 }
396 catch ( ParseException e )
397 {
398 System.err.println( "Unable to parse maven.config: " + e.getMessage() );
399 cliManager.displayHelp( System.out );
400 throw e;
401 }
402
403 try
404 {
405 if ( mavenConfig == null )
406 {
407 cliRequest.commandLine = cliManager.parse( cliRequest.args );
408 }
409 else
410 {
411 cliRequest.commandLine = cliMerge( cliManager.parse( cliRequest.args ), mavenConfig );
412 }
413 }
414 catch ( ParseException e )
415 {
416 System.err.println( "Unable to parse command line options: " + e.getMessage() );
417 cliManager.displayHelp( System.out );
418 throw e;
419 }
420
421 if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
422 {
423 cliManager.displayHelp( System.out );
424 throw new ExitException( 0 );
425 }
426
427 if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
428 {
429 System.out.println( CLIReportingUtils.showVersion() );
430 throw new ExitException( 0 );
431 }
432 }
433
434 private CommandLine cliMerge( CommandLine mavenArgs, CommandLine mavenConfig )
435 {
436 CommandLine.Builder commandLineBuilder = new CommandLine.Builder();
437
438
439 for ( String arg : mavenArgs.getArgs() )
440 {
441 commandLineBuilder.addArg( arg );
442 }
443 for ( String arg : mavenConfig.getArgs() )
444 {
445 commandLineBuilder.addArg( arg );
446 }
447
448
449 List<Option> setPropertyOptions = new ArrayList<>();
450 for ( Option opt : mavenArgs.getOptions() )
451 {
452 if ( String.valueOf( CLIManager.SET_SYSTEM_PROPERTY ).equals( opt.getOpt() ) )
453 {
454 setPropertyOptions.add( opt );
455 }
456 else
457 {
458 commandLineBuilder.addOption( opt );
459 }
460 }
461 for ( Option opt : mavenConfig.getOptions() )
462 {
463 commandLineBuilder.addOption( opt );
464 }
465
466 for ( Option opt : setPropertyOptions )
467 {
468 commandLineBuilder.addOption( opt );
469 }
470 return commandLineBuilder.build();
471 }
472
473
474
475
476 void logging( CliRequest cliRequest )
477 {
478
479 cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
480 cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
481 cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );
482
483 slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
484 Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration( slf4jLoggerFactory );
485
486 if ( cliRequest.debug )
487 {
488 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
489 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.DEBUG );
490 }
491 else if ( cliRequest.quiet )
492 {
493 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
494 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.ERROR );
495 }
496
497
498
499
500 String styleColor = cliRequest.getUserProperties().getProperty( STYLE_COLOR_PROPERTY, "auto" );
501 if ( "always".equals( styleColor ) )
502 {
503 MessageUtils.setColorEnabled( true );
504 }
505 else if ( "never".equals( styleColor ) )
506 {
507 MessageUtils.setColorEnabled( false );
508 }
509 else if ( !"auto".equals( styleColor ) )
510 {
511 throw new IllegalArgumentException( "Invalid color configuration option [" + styleColor
512 + "]. Supported values are (auto|always|never)." );
513 }
514 else if ( cliRequest.commandLine.hasOption( CLIManager.BATCH_MODE )
515 || cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
516 {
517 MessageUtils.setColorEnabled( false );
518 }
519
520
521 if ( cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
522 {
523 File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
524 logFile = resolveFile( logFile, cliRequest.workingDirectory );
525
526
527 try
528 {
529 PrintStream ps = new PrintStream( new FileOutputStream( logFile ) );
530 System.setOut( ps );
531 System.setErr( ps );
532 }
533 catch ( FileNotFoundException e )
534 {
535
536
537
538 }
539 }
540
541 slf4jConfiguration.activate();
542
543 plexusLoggerManager = new Slf4jLoggerManager();
544 slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
545 }
546
547 private void version( CliRequest cliRequest )
548 {
549 if ( cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.SHOW_VERSION ) )
550 {
551 System.out.println( CLIReportingUtils.showVersion() );
552 }
553 }
554
555 private void commands( CliRequest cliRequest )
556 {
557 if ( cliRequest.showErrors )
558 {
559 slf4jLogger.info( "Error stacktraces are turned on." );
560 }
561
562 if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
563 {
564 slf4jLogger.info( "Disabling strict checksum verification on all artifact downloads." );
565 }
566 else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
567 {
568 slf4jLogger.info( "Enabling strict checksum verification on all artifact downloads." );
569 }
570
571 if ( slf4jLogger.isDebugEnabled() )
572 {
573 slf4jLogger.debug( "Message scheme: {}", ( MessageUtils.isColorEnabled() ? "color" : "plain" ) );
574 if ( MessageUtils.isColorEnabled() )
575 {
576 MessageBuilder buff = MessageUtils.buffer();
577 buff.a( "Message styles: " );
578 buff.a( MessageUtils.level().debug( "debug" ) ).a( ' ' );
579 buff.a( MessageUtils.level().info( "info" ) ).a( ' ' );
580 buff.a( MessageUtils.level().warning( "warning" ) ).a( ' ' );
581 buff.a( MessageUtils.level().error( "error" ) ).a( ' ' );
582
583 buff.success( "success" ).a( ' ' );
584 buff.failure( "failure" ).a( ' ' );
585 buff.strong( "strong" ).a( ' ' );
586 buff.mojo( "mojo" ).a( ' ' );
587 buff.project( "project" );
588 slf4jLogger.debug( buff.toString() );
589 }
590 }
591 }
592
593
594
595 void properties( CliRequest cliRequest )
596 {
597 populateProperties( cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties );
598 }
599
600 PlexusContainer container( CliRequest cliRequest )
601 throws Exception
602 {
603 if ( cliRequest.classWorld == null )
604 {
605 cliRequest.classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
606 }
607
608 ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
609 if ( coreRealm == null )
610 {
611 coreRealm = cliRequest.classWorld.getRealms().iterator().next();
612 }
613
614 List<File> extClassPath = parseExtClasspath( cliRequest );
615
616 CoreExtensionEntry coreEntry = CoreExtensionEntry.discoverFrom( coreRealm );
617 List<CoreExtensionEntry> extensions =
618 loadCoreExtensions( cliRequest, coreRealm, coreEntry.getExportedArtifacts() );
619
620 ClassRealm containerRealm = setupContainerRealm( cliRequest.classWorld, coreRealm, extClassPath, extensions );
621
622 ContainerConfiguration cc = new DefaultContainerConfiguration().setClassWorld( cliRequest.classWorld )
623 .setRealm( containerRealm ).setClassPathScanning( PlexusConstants.SCANNING_INDEX ).setAutoWiring( true )
624 .setJSR250Lifecycle( true ).setName( "maven" );
625
626 Set<String> exportedArtifacts = new HashSet<>( coreEntry.getExportedArtifacts() );
627 Set<String> exportedPackages = new HashSet<>( coreEntry.getExportedPackages() );
628 for ( CoreExtensionEntry extension : extensions )
629 {
630 exportedArtifacts.addAll( extension.getExportedArtifacts() );
631 exportedPackages.addAll( extension.getExportedPackages() );
632 }
633
634 final CoreExports exports = new CoreExports( containerRealm, exportedArtifacts, exportedPackages );
635
636 DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
637 {
638 @Override
639 protected void configure()
640 {
641 bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
642 bind( CoreExports.class ).toInstance( exports );
643 }
644 } );
645
646
647 container.setLookupRealm( null );
648 Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
649
650 container.setLoggerManager( plexusLoggerManager );
651
652 for ( CoreExtensionEntry extension : extensions )
653 {
654 container.discoverComponents( extension.getClassRealm(), new SessionScopeModule( container ),
655 new MojoExecutionScopeModule( container ) );
656 }
657
658 customizeContainer( container );
659
660 container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
661
662 eventSpyDispatcher = container.lookup( EventSpyDispatcher.class );
663
664 DefaultEventSpyContext eventSpyContext = new DefaultEventSpyContext();
665 Map<String, Object> data = eventSpyContext.getData();
666 data.put( "plexus", container );
667 data.put( "workingDirectory", cliRequest.workingDirectory );
668 data.put( "systemProperties", cliRequest.systemProperties );
669 data.put( "userProperties", cliRequest.userProperties );
670 data.put( "versionProperties", CLIReportingUtils.getBuildProperties() );
671 eventSpyDispatcher.init( eventSpyContext );
672
673
674 slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
675
676 maven = container.lookup( Maven.class );
677
678 executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
679
680 modelProcessor = createModelProcessor( container );
681
682 configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
683
684 toolchainsBuilder = container.lookup( ToolchainsBuilder.class );
685
686 dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
687
688 return container;
689 }
690
691 private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm,
692 Set<String> providedArtifacts )
693 {
694 if ( cliRequest.multiModuleProjectDirectory == null )
695 {
696 return Collections.emptyList();
697 }
698
699 File extensionsFile = new File( cliRequest.multiModuleProjectDirectory, EXTENSIONS_FILENAME );
700 if ( !extensionsFile.isFile() )
701 {
702 return Collections.emptyList();
703 }
704
705 try
706 {
707 List<CoreExtension> extensions = readCoreExtensionsDescriptor( extensionsFile );
708 if ( extensions.isEmpty() )
709 {
710 return Collections.emptyList();
711 }
712
713 ContainerConfiguration cc = new DefaultContainerConfiguration()
714 .setClassWorld( cliRequest.classWorld )
715 .setRealm( containerRealm )
716 .setClassPathScanning( PlexusConstants.SCANNING_INDEX )
717 .setAutoWiring( true )
718 .setJSR250Lifecycle( true )
719 .setName( "maven" );
720
721 DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
722 {
723 @Override
724 protected void configure()
725 {
726 bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
727 }
728 } );
729
730 try
731 {
732 container.setLookupRealm( null );
733
734 container.setLoggerManager( plexusLoggerManager );
735
736 container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
737
738 Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
739
740 executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
741
742 configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
743
744 configure( cliRequest );
745
746 MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request );
747
748 request = populateRequest( cliRequest, request );
749
750 request = executionRequestPopulator.populateDefaults( request );
751
752 BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
753
754 return Collections.unmodifiableList( resolver.loadCoreExtensions( request, providedArtifacts,
755 extensions ) );
756
757 }
758 finally
759 {
760 executionRequestPopulator = null;
761 container.dispose();
762 }
763 }
764 catch ( RuntimeException e )
765 {
766
767 throw e;
768 }
769 catch ( Exception e )
770 {
771 slf4jLogger.warn( "Failed to read extensions descriptor {}: {}", extensionsFile, e.getMessage() );
772 }
773 return Collections.emptyList();
774 }
775
776 private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile )
777 throws IOException, XmlPullParserException
778 {
779 CoreExtensionsXpp3Reader parser = new CoreExtensionsXpp3Reader();
780
781 try ( InputStream is = new BufferedInputStream( new FileInputStream( extensionsFile ) ) )
782 {
783
784 return parser.read( is ).getExtensions();
785 }
786
787 }
788
789 private ClassRealm setupContainerRealm( ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath,
790 List<CoreExtensionEntry> extensions )
791 throws Exception
792 {
793 if ( !extClassPath.isEmpty() || !extensions.isEmpty() )
794 {
795 ClassRealm extRealm = classWorld.newRealm( "maven.ext", null );
796
797 extRealm.setParentRealm( coreRealm );
798
799 slf4jLogger.debug( "Populating class realm {}", extRealm.getId() );
800
801 for ( File file : extClassPath )
802 {
803 slf4jLogger.debug( " Included {}", file );
804
805 extRealm.addURL( file.toURI().toURL() );
806 }
807
808 for ( CoreExtensionEntry entry : reverse( extensions ) )
809 {
810 Set<String> exportedPackages = entry.getExportedPackages();
811 ClassRealm realm = entry.getClassRealm();
812 for ( String exportedPackage : exportedPackages )
813 {
814 extRealm.importFrom( realm, exportedPackage );
815 }
816 if ( exportedPackages.isEmpty() )
817 {
818
819 extRealm.importFrom( realm, realm.getId() );
820 }
821 }
822
823 return extRealm;
824 }
825
826 return coreRealm;
827 }
828
829 private static <T> List<T> reverse( List<T> list )
830 {
831 List<T> copy = new ArrayList<>( list );
832 Collections.reverse( copy );
833 return copy;
834 }
835
836 private List<File> parseExtClasspath( CliRequest cliRequest )
837 {
838 String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
839 if ( extClassPath == null )
840 {
841 extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
842 }
843
844 List<File> jars = new ArrayList<>();
845
846 if ( StringUtils.isNotEmpty( extClassPath ) )
847 {
848 for ( String jar : StringUtils.split( extClassPath, File.pathSeparator ) )
849 {
850 File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
851
852 slf4jLogger.debug( " Included {}", file );
853
854 jars.add( file );
855 }
856 }
857
858 return jars;
859 }
860
861
862
863
864 private void encryption( CliRequest cliRequest )
865 throws Exception
866 {
867 if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
868 {
869 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
870
871 if ( passwd == null )
872 {
873 Console cons = System.console();
874 char[] password = ( cons == null ) ? null : cons.readPassword( "Master password: " );
875 if ( password != null )
876 {
877
878 passwd = String.copyValueOf( password );
879
880
881 java.util.Arrays.fill( password, ' ' );
882 }
883 }
884
885 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
886
887 System.out.println(
888 cipher.encryptAndDecorate( passwd, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
889
890 throw new ExitException( 0 );
891 }
892 else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
893 {
894 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
895
896 if ( passwd == null )
897 {
898 Console cons = System.console();
899 char[] password = ( cons == null ) ? null : cons.readPassword( "Password: " );
900 if ( password != null )
901 {
902
903 passwd = String.copyValueOf( password );
904
905
906 java.util.Arrays.fill( password, ' ' );
907 }
908 }
909
910 String configurationFile = dispatcher.getConfigurationFile();
911
912 if ( configurationFile.startsWith( "~" ) )
913 {
914 configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
915 }
916
917 String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
918
919 String master = null;
920
921 SettingsSecurity sec = SecUtil.read( file, true );
922 if ( sec != null )
923 {
924 master = sec.getMaster();
925 }
926
927 if ( master == null )
928 {
929 throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
930 }
931
932 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
933 String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
934 System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
935
936 throw new ExitException( 0 );
937 }
938 }
939
940 private void repository( CliRequest cliRequest )
941 throws Exception
942 {
943 if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY ) || Boolean.getBoolean(
944 "maven.legacyLocalRepo" ) )
945 {
946 cliRequest.request.setUseLegacyLocalRepository( true );
947 }
948 }
949
950 private int execute( CliRequest cliRequest )
951 throws MavenExecutionRequestPopulationException
952 {
953 MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request );
954
955 eventSpyDispatcher.onEvent( request );
956
957 MavenExecutionResult result = maven.execute( request );
958
959 eventSpyDispatcher.onEvent( result );
960
961 eventSpyDispatcher.close();
962
963 if ( result.hasExceptions() )
964 {
965 ExceptionHandler handler = new DefaultExceptionHandler();
966
967 Map<String, String> references = new LinkedHashMap<>();
968
969 MavenProject project = null;
970
971 for ( Throwable exception : result.getExceptions() )
972 {
973 ExceptionSummary summary = handler.handleException( exception );
974
975 logSummary( summary, references, "", cliRequest.showErrors );
976
977 if ( project == null && exception instanceof LifecycleExecutionException )
978 {
979 project = ( (LifecycleExecutionException) exception ).getProject();
980 }
981 }
982
983 slf4jLogger.error( "" );
984
985 if ( !cliRequest.showErrors )
986 {
987 slf4jLogger.error( "To see the full stack trace of the errors, re-run Maven with the {} switch.",
988 buffer().strong( "-e" ) );
989 }
990 if ( !slf4jLogger.isDebugEnabled() )
991 {
992 slf4jLogger.error( "Re-run Maven using the {} switch to enable full debug logging.",
993 buffer().strong( "-X" ) );
994 }
995
996 if ( !references.isEmpty() )
997 {
998 slf4jLogger.error( "" );
999 slf4jLogger.error( "For more information about the errors and possible solutions"
1000 + ", please read the following articles:" );
1001
1002 for ( Map.Entry<String, String> entry : references.entrySet() )
1003 {
1004 slf4jLogger.error( "{} {}", buffer().strong( entry.getValue() ), entry.getKey() );
1005 }
1006 }
1007
1008 if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) )
1009 {
1010 slf4jLogger.error( "" );
1011 slf4jLogger.error( "After correcting the problems, you can resume the build with the command" );
1012 slf4jLogger.error( buffer().a( " " ).strong( "mvn <args> -rf "
1013 + getResumeFrom( result.getTopologicallySortedProjects(), project ) ).toString() );
1014 }
1015
1016 if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) )
1017 {
1018 slf4jLogger.info( "Build failures were ignored." );
1019
1020 return 0;
1021 }
1022 else
1023 {
1024 return 1;
1025 }
1026 }
1027 else
1028 {
1029 return 0;
1030 }
1031 }
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 private String getResumeFrom( List<MavenProject> mavenProjects, MavenProject failedProject )
1050 {
1051 for ( MavenProject buildProject : mavenProjects )
1052 {
1053 if ( failedProject.getArtifactId().equals( buildProject.getArtifactId() ) && !failedProject.equals(
1054 buildProject ) )
1055 {
1056 return failedProject.getGroupId() + ":" + failedProject.getArtifactId();
1057 }
1058 }
1059 return ":" + failedProject.getArtifactId();
1060 }
1061
1062 private void logSummary( ExceptionSummary summary, Map<String, String> references, String indent,
1063 boolean showErrors )
1064 {
1065 String referenceKey = "";
1066
1067 if ( StringUtils.isNotEmpty( summary.getReference() ) )
1068 {
1069 referenceKey = references.get( summary.getReference() );
1070 if ( referenceKey == null )
1071 {
1072 referenceKey = "[Help " + ( references.size() + 1 ) + "]";
1073 references.put( summary.getReference(), referenceKey );
1074 }
1075 }
1076
1077 String msg = summary.getMessage();
1078
1079 if ( StringUtils.isNotEmpty( referenceKey ) )
1080 {
1081 if ( msg.indexOf( '\n' ) < 0 )
1082 {
1083 msg += " -> " + buffer().strong( referenceKey );
1084 }
1085 else
1086 {
1087 msg += "\n-> " + buffer().strong( referenceKey );
1088 }
1089 }
1090
1091 String[] lines = msg.split( "(\r\n)|(\r)|(\n)" );
1092 String currentColor = "";
1093
1094 for ( int i = 0; i < lines.length; i++ )
1095 {
1096
1097 String line = currentColor + lines[i];
1098
1099
1100 Matcher matcher = LAST_ANSI_SEQUENCE.matcher( line );
1101 String nextColor = "";
1102 if ( matcher.find() )
1103 {
1104 nextColor = matcher.group( 1 );
1105 if ( ANSI_RESET.equals( nextColor ) )
1106 {
1107
1108 nextColor = "";
1109 }
1110 }
1111
1112
1113 line = indent + line + ( "".equals( nextColor ) ? "" : ANSI_RESET );
1114
1115 if ( ( i == lines.length - 1 ) && ( showErrors
1116 || ( summary.getException() instanceof InternalErrorException ) ) )
1117 {
1118 slf4jLogger.error( line, summary.getException() );
1119 }
1120 else
1121 {
1122 slf4jLogger.error( line );
1123 }
1124
1125 currentColor = nextColor;
1126 }
1127
1128 indent += " ";
1129
1130 for ( ExceptionSummary child : summary.getChildren() )
1131 {
1132 logSummary( child, references, indent, showErrors );
1133 }
1134 }
1135
1136 private static final Pattern LAST_ANSI_SEQUENCE = Pattern.compile( "(\u001B\\[[;\\d]*[ -/]*[@-~])[^\u001B]*$" );
1137
1138 private static final String ANSI_RESET = "\u001B\u005Bm";
1139
1140 private void configure( CliRequest cliRequest )
1141 throws Exception
1142 {
1143
1144
1145
1146
1147
1148
1149 cliRequest.request.setEventSpyDispatcher( eventSpyDispatcher );
1150
1151
1152
1153
1154
1155
1156
1157
1158 int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;
1159
1160 if ( userSuppliedConfigurationProcessorCount == 0 )
1161 {
1162
1163
1164
1165
1166 configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest );
1167 }
1168 else if ( userSuppliedConfigurationProcessorCount == 1 )
1169 {
1170
1171
1172
1173 for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
1174 {
1175 String hint = entry.getKey();
1176 if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
1177 {
1178 ConfigurationProcessor configurationProcessor = entry.getValue();
1179 configurationProcessor.process( cliRequest );
1180 }
1181 }
1182 }
1183 else if ( userSuppliedConfigurationProcessorCount > 1 )
1184 {
1185
1186
1187
1188 StringBuilder sb = new StringBuilder(
1189 String.format( "\nThere can only be one user supplied ConfigurationProcessor, there are %s:\n\n",
1190 userSuppliedConfigurationProcessorCount ) );
1191 for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
1192 {
1193 String hint = entry.getKey();
1194 if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
1195 {
1196 ConfigurationProcessor configurationProcessor = entry.getValue();
1197 sb.append( String.format( "%s\n", configurationProcessor.getClass().getName() ) );
1198 }
1199 }
1200 sb.append( "\n" );
1201 throw new Exception( sb.toString() );
1202 }
1203 }
1204
1205 void toolchains( CliRequest cliRequest )
1206 throws Exception
1207 {
1208 File userToolchainsFile;
1209
1210 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
1211 {
1212 userToolchainsFile =
1213 new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
1214 userToolchainsFile = resolveFile( userToolchainsFile, cliRequest.workingDirectory );
1215
1216 if ( !userToolchainsFile.isFile() )
1217 {
1218 throw new FileNotFoundException(
1219 "The specified user toolchains file does not exist: " + userToolchainsFile );
1220 }
1221 }
1222 else
1223 {
1224 userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
1225 }
1226
1227 File globalToolchainsFile;
1228
1229 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) )
1230 {
1231 globalToolchainsFile =
1232 new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) );
1233 globalToolchainsFile = resolveFile( globalToolchainsFile, cliRequest.workingDirectory );
1234
1235 if ( !globalToolchainsFile.isFile() )
1236 {
1237 throw new FileNotFoundException(
1238 "The specified global toolchains file does not exist: " + globalToolchainsFile );
1239 }
1240 }
1241 else
1242 {
1243 globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
1244 }
1245
1246 cliRequest.request.setGlobalToolchainsFile( globalToolchainsFile );
1247 cliRequest.request.setUserToolchainsFile( userToolchainsFile );
1248
1249 DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
1250 if ( globalToolchainsFile.isFile() )
1251 {
1252 toolchainsRequest.setGlobalToolchainsSource( new FileSource( globalToolchainsFile ) );
1253 }
1254 if ( userToolchainsFile.isFile() )
1255 {
1256 toolchainsRequest.setUserToolchainsSource( new FileSource( userToolchainsFile ) );
1257 }
1258
1259 eventSpyDispatcher.onEvent( toolchainsRequest );
1260
1261 slf4jLogger.debug( "Reading global toolchains from {}",
1262 getLocation( toolchainsRequest.getGlobalToolchainsSource(), globalToolchainsFile ) );
1263 slf4jLogger.debug( "Reading user toolchains from {}",
1264 getLocation( toolchainsRequest.getUserToolchainsSource(), userToolchainsFile ) );
1265
1266 ToolchainsBuildingResult toolchainsResult = toolchainsBuilder.build( toolchainsRequest );
1267
1268 eventSpyDispatcher.onEvent( toolchainsResult );
1269
1270 executionRequestPopulator.populateFromToolchains( cliRequest.request,
1271 toolchainsResult.getEffectiveToolchains() );
1272
1273 if ( !toolchainsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
1274 {
1275 slf4jLogger.warn( "" );
1276 slf4jLogger.warn( "Some problems were encountered while building the effective toolchains" );
1277
1278 for ( Problem problem : toolchainsResult.getProblems() )
1279 {
1280 slf4jLogger.warn( "{} @ {}", problem.getMessage(), problem.getLocation() );
1281 }
1282
1283 slf4jLogger.warn( "" );
1284 }
1285 }
1286
1287 private Object getLocation( Source source, File defaultLocation )
1288 {
1289 if ( source != null )
1290 {
1291 return source.getLocation();
1292 }
1293 return defaultLocation;
1294 }
1295
1296 private MavenExecutionRequest populateRequest( CliRequest cliRequest )
1297 {
1298 return populateRequest( cliRequest, cliRequest.request );
1299 }
1300
1301 @SuppressWarnings( "checkstyle:methodlength" )
1302 private MavenExecutionRequest populateRequest( CliRequest cliRequest, MavenExecutionRequest request )
1303 {
1304 CommandLine commandLine = cliRequest.commandLine;
1305 String workingDirectory = cliRequest.workingDirectory;
1306 boolean quiet = cliRequest.quiet;
1307 boolean showErrors = cliRequest.showErrors;
1308
1309 String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
1310 for ( String deprecatedOption : deprecatedOptions )
1311 {
1312 if ( commandLine.hasOption( deprecatedOption ) )
1313 {
1314 slf4jLogger.warn( "Command line option -{} is deprecated and will be removed in future Maven versions.",
1315 deprecatedOption );
1316 }
1317 }
1318
1319
1320
1321
1322
1323
1324 if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
1325 {
1326 request.setInteractiveMode( false );
1327 }
1328
1329 boolean noSnapshotUpdates = false;
1330 if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
1331 {
1332 noSnapshotUpdates = true;
1333 }
1334
1335
1336
1337
1338
1339 List<String> goals = commandLine.getArgList();
1340
1341 boolean recursive = true;
1342
1343
1344 String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
1345
1346 if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
1347 {
1348 recursive = false;
1349 }
1350
1351 if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
1352 {
1353 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
1354 }
1355 else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
1356 {
1357 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
1358 }
1359 else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
1360 {
1361 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
1362 }
1363
1364 if ( commandLine.hasOption( CLIManager.OFFLINE ) )
1365 {
1366 request.setOffline( true );
1367 }
1368
1369 boolean updateSnapshots = false;
1370
1371 if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
1372 {
1373 updateSnapshots = true;
1374 }
1375
1376 String globalChecksumPolicy = null;
1377
1378 if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
1379 {
1380 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
1381 }
1382 else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
1383 {
1384 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
1385 }
1386
1387 File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
1388
1389
1390
1391
1392
1393 List<String> activeProfiles = new ArrayList<>();
1394
1395 List<String> inactiveProfiles = new ArrayList<>();
1396
1397 if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
1398 {
1399 String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
1400 if ( profileOptionValues != null )
1401 {
1402 for ( String profileOptionValue : profileOptionValues )
1403 {
1404 StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );
1405
1406 while ( profileTokens.hasMoreTokens() )
1407 {
1408 String profileAction = profileTokens.nextToken().trim();
1409
1410 if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
1411 {
1412 inactiveProfiles.add( profileAction.substring( 1 ) );
1413 }
1414 else if ( profileAction.startsWith( "+" ) )
1415 {
1416 activeProfiles.add( profileAction.substring( 1 ) );
1417 }
1418 else
1419 {
1420 activeProfiles.add( profileAction );
1421 }
1422 }
1423 }
1424 }
1425 }
1426
1427 TransferListener transferListener;
1428
1429 if ( quiet || cliRequest.commandLine.hasOption( CLIManager.NO_TRANSFER_PROGRESS ) )
1430 {
1431 transferListener = new QuietMavenTransferListener();
1432 }
1433 else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
1434 {
1435
1436
1437
1438
1439 transferListener = getConsoleTransferListener( cliRequest.commandLine.hasOption( CLIManager.DEBUG ) );
1440 }
1441 else
1442 {
1443 transferListener = getBatchTransferListener();
1444 }
1445
1446 ExecutionListener executionListener = new ExecutionEventLogger();
1447 if ( eventSpyDispatcher != null )
1448 {
1449 executionListener = eventSpyDispatcher.chainListener( executionListener );
1450 }
1451
1452 String alternatePomFile = null;
1453 if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
1454 {
1455 alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
1456 }
1457
1458 request.setBaseDirectory( baseDirectory ).setGoals( goals ).setSystemProperties(
1459 cliRequest.systemProperties ).setUserProperties( cliRequest.userProperties ).setReactorFailureBehavior(
1460 reactorFailureBehaviour )
1461 .setRecursive( recursive )
1462 .setShowErrors( showErrors )
1463 .addActiveProfiles( activeProfiles )
1464 .addInactiveProfiles( inactiveProfiles )
1465 .setExecutionListener( executionListener ).setTransferListener(
1466 transferListener )
1467 .setUpdateSnapshots( updateSnapshots )
1468 .setNoSnapshotUpdates( noSnapshotUpdates )
1469 .setGlobalChecksumPolicy( globalChecksumPolicy )
1470 .setMultiModuleProjectDirectory( cliRequest.multiModuleProjectDirectory );
1471
1472 if ( alternatePomFile != null )
1473 {
1474 File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
1475 if ( pom.isDirectory() )
1476 {
1477 pom = new File( pom, "pom.xml" );
1478 }
1479
1480 request.setPom( pom );
1481 }
1482 else if ( modelProcessor != null )
1483 {
1484 File pom = modelProcessor.locatePom( baseDirectory );
1485
1486 if ( pom.isFile() )
1487 {
1488 request.setPom( pom );
1489 }
1490 }
1491
1492 if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
1493 {
1494 request.setBaseDirectory( request.getPom().getParentFile() );
1495 }
1496
1497 if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
1498 {
1499 request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
1500 }
1501
1502 if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
1503 {
1504 String[] projectOptionValues = commandLine.getOptionValues( CLIManager.PROJECT_LIST );
1505
1506 List<String> inclProjects = new ArrayList<>();
1507 List<String> exclProjects = new ArrayList<>();
1508
1509 if ( projectOptionValues != null )
1510 {
1511 for ( String projectOptionValue : projectOptionValues )
1512 {
1513 StringTokenizer projectTokens = new StringTokenizer( projectOptionValue, "," );
1514
1515 while ( projectTokens.hasMoreTokens() )
1516 {
1517 String projectAction = projectTokens.nextToken().trim();
1518
1519 if ( projectAction.startsWith( "-" ) || projectAction.startsWith( "!" ) )
1520 {
1521 exclProjects.add( projectAction.substring( 1 ) );
1522 }
1523 else if ( projectAction.startsWith( "+" ) )
1524 {
1525 inclProjects.add( projectAction.substring( 1 ) );
1526 }
1527 else
1528 {
1529 inclProjects.add( projectAction );
1530 }
1531 }
1532 }
1533 }
1534
1535 request.setSelectedProjects( inclProjects );
1536 request.setExcludedProjects( exclProjects );
1537 }
1538
1539 if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && !commandLine.hasOption(
1540 CLIManager.ALSO_MAKE_DEPENDENTS ) )
1541 {
1542 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
1543 }
1544 else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE ) && commandLine.hasOption(
1545 CLIManager.ALSO_MAKE_DEPENDENTS ) )
1546 {
1547 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
1548 }
1549 else if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && commandLine.hasOption(
1550 CLIManager.ALSO_MAKE_DEPENDENTS ) )
1551 {
1552 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
1553 }
1554
1555 String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1556
1557 if ( localRepoProperty == null )
1558 {
1559 localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1560 }
1561
1562 if ( localRepoProperty != null )
1563 {
1564 request.setLocalRepositoryPath( localRepoProperty );
1565 }
1566
1567 request.setCacheNotFound( true );
1568 request.setCacheTransferError( false );
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578 final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS )
1579 ? commandLine.getOptionValue( CLIManager.THREADS )
1580 : null;
1581
1582 if ( threadConfiguration != null )
1583 {
1584
1585
1586
1587 request.setBuilderId( "multithreaded" );
1588
1589 if ( threadConfiguration.contains( "C" ) )
1590 {
1591 request.setDegreeOfConcurrency( calculateDegreeOfConcurrencyWithCoreMultiplier( threadConfiguration ) );
1592 }
1593 else
1594 {
1595 request.setDegreeOfConcurrency( Integer.valueOf( threadConfiguration ) );
1596 }
1597 }
1598
1599
1600
1601
1602 if ( commandLine.hasOption( CLIManager.BUILDER ) )
1603 {
1604 request.setBuilderId( commandLine.getOptionValue( CLIManager.BUILDER ) );
1605 }
1606
1607 return request;
1608 }
1609
1610 int calculateDegreeOfConcurrencyWithCoreMultiplier( String threadConfiguration )
1611 {
1612 int procs = Runtime.getRuntime().availableProcessors();
1613 return (int) ( Float.valueOf( threadConfiguration.replace( "C", "" ) ) * procs );
1614 }
1615
1616
1617
1618
1619
1620 static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
1621 {
1622 EnvironmentUtils.addEnvVars( systemProperties );
1623
1624
1625
1626
1627
1628
1629
1630 if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
1631 {
1632 String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
1633
1634 if ( defStrs != null )
1635 {
1636 for ( String defStr : defStrs )
1637 {
1638 setCliProperty( defStr, userProperties );
1639 }
1640 }
1641 }
1642
1643 SystemProperties.addSystemProperties( systemProperties );
1644
1645
1646
1647
1648
1649
1650 Properties buildProperties = CLIReportingUtils.getBuildProperties();
1651
1652 String mavenVersion = buildProperties.getProperty( CLIReportingUtils.BUILD_VERSION_PROPERTY );
1653 systemProperties.setProperty( "maven.version", mavenVersion );
1654
1655 String mavenBuildVersion = CLIReportingUtils.createMavenVersionString( buildProperties );
1656 systemProperties.setProperty( "maven.build.version", mavenBuildVersion );
1657 }
1658
1659 private static void setCliProperty( String property, Properties properties )
1660 {
1661 String name;
1662
1663 String value;
1664
1665 int i = property.indexOf( '=' );
1666
1667 if ( i <= 0 )
1668 {
1669 name = property.trim();
1670
1671 value = "true";
1672 }
1673 else
1674 {
1675 name = property.substring( 0, i ).trim();
1676
1677 value = property.substring( i + 1 );
1678 }
1679
1680 properties.setProperty( name, value );
1681
1682
1683
1684
1685
1686
1687 System.setProperty( name, value );
1688 }
1689
1690 static class ExitException
1691 extends Exception
1692 {
1693 int exitCode;
1694
1695 ExitException( int exitCode )
1696 {
1697 this.exitCode = exitCode;
1698 }
1699 }
1700
1701
1702
1703
1704
1705 protected TransferListener getConsoleTransferListener( boolean printResourceNames )
1706 {
1707 return new ConsoleMavenTransferListener( System.out, printResourceNames );
1708 }
1709
1710 protected TransferListener getBatchTransferListener()
1711 {
1712 return new Slf4jMavenTransferListener();
1713 }
1714
1715 protected void customizeContainer( PlexusContainer container )
1716 {
1717 }
1718
1719 protected ModelProcessor createModelProcessor( PlexusContainer container )
1720 throws ComponentLookupException
1721 {
1722 return container.lookup( ModelProcessor.class );
1723 }
1724 }