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