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 java.io.Console;
23 import java.io.File;
24 import java.io.FileNotFoundException;
25 import java.io.FileOutputStream;
26 import java.io.PrintStream;
27 import java.util.ArrayList;
28 import java.util.LinkedHashMap;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.Properties;
32 import java.util.StringTokenizer;
33
34 import org.apache.commons.cli.CommandLine;
35 import org.apache.commons.cli.ParseException;
36 import org.apache.commons.cli.UnrecognizedOptionException;
37 import org.apache.maven.BuildAbort;
38 import org.apache.maven.InternalErrorException;
39 import org.apache.maven.Maven;
40 import org.apache.maven.cli.event.DefaultEventSpyContext;
41 import org.apache.maven.cli.event.ExecutionEventLogger;
42 import org.apache.maven.cli.logging.Slf4jConfiguration;
43 import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
44 import org.apache.maven.cli.logging.Slf4jLoggerManager;
45 import org.apache.maven.cli.logging.Slf4jStdoutLogger;
46 import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
47 import org.apache.maven.cli.transfer.QuietMavenTransferListener;
48 import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
49 import org.apache.maven.eventspy.internal.EventSpyDispatcher;
50 import org.apache.maven.exception.DefaultExceptionHandler;
51 import org.apache.maven.exception.ExceptionHandler;
52 import org.apache.maven.exception.ExceptionSummary;
53 import org.apache.maven.execution.DefaultMavenExecutionRequest;
54 import org.apache.maven.execution.ExecutionListener;
55 import org.apache.maven.execution.MavenExecutionRequest;
56 import org.apache.maven.execution.MavenExecutionRequestPopulator;
57 import org.apache.maven.execution.MavenExecutionResult;
58 import org.apache.maven.lifecycle.LifecycleExecutionException;
59 import org.apache.maven.model.building.ModelProcessor;
60 import org.apache.maven.project.MavenProject;
61 import org.apache.maven.properties.internal.EnvironmentUtils;
62 import org.apache.maven.properties.internal.SystemProperties;
63 import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
64 import org.apache.maven.settings.building.SettingsBuilder;
65 import org.apache.maven.settings.building.SettingsBuildingRequest;
66 import org.apache.maven.settings.building.SettingsBuildingResult;
67 import org.apache.maven.settings.building.SettingsProblem;
68 import org.apache.maven.settings.building.SettingsSource;
69 import org.codehaus.plexus.ContainerConfiguration;
70 import org.codehaus.plexus.DefaultContainerConfiguration;
71 import org.codehaus.plexus.DefaultPlexusContainer;
72 import org.codehaus.plexus.PlexusConstants;
73 import org.codehaus.plexus.PlexusContainer;
74 import org.codehaus.plexus.classworlds.ClassWorld;
75 import org.codehaus.plexus.classworlds.realm.ClassRealm;
76 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
77 import org.codehaus.plexus.logging.LoggerManager;
78 import org.codehaus.plexus.util.StringUtils;
79 import org.eclipse.aether.transfer.TransferListener;
80 import org.slf4j.ILoggerFactory;
81 import org.slf4j.Logger;
82 import org.slf4j.LoggerFactory;
83 import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
84 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
85 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
86 import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
87 import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
88
89 import com.google.inject.AbstractModule;
90
91
92
93
94
95
96
97 public class MavenCli
98 {
99 public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";
100
101 public static final String THREADS_DEPRECATED = "maven.threads.experimental";
102
103 @SuppressWarnings( "checkstyle:constantname" )
104 public static final String userHome = System.getProperty( "user.home" );
105
106 @SuppressWarnings( "checkstyle:constantname" )
107 public static final File userMavenConfigurationHome = new File( userHome, ".m2" );
108
109 public static final File DEFAULT_USER_SETTINGS_FILE = new File( userMavenConfigurationHome, "settings.xml" );
110
111 public static final File DEFAULT_GLOBAL_SETTINGS_FILE =
112 new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/settings.xml" );
113
114 public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
115
116 private static final String EXT_CLASS_PATH = "maven.ext.class.path";
117
118 private ClassWorld classWorld;
119
120 private LoggerManager plexusLoggerManager;
121
122 private ILoggerFactory slf4jLoggerFactory;
123
124 private Logger slf4jLogger;
125
126 private EventSpyDispatcher eventSpyDispatcher;
127
128 private ModelProcessor modelProcessor;
129
130 private Maven maven;
131
132 private MavenExecutionRequestPopulator executionRequestPopulator;
133
134 private SettingsBuilder settingsBuilder;
135
136 private DefaultSecDispatcher dispatcher;
137
138 public MavenCli()
139 {
140 this( null );
141 }
142
143
144 public MavenCli( ClassWorld classWorld )
145 {
146 this.classWorld = classWorld;
147 }
148
149 public static void main( String[] args )
150 {
151 int result = main( args, null );
152
153 System.exit( result );
154 }
155
156
157 public static int main( String[] args, ClassWorld classWorld )
158 {
159 MavenCli cli = new MavenCli();
160 return cli.doMain( new CliRequest( args, classWorld ) );
161 }
162
163
164 public static int doMain( String[] args, ClassWorld classWorld )
165 {
166 MavenCli cli = new MavenCli();
167 return cli.doMain( new CliRequest( args, classWorld ) );
168 }
169
170
171 public int doMain( String[] args, String workingDirectory, PrintStream stdout, PrintStream stderr )
172 {
173 PrintStream oldout = System.out;
174 PrintStream olderr = System.err;
175
176 try
177 {
178 if ( stdout != null )
179 {
180 System.setOut( stdout );
181 }
182 if ( stderr != null )
183 {
184 System.setErr( stderr );
185 }
186
187 CliRequest cliRequest = new CliRequest( args, classWorld );
188 cliRequest.workingDirectory = workingDirectory;
189
190 return doMain( cliRequest );
191 }
192 finally
193 {
194 System.setOut( oldout );
195 System.setErr( olderr );
196 }
197 }
198
199
200 public int doMain( CliRequest cliRequest )
201 {
202 PlexusContainer localContainer = null;
203 try
204 {
205 initialize( cliRequest );
206 cli( cliRequest );
207 logging( cliRequest );
208 version( cliRequest );
209 properties( cliRequest );
210 localContainer = container( cliRequest );
211 commands( cliRequest );
212 settings( cliRequest );
213 populateRequest( cliRequest );
214 encryption( cliRequest );
215 repository( cliRequest );
216 return execute( cliRequest );
217 }
218 catch ( ExitException e )
219 {
220 return e.exitCode;
221 }
222 catch ( UnrecognizedOptionException e )
223 {
224
225 return 1;
226 }
227 catch ( BuildAbort e )
228 {
229 CLIReportingUtils.showError( slf4jLogger, "ABORTED", e, cliRequest.showErrors );
230
231 return 2;
232 }
233 catch ( Exception e )
234 {
235 CLIReportingUtils.showError( slf4jLogger, "Error executing Maven.", e, cliRequest.showErrors );
236
237 return 1;
238 }
239 finally
240 {
241 if ( localContainer != null )
242 {
243 localContainer.dispose();
244 }
245 }
246 }
247
248 private void initialize( CliRequest cliRequest )
249 {
250 if ( cliRequest.workingDirectory == null )
251 {
252 cliRequest.workingDirectory = System.getProperty( "user.dir" );
253 }
254
255
256
257
258
259 String mavenHome = System.getProperty( "maven.home" );
260
261 if ( mavenHome != null )
262 {
263 System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
264 }
265 }
266
267 private void cli( CliRequest cliRequest )
268 throws Exception
269 {
270
271
272
273
274 slf4jLogger = new Slf4jStdoutLogger();
275
276 CLIManager cliManager = new CLIManager();
277
278 try
279 {
280 cliRequest.commandLine = cliManager.parse( cliRequest.args );
281 }
282 catch ( ParseException e )
283 {
284 System.err.println( "Unable to parse command line options: " + e.getMessage() );
285 cliManager.displayHelp( System.out );
286 throw e;
287 }
288
289 if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
290 {
291 cliManager.displayHelp( System.out );
292 throw new ExitException( 0 );
293 }
294
295 if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
296 {
297 System.out.println( CLIReportingUtils.showVersion() );
298 throw new ExitException( 0 );
299 }
300 }
301
302
303
304
305 private void logging( CliRequest cliRequest )
306 {
307 cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
308 cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
309 cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );
310
311 slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
312 Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration( slf4jLoggerFactory );
313
314 if ( cliRequest.debug )
315 {
316 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
317 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.DEBUG );
318 }
319 else if ( cliRequest.quiet )
320 {
321 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
322 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.ERROR );
323 }
324
325
326
327 if ( cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
328 {
329 File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
330 logFile = resolveFile( logFile, cliRequest.workingDirectory );
331
332
333 try
334 {
335 PrintStream ps = new PrintStream( new FileOutputStream( logFile ) );
336 System.setOut( ps );
337 System.setErr( ps );
338 }
339 catch ( FileNotFoundException e )
340 {
341
342
343
344 }
345 }
346
347 slf4jConfiguration.activate();
348
349 plexusLoggerManager = new Slf4jLoggerManager();
350 slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
351 }
352
353 private void version( CliRequest cliRequest )
354 {
355 if ( cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.SHOW_VERSION ) )
356 {
357 System.out.println( CLIReportingUtils.showVersion() );
358 }
359 }
360
361 private void commands( CliRequest cliRequest )
362 {
363 if ( cliRequest.showErrors )
364 {
365 slf4jLogger.info( "Error stacktraces are turned on." );
366 }
367
368 if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
369 {
370 slf4jLogger.info( "Disabling strict checksum verification on all artifact downloads." );
371 }
372 else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
373 {
374 slf4jLogger.info( "Enabling strict checksum verification on all artifact downloads." );
375 }
376 }
377
378 private void properties( CliRequest cliRequest )
379 {
380 populateProperties( cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties );
381 }
382
383 private PlexusContainer container( CliRequest cliRequest )
384 throws Exception
385 {
386 if ( cliRequest.classWorld == null )
387 {
388 cliRequest.classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
389 }
390
391 DefaultPlexusContainer container;
392
393 ContainerConfiguration cc = new DefaultContainerConfiguration()
394 .setClassWorld( cliRequest.classWorld )
395 .setRealm( setupContainerRealm( cliRequest ) )
396 .setClassPathScanning( PlexusConstants.SCANNING_INDEX )
397 .setAutoWiring( true )
398 .setName( "maven" );
399
400 container = new DefaultPlexusContainer( cc, new AbstractModule()
401 {
402 protected void configure()
403 {
404 bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
405 }
406 } );
407
408
409 container.setLookupRealm( null );
410
411 container.setLoggerManager( plexusLoggerManager );
412
413 customizeContainer( container );
414
415 container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
416
417 Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
418
419 eventSpyDispatcher = container.lookup( EventSpyDispatcher.class );
420
421 DefaultEventSpyContext eventSpyContext = new DefaultEventSpyContext();
422 Map<String, Object> data = eventSpyContext.getData();
423 data.put( "plexus", container );
424 data.put( "workingDirectory", cliRequest.workingDirectory );
425 data.put( "systemProperties", cliRequest.systemProperties );
426 data.put( "userProperties", cliRequest.userProperties );
427 data.put( "versionProperties", CLIReportingUtils.getBuildProperties() );
428 eventSpyDispatcher.init( eventSpyContext );
429
430
431 slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
432
433 maven = container.lookup( Maven.class );
434
435 executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
436
437 modelProcessor = createModelProcessor( container );
438
439 settingsBuilder = container.lookup( SettingsBuilder.class );
440
441 dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
442
443 return container;
444 }
445
446 private ClassRealm setupContainerRealm( CliRequest cliRequest )
447 throws Exception
448 {
449 ClassRealm containerRealm = null;
450
451 String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
452 if ( extClassPath == null )
453 {
454 extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
455 }
456
457 if ( StringUtils.isNotEmpty( extClassPath ) )
458 {
459 String[] jars = StringUtils.split( extClassPath, File.pathSeparator );
460
461 if ( jars.length > 0 )
462 {
463 ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
464 if ( coreRealm == null )
465 {
466 coreRealm = cliRequest.classWorld.getRealms().iterator().next();
467 }
468
469 ClassRealm extRealm = cliRequest.classWorld.newRealm( "maven.ext", null );
470
471 slf4jLogger.debug( "Populating class realm " + extRealm.getId() );
472
473 for ( String jar : jars )
474 {
475 File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
476
477 slf4jLogger.debug( " Included " + file );
478
479 extRealm.addURL( file.toURI().toURL() );
480 }
481
482 extRealm.setParentRealm( coreRealm );
483
484 containerRealm = extRealm;
485 }
486 }
487
488 return containerRealm;
489 }
490
491
492
493
494 private void encryption( CliRequest cliRequest )
495 throws Exception
496 {
497 if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
498 {
499 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
500
501 if ( passwd == null )
502 {
503 Console cons = System.console();
504 char[] password = ( cons == null ) ? null : cons.readPassword( "Master password: " );
505 if ( password != null )
506 {
507
508 passwd = String.copyValueOf( password );
509
510
511 java.util.Arrays.fill( password, ' ' );
512 }
513 }
514
515 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
516
517 System.out.println( cipher.encryptAndDecorate( passwd,
518 DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
519
520 throw new ExitException( 0 );
521 }
522 else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
523 {
524 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
525
526 if ( passwd == null )
527 {
528 Console cons = System.console();
529 char[] password = ( cons == null ) ? null : cons.readPassword( "Password: " );
530 if ( password != null )
531 {
532
533 passwd = String.copyValueOf( password );
534
535
536 java.util.Arrays.fill( password, ' ' );
537 }
538 }
539
540 String configurationFile = dispatcher.getConfigurationFile();
541
542 if ( configurationFile.startsWith( "~" ) )
543 {
544 configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
545 }
546
547 String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
548
549 String master = null;
550
551 SettingsSecurity sec = SecUtil.read( file, true );
552 if ( sec != null )
553 {
554 master = sec.getMaster();
555 }
556
557 if ( master == null )
558 {
559 throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
560 }
561
562 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
563 String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
564 System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
565
566 throw new ExitException( 0 );
567 }
568 }
569
570 private void repository( CliRequest cliRequest )
571 throws Exception
572 {
573 if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY )
574 || Boolean.getBoolean( "maven.legacyLocalRepo" ) )
575 {
576 cliRequest.request.setUseLegacyLocalRepository( true );
577 }
578 }
579
580 private int execute( CliRequest cliRequest )
581 {
582 eventSpyDispatcher.onEvent( cliRequest.request );
583
584 MavenExecutionResult result = maven.execute( cliRequest.request );
585
586 eventSpyDispatcher.onEvent( result );
587
588 eventSpyDispatcher.close();
589
590 if ( result.hasExceptions() )
591 {
592 ExceptionHandler handler = new DefaultExceptionHandler();
593
594 Map<String, String> references = new LinkedHashMap<String, String>();
595
596 MavenProject project = null;
597
598 for ( Throwable exception : result.getExceptions() )
599 {
600 ExceptionSummary summary = handler.handleException( exception );
601
602 logSummary( summary, references, "", cliRequest.showErrors );
603
604 if ( project == null && exception instanceof LifecycleExecutionException )
605 {
606 project = ( (LifecycleExecutionException) exception ).getProject();
607 }
608 }
609
610 slf4jLogger.error( "" );
611
612 if ( !cliRequest.showErrors )
613 {
614 slf4jLogger.error( "To see the full stack trace of the errors, re-run Maven with the -e switch." );
615 }
616 if ( !slf4jLogger.isDebugEnabled() )
617 {
618 slf4jLogger.error( "Re-run Maven using the -X switch to enable full debug logging." );
619 }
620
621 if ( !references.isEmpty() )
622 {
623 slf4jLogger.error( "" );
624 slf4jLogger.error( "For more information about the errors and possible solutions"
625 + ", please read the following articles:" );
626
627 for ( Map.Entry<String, String> entry : references.entrySet() )
628 {
629 slf4jLogger.error( entry.getValue() + " " + entry.getKey() );
630 }
631 }
632
633 if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) )
634 {
635 slf4jLogger.error( "" );
636 slf4jLogger.error( "After correcting the problems, you can resume the build with the command" );
637 slf4jLogger.error( " mvn <goals> -rf :" + project.getArtifactId() );
638 }
639
640 if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) )
641 {
642 slf4jLogger.info( "Build failures were ignored." );
643
644 return 0;
645 }
646 else
647 {
648 return 1;
649 }
650 }
651 else
652 {
653 return 0;
654 }
655 }
656
657 private void logSummary( ExceptionSummary summary, Map<String, String> references, String indent,
658 boolean showErrors )
659 {
660 String referenceKey = "";
661
662 if ( StringUtils.isNotEmpty( summary.getReference() ) )
663 {
664 referenceKey = references.get( summary.getReference() );
665 if ( referenceKey == null )
666 {
667 referenceKey = "[Help " + ( references.size() + 1 ) + "]";
668 references.put( summary.getReference(), referenceKey );
669 }
670 }
671
672 String msg = summary.getMessage();
673
674 if ( StringUtils.isNotEmpty( referenceKey ) )
675 {
676 if ( msg.indexOf( '\n' ) < 0 )
677 {
678 msg += " -> " + referenceKey;
679 }
680 else
681 {
682 msg += "\n-> " + referenceKey;
683 }
684 }
685
686 String[] lines = msg.split( "(\r\n)|(\r)|(\n)" );
687
688 for ( int i = 0; i < lines.length; i++ )
689 {
690 String line = indent + lines[i].trim();
691
692 if ( ( i == lines.length - 1 )
693 && ( showErrors || ( summary.getException() instanceof InternalErrorException ) ) )
694 {
695 slf4jLogger.error( line, summary.getException() );
696 }
697 else
698 {
699 slf4jLogger.error( line );
700 }
701 }
702
703 indent += " ";
704
705 for ( ExceptionSummary child : summary.getChildren() )
706 {
707 logSummary( child, references, indent, showErrors );
708 }
709 }
710
711 @SuppressWarnings( "checkstyle:methodlength" )
712 private void settings( CliRequest cliRequest )
713 throws Exception
714 {
715 File userSettingsFile;
716
717 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
718 {
719 userSettingsFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS ) );
720 userSettingsFile = resolveFile( userSettingsFile, cliRequest.workingDirectory );
721
722 if ( !userSettingsFile.isFile() )
723 {
724 throw new FileNotFoundException( "The specified user settings file does not exist: "
725 + userSettingsFile );
726 }
727 }
728 else
729 {
730 userSettingsFile = DEFAULT_USER_SETTINGS_FILE;
731 }
732
733 File globalSettingsFile;
734
735 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
736 {
737 globalSettingsFile =
738 new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) );
739 globalSettingsFile = resolveFile( globalSettingsFile, cliRequest.workingDirectory );
740
741 if ( !globalSettingsFile.isFile() )
742 {
743 throw new FileNotFoundException( "The specified global settings file does not exist: "
744 + globalSettingsFile );
745 }
746 }
747 else
748 {
749 globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
750 }
751
752 cliRequest.request.setGlobalSettingsFile( globalSettingsFile );
753 cliRequest.request.setUserSettingsFile( userSettingsFile );
754
755 SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
756 settingsRequest.setGlobalSettingsFile( globalSettingsFile );
757 settingsRequest.setUserSettingsFile( userSettingsFile );
758 settingsRequest.setSystemProperties( cliRequest.systemProperties );
759 settingsRequest.setUserProperties( cliRequest.userProperties );
760
761 eventSpyDispatcher.onEvent( settingsRequest );
762
763 slf4jLogger.debug( "Reading global settings from "
764 + getSettingsLocation( settingsRequest.getGlobalSettingsSource(),
765 settingsRequest.getGlobalSettingsFile() ) );
766 slf4jLogger.debug( "Reading user settings from "
767 + getSettingsLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
768
769 SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
770
771 eventSpyDispatcher.onEvent( settingsResult );
772
773 executionRequestPopulator.populateFromSettings( cliRequest.request, settingsResult.getEffectiveSettings() );
774
775 if ( !settingsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
776 {
777 slf4jLogger.warn( "" );
778 slf4jLogger.warn( "Some problems were encountered while building the effective settings" );
779
780 for ( SettingsProblem problem : settingsResult.getProblems() )
781 {
782 slf4jLogger.warn( problem.getMessage() + " @ " + problem.getLocation() );
783 }
784
785 slf4jLogger.warn( "" );
786 }
787 }
788
789 private Object getSettingsLocation( SettingsSource source, File file )
790 {
791 if ( source != null )
792 {
793 return source.getLocation();
794 }
795 return file;
796 }
797
798 private MavenExecutionRequest populateRequest( CliRequest cliRequest )
799 {
800 MavenExecutionRequest request = cliRequest.request;
801 CommandLine commandLine = cliRequest.commandLine;
802 String workingDirectory = cliRequest.workingDirectory;
803 boolean quiet = cliRequest.quiet;
804 boolean showErrors = cliRequest.showErrors;
805
806 String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
807 for ( String deprecatedOption : deprecatedOptions )
808 {
809 if ( commandLine.hasOption( deprecatedOption ) )
810 {
811 slf4jLogger.warn( "Command line option -" + deprecatedOption
812 + " is deprecated and will be removed in future Maven versions." );
813 }
814 }
815
816
817
818
819
820
821 if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
822 {
823 request.setInteractiveMode( false );
824 }
825
826 boolean noSnapshotUpdates = false;
827 if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
828 {
829 noSnapshotUpdates = true;
830 }
831
832
833
834
835
836 @SuppressWarnings( "unchecked" )
837 List<String> goals = commandLine.getArgList();
838
839 boolean recursive = true;
840
841
842 String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
843
844 if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
845 {
846 recursive = false;
847 }
848
849 if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
850 {
851 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
852 }
853 else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
854 {
855 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
856 }
857 else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
858 {
859 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
860 }
861
862 if ( commandLine.hasOption( CLIManager.OFFLINE ) )
863 {
864 request.setOffline( true );
865 }
866
867 boolean updateSnapshots = false;
868
869 if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
870 {
871 updateSnapshots = true;
872 }
873
874 String globalChecksumPolicy = null;
875
876 if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
877 {
878 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
879 }
880 else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
881 {
882 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
883 }
884
885 File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
886
887
888
889
890
891 List<String> activeProfiles = new ArrayList<String>();
892
893 List<String> inactiveProfiles = new ArrayList<String>();
894
895 if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
896 {
897 String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
898 if ( profileOptionValues != null )
899 {
900 for ( String profileOptionValue : profileOptionValues )
901 {
902 StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );
903
904 while ( profileTokens.hasMoreTokens() )
905 {
906 String profileAction = profileTokens.nextToken().trim();
907
908 if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
909 {
910 inactiveProfiles.add( profileAction.substring( 1 ) );
911 }
912 else if ( profileAction.startsWith( "+" ) )
913 {
914 activeProfiles.add( profileAction.substring( 1 ) );
915 }
916 else
917 {
918 activeProfiles.add( profileAction );
919 }
920 }
921 }
922 }
923 }
924
925 TransferListener transferListener;
926
927 if ( quiet )
928 {
929 transferListener = new QuietMavenTransferListener();
930 }
931 else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
932 {
933
934
935
936
937 transferListener = getConsoleTransferListener();
938 }
939 else
940 {
941 transferListener = getBatchTransferListener();
942 }
943
944 ExecutionListener executionListener = new ExecutionEventLogger();
945 executionListener = eventSpyDispatcher.chainListener( executionListener );
946
947 String alternatePomFile = null;
948 if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
949 {
950 alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
951 }
952
953 File userToolchainsFile;
954 if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
955 {
956 userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
957 userToolchainsFile = resolveFile( userToolchainsFile, workingDirectory );
958 }
959 else
960 {
961 userToolchainsFile = MavenCli.DEFAULT_USER_TOOLCHAINS_FILE;
962 }
963
964 request.setBaseDirectory( baseDirectory ).setGoals( goals )
965 .setSystemProperties( cliRequest.systemProperties )
966 .setUserProperties( cliRequest.userProperties )
967 .setReactorFailureBehavior( reactorFailureBehaviour )
968 .setRecursive( recursive )
969 .setShowErrors( showErrors )
970 .addActiveProfiles( activeProfiles )
971 .addInactiveProfiles( inactiveProfiles )
972 .setExecutionListener( executionListener )
973 .setTransferListener( transferListener )
974 .setUpdateSnapshots( updateSnapshots )
975 .setNoSnapshotUpdates( noSnapshotUpdates )
976 .setGlobalChecksumPolicy( globalChecksumPolicy )
977 .setUserToolchainsFile( userToolchainsFile );
978
979 if ( alternatePomFile != null )
980 {
981 File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
982 if ( pom.isDirectory() )
983 {
984 pom = new File( pom, "pom.xml" );
985 }
986
987 request.setPom( pom );
988 }
989 else
990 {
991 File pom = modelProcessor.locatePom( baseDirectory );
992
993 if ( pom.isFile() )
994 {
995 request.setPom( pom );
996 }
997 }
998
999 if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
1000 {
1001 request.setBaseDirectory( request.getPom().getParentFile() );
1002 }
1003
1004 if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
1005 {
1006 request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
1007 }
1008
1009 if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
1010 {
1011 String[] projectOptionValues = commandLine.getOptionValues( CLIManager.PROJECT_LIST );
1012
1013 List<String> inclProjects = new ArrayList<String>();
1014 List<String> exclProjects = new ArrayList<String>();
1015
1016 if ( projectOptionValues != null )
1017 {
1018 for ( String projectOptionValue : projectOptionValues )
1019 {
1020 StringTokenizer projectTokens = new StringTokenizer( projectOptionValue, "," );
1021
1022 while ( projectTokens.hasMoreTokens() )
1023 {
1024 String projectAction = projectTokens.nextToken().trim();
1025
1026 if ( projectAction.startsWith( "-" ) || projectAction.startsWith( "!" ) )
1027 {
1028 exclProjects.add( projectAction.substring( 1 ) );
1029 }
1030 else if ( projectAction.startsWith( "+" ) )
1031 {
1032 inclProjects.add( projectAction.substring( 1 ) );
1033 }
1034 else
1035 {
1036 inclProjects.add( projectAction );
1037 }
1038 }
1039 }
1040 }
1041
1042 request.setSelectedProjects( inclProjects );
1043 request.setExcludedProjects( exclProjects );
1044 }
1045
1046 if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
1047 && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
1048 {
1049 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
1050 }
1051 else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
1052 && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
1053 {
1054 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
1055 }
1056 else if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
1057 && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
1058 {
1059 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
1060 }
1061
1062 String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1063
1064 if ( localRepoProperty == null )
1065 {
1066 localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1067 }
1068
1069 if ( localRepoProperty != null )
1070 {
1071 request.setLocalRepositoryPath( localRepoProperty );
1072 }
1073
1074
1075 request.setCacheNotFound( true );
1076 request.setCacheTransferError( false );
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086 final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS )
1087 ? commandLine.getOptionValue( CLIManager.THREADS )
1088 : request.getSystemProperties().getProperty(
1089 MavenCli.THREADS_DEPRECATED );
1090
1091 if ( threadConfiguration != null )
1092 {
1093
1094
1095
1096 request.setBuilderId( "multithreaded" );
1097
1098 if ( threadConfiguration.contains( "C" ) )
1099 {
1100 request.setDegreeOfConcurrency( calculateDegreeOfConcurrencyWithCoreMultiplier( threadConfiguration ) );
1101 }
1102 else
1103 {
1104 request.setDegreeOfConcurrency( Integer.valueOf( threadConfiguration ) );
1105 }
1106 }
1107
1108
1109
1110
1111 if ( commandLine.hasOption( CLIManager.BUILDER ) )
1112 {
1113 request.setBuilderId( commandLine.getOptionValue( CLIManager.BUILDER ) );
1114 }
1115
1116 return request;
1117 }
1118
1119 int calculateDegreeOfConcurrencyWithCoreMultiplier( String threadConfiguration )
1120 {
1121 int procs = Runtime.getRuntime().availableProcessors();
1122 return (int) ( Float.valueOf( threadConfiguration.replace( "C", "" ) ) * procs );
1123 }
1124
1125 static File resolveFile( File file, String workingDirectory )
1126 {
1127 if ( file == null )
1128 {
1129 return null;
1130 }
1131 else if ( file.isAbsolute() )
1132 {
1133 return file;
1134 }
1135 else if ( file.getPath().startsWith( File.separator ) )
1136 {
1137
1138 return file.getAbsoluteFile();
1139 }
1140 else
1141 {
1142 return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
1143 }
1144 }
1145
1146
1147
1148
1149
1150 static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
1151 {
1152 EnvironmentUtils.addEnvVars( systemProperties );
1153
1154
1155
1156
1157
1158
1159
1160 if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
1161 {
1162 String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
1163
1164 if ( defStrs != null )
1165 {
1166 for ( String defStr : defStrs )
1167 {
1168 setCliProperty( defStr, userProperties );
1169 }
1170 }
1171 }
1172
1173 SystemProperties.addSystemProperties( systemProperties );
1174
1175
1176
1177
1178
1179
1180 Properties buildProperties = CLIReportingUtils.getBuildProperties();
1181
1182 String mavenVersion = buildProperties.getProperty( CLIReportingUtils.BUILD_VERSION_PROPERTY );
1183 systemProperties.setProperty( "maven.version", mavenVersion );
1184
1185 String mavenBuildVersion = CLIReportingUtils.createMavenVersionString( buildProperties );
1186 systemProperties.setProperty( "maven.build.version", mavenBuildVersion );
1187 }
1188
1189 private static void setCliProperty( String property, Properties properties )
1190 {
1191 String name;
1192
1193 String value;
1194
1195 int i = property.indexOf( "=" );
1196
1197 if ( i <= 0 )
1198 {
1199 name = property.trim();
1200
1201 value = "true";
1202 }
1203 else
1204 {
1205 name = property.substring( 0, i ).trim();
1206
1207 value = property.substring( i + 1 );
1208 }
1209
1210 properties.setProperty( name, value );
1211
1212
1213
1214
1215
1216
1217 System.setProperty( name, value );
1218 }
1219
1220 static class CliRequest
1221 {
1222 String[] args;
1223 CommandLine commandLine;
1224 ClassWorld classWorld;
1225 String workingDirectory;
1226 boolean debug;
1227 boolean quiet;
1228 boolean showErrors = true;
1229 Properties userProperties = new Properties();
1230 Properties systemProperties = new Properties();
1231 MavenExecutionRequest request;
1232
1233 CliRequest( String[] args, ClassWorld classWorld )
1234 {
1235 this.args = args;
1236 this.classWorld = classWorld;
1237 this.request = new DefaultMavenExecutionRequest();
1238 }
1239 }
1240
1241 static class ExitException
1242 extends Exception
1243 {
1244 @SuppressWarnings( "checkstyle:visibilitymodifier" )
1245 public int exitCode;
1246
1247 public ExitException( int exitCode )
1248 {
1249 this.exitCode = exitCode;
1250 }
1251
1252 }
1253
1254
1255
1256
1257
1258 protected TransferListener getConsoleTransferListener()
1259 {
1260 return new ConsoleMavenTransferListener( System.out );
1261 }
1262
1263 protected TransferListener getBatchTransferListener()
1264 {
1265 return new Slf4jMavenTransferListener();
1266 }
1267
1268 protected void customizeContainer( PlexusContainer container )
1269 {
1270 }
1271
1272 protected ModelProcessor createModelProcessor( PlexusContainer container )
1273 throws ComponentLookupException
1274 {
1275 return container.lookup( ModelProcessor.class );
1276 }
1277 }