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