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.settings.building.DefaultSettingsBuildingRequest;
63 import org.apache.maven.settings.building.SettingsBuilder;
64 import org.apache.maven.settings.building.SettingsBuildingRequest;
65 import org.apache.maven.settings.building.SettingsBuildingResult;
66 import org.apache.maven.settings.building.SettingsProblem;
67 import org.apache.maven.settings.building.SettingsSource;
68 import org.codehaus.plexus.ContainerConfiguration;
69 import org.codehaus.plexus.DefaultContainerConfiguration;
70 import org.codehaus.plexus.DefaultPlexusContainer;
71 import org.codehaus.plexus.PlexusConstants;
72 import org.codehaus.plexus.PlexusContainer;
73 import org.codehaus.plexus.classworlds.ClassWorld;
74 import org.codehaus.plexus.classworlds.realm.ClassRealm;
75 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
76 import org.codehaus.plexus.logging.LoggerManager;
77 import org.codehaus.plexus.util.StringUtils;
78 import org.eclipse.aether.transfer.TransferListener;
79 import org.slf4j.ILoggerFactory;
80 import org.slf4j.Logger;
81 import org.slf4j.LoggerFactory;
82 import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
83 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
84 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
85 import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
86 import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
87
88 import com.google.inject.AbstractModule;
89
90
91
92
93
94
95
96 public class MavenCli
97 {
98 public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";
99
100 public static final String THREADS_DEPRECATED = "maven.threads.experimental";
101
102 public static final String userHome = System.getProperty( "user.home" );
103
104 public static final File userMavenConfigurationHome = new File( userHome, ".m2" );
105
106 public static final File DEFAULT_USER_SETTINGS_FILE = new File( userMavenConfigurationHome, "settings.xml" );
107
108 public static final File DEFAULT_GLOBAL_SETTINGS_FILE =
109 new File( System.getProperty( "maven.home", System.getProperty( "user.dir", "" ) ), "conf/settings.xml" );
110
111 public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
112
113 private static final String EXT_CLASS_PATH = "maven.ext.class.path";
114
115 private ClassWorld classWorld;
116
117 private LoggerManager plexusLoggerManager;
118
119 private ILoggerFactory slf4jLoggerFactory;
120
121 private Logger slf4jLogger;
122
123 private EventSpyDispatcher eventSpyDispatcher;
124
125 private ModelProcessor modelProcessor;
126
127 private Maven maven;
128
129 private MavenExecutionRequestPopulator executionRequestPopulator;
130
131 private SettingsBuilder settingsBuilder;
132
133 private DefaultSecDispatcher dispatcher;
134
135 public MavenCli()
136 {
137 this( null );
138 }
139
140
141 public MavenCli( ClassWorld classWorld )
142 {
143 this.classWorld = classWorld;
144 }
145
146 public static void main( String[] args )
147 {
148 int result = main( args, null );
149
150 System.exit( result );
151 }
152
153
154 public static int main( String[] args, ClassWorld classWorld )
155 {
156 MavenCli cli = new MavenCli();
157 return cli.doMain( new CliRequest( args, classWorld ) );
158 }
159
160
161 public static int doMain( String[] args, ClassWorld classWorld )
162 {
163 MavenCli cli = new MavenCli();
164 return cli.doMain( new CliRequest( args, classWorld ) );
165 }
166
167
168 public int doMain( String[] args, String workingDirectory, PrintStream stdout, PrintStream stderr )
169 {
170 PrintStream oldout = System.out;
171 PrintStream olderr = System.err;
172
173 try
174 {
175 if ( stdout != null )
176 {
177 System.setOut( stdout );
178 }
179 if ( stderr != null )
180 {
181 System.setErr( stderr );
182 }
183
184 CliRequest cliRequest = new CliRequest( args, classWorld );
185 cliRequest.workingDirectory = workingDirectory;
186
187 return doMain( cliRequest );
188 }
189 finally
190 {
191 System.setOut( oldout );
192 System.setErr( olderr );
193 }
194 }
195
196
197 public int doMain( CliRequest cliRequest )
198 {
199 PlexusContainer localContainer = null;
200 try
201 {
202 initialize( cliRequest );
203 cli( cliRequest );
204 logging( cliRequest );
205 version( cliRequest );
206 properties( cliRequest );
207 localContainer = container( cliRequest );
208 commands( cliRequest );
209 settings( cliRequest );
210 populateRequest( cliRequest );
211 encryption( cliRequest );
212 repository( cliRequest );
213 return execute( cliRequest );
214 }
215 catch ( ExitException e )
216 {
217 return e.exitCode;
218 }
219 catch ( UnrecognizedOptionException e )
220 {
221
222 return 1;
223 }
224 catch ( BuildAbort e )
225 {
226 CLIReportingUtils.showError( slf4jLogger, "ABORTED", e, cliRequest.showErrors );
227
228 return 2;
229 }
230 catch ( Exception e )
231 {
232 CLIReportingUtils.showError( slf4jLogger, "Error executing Maven.", e, cliRequest.showErrors );
233
234 return 1;
235 }
236 finally
237 {
238 if ( localContainer != null )
239 {
240 localContainer.dispose();
241 }
242 }
243 }
244
245 private void initialize( CliRequest cliRequest )
246 {
247 if ( cliRequest.workingDirectory == null )
248 {
249 cliRequest.workingDirectory = System.getProperty( "user.dir" );
250 }
251
252
253
254
255
256 String mavenHome = System.getProperty( "maven.home" );
257
258 if ( mavenHome != null )
259 {
260 System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
261 }
262 }
263
264 private void cli( CliRequest cliRequest )
265 throws Exception
266 {
267
268
269
270
271 slf4jLogger = new Slf4jStdoutLogger();
272
273 CLIManager cliManager = new CLIManager();
274
275 try
276 {
277 cliRequest.commandLine = cliManager.parse( cliRequest.args );
278 }
279 catch ( ParseException e )
280 {
281 System.err.println( "Unable to parse command line options: " + e.getMessage() );
282 cliManager.displayHelp( System.out );
283 throw e;
284 }
285
286 if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
287 {
288 cliManager.displayHelp( System.out );
289 throw new ExitException( 0 );
290 }
291
292 if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
293 {
294 System.out.println( CLIReportingUtils.showVersion() );
295 throw new ExitException( 0 );
296 }
297 }
298
299
300
301
302 private void logging( CliRequest cliRequest )
303 {
304 cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
305 cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
306 cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );
307
308 slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
309 Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration( slf4jLoggerFactory );
310
311 if ( cliRequest.debug )
312 {
313 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
314 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.DEBUG );
315 }
316 else if ( cliRequest.quiet )
317 {
318 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
319 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.ERROR );
320 }
321 else
322 {
323 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_INFO );
324 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.INFO );
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;
504 char[] password;
505 if ( ( cons = System.console() ) != null
506 && ( password = cons.readPassword( "Master password: " ) ) != null )
507 {
508
509 passwd = String.copyValueOf( password );
510
511
512 java.util.Arrays.fill( password, ' ' );
513 }
514 }
515
516 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
517
518 System.out.println( cipher.encryptAndDecorate( passwd, 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;
529 char[] password;
530 if ( ( cons = System.console() ) != null
531 && ( password = cons.readPassword( "Password: " ) ) != null )
532 {
533
534 passwd = String.copyValueOf( password );
535
536
537 java.util.Arrays.fill( password, ' ' );
538 }
539 }
540
541 String configurationFile = dispatcher.getConfigurationFile();
542
543 if ( configurationFile.startsWith( "~" ) )
544 {
545 configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
546 }
547
548 String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
549
550 String master = null;
551
552 SettingsSecurity sec = SecUtil.read( file, true );
553 if ( sec != null )
554 {
555 master = sec.getMaster();
556 }
557
558 if ( master == null )
559 {
560 throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
561 }
562
563 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
564 String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
565 System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
566
567 throw new ExitException( 0 );
568 }
569 }
570
571 private void repository( CliRequest cliRequest )
572 throws Exception
573 {
574 if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY ) || 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 && ( showErrors || ( summary.getException() instanceof InternalErrorException ) ) )
693 {
694 slf4jLogger.error( line, summary.getException() );
695 }
696 else
697 {
698 slf4jLogger.error( line );
699 }
700 }
701
702 indent += " ";
703
704 for ( ExceptionSummary child : summary.getChildren() )
705 {
706 logSummary( child, references, indent, showErrors );
707 }
708 }
709
710 private void settings( CliRequest cliRequest )
711 throws Exception
712 {
713 File userSettingsFile;
714
715 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
716 {
717 userSettingsFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS ) );
718 userSettingsFile = resolveFile( userSettingsFile, cliRequest.workingDirectory );
719
720 if ( !userSettingsFile.isFile() )
721 {
722 throw new FileNotFoundException( "The specified user settings file does not exist: "
723 + userSettingsFile );
724 }
725 }
726 else
727 {
728 userSettingsFile = DEFAULT_USER_SETTINGS_FILE;
729 }
730
731 File globalSettingsFile;
732
733 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
734 {
735 globalSettingsFile =
736 new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) );
737 globalSettingsFile = resolveFile( globalSettingsFile, cliRequest.workingDirectory );
738
739 if ( !globalSettingsFile.isFile() )
740 {
741 throw new FileNotFoundException( "The specified global settings file does not exist: "
742 + globalSettingsFile );
743 }
744 }
745 else
746 {
747 globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
748 }
749
750 cliRequest.request.setGlobalSettingsFile( globalSettingsFile );
751 cliRequest.request.setUserSettingsFile( userSettingsFile );
752
753 SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
754 settingsRequest.setGlobalSettingsFile( globalSettingsFile );
755 settingsRequest.setUserSettingsFile( userSettingsFile );
756 settingsRequest.setSystemProperties( cliRequest.systemProperties );
757 settingsRequest.setUserProperties( cliRequest.userProperties );
758
759 eventSpyDispatcher.onEvent( settingsRequest );
760
761 slf4jLogger.debug( "Reading global settings from "
762 + getSettingsLocation( settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile() ) );
763 slf4jLogger.debug( "Reading user settings from "
764 + getSettingsLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
765
766 SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
767
768 eventSpyDispatcher.onEvent( settingsResult );
769
770 executionRequestPopulator.populateFromSettings( cliRequest.request, settingsResult.getEffectiveSettings() );
771
772 if ( !settingsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
773 {
774 slf4jLogger.warn( "" );
775 slf4jLogger.warn( "Some problems were encountered while building the effective settings" );
776
777 for ( SettingsProblem problem : settingsResult.getProblems() )
778 {
779 slf4jLogger.warn( problem.getMessage() + " @ " + problem.getLocation() );
780 }
781
782 slf4jLogger.warn( "" );
783 }
784 }
785
786 private Object getSettingsLocation( SettingsSource source, File file )
787 {
788 if ( source != null )
789 {
790 return source.getLocation();
791 }
792 return file;
793 }
794
795 private MavenExecutionRequest populateRequest( CliRequest cliRequest )
796 {
797 MavenExecutionRequest request = cliRequest.request;
798 CommandLine commandLine = cliRequest.commandLine;
799 String workingDirectory = cliRequest.workingDirectory;
800 boolean quiet = cliRequest.quiet;
801 boolean showErrors = cliRequest.showErrors;
802
803 String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
804 for ( String deprecatedOption : deprecatedOptions )
805 {
806 if ( commandLine.hasOption( deprecatedOption ) )
807 {
808 slf4jLogger.warn( "Command line option -" + deprecatedOption
809 + " is deprecated and will be removed in future Maven versions." );
810 }
811 }
812
813
814
815
816
817
818 if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
819 {
820 request.setInteractiveMode( false );
821 }
822
823 boolean noSnapshotUpdates = false;
824 if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
825 {
826 noSnapshotUpdates = true;
827 }
828
829
830
831
832
833 @SuppressWarnings( "unchecked" )
834 List<String> goals = commandLine.getArgList();
835
836 boolean recursive = true;
837
838
839 String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
840
841 if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
842 {
843 recursive = false;
844 }
845
846 if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
847 {
848 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
849 }
850 else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
851 {
852 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
853 }
854 else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
855 {
856 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
857 }
858
859 if ( commandLine.hasOption( CLIManager.OFFLINE ) )
860 {
861 request.setOffline( true );
862 }
863
864 boolean updateSnapshots = false;
865
866 if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
867 {
868 updateSnapshots = true;
869 }
870
871 String globalChecksumPolicy = null;
872
873 if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
874 {
875 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
876 }
877 else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
878 {
879 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
880 }
881
882 File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
883
884
885
886
887
888 List<String> activeProfiles = new ArrayList<String>();
889
890 List<String> inactiveProfiles = new ArrayList<String>();
891
892 if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
893 {
894 String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
895 if ( profileOptionValues != null )
896 {
897 for ( String profileOptionValue : profileOptionValues )
898 {
899 StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );
900
901 while ( profileTokens.hasMoreTokens() )
902 {
903 String profileAction = profileTokens.nextToken().trim();
904
905 if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
906 {
907 inactiveProfiles.add( profileAction.substring( 1 ) );
908 }
909 else if ( profileAction.startsWith( "+" ) )
910 {
911 activeProfiles.add( profileAction.substring( 1 ) );
912 }
913 else
914 {
915 activeProfiles.add( profileAction );
916 }
917 }
918 }
919 }
920 }
921
922 TransferListener transferListener;
923
924 if ( quiet )
925 {
926 transferListener = new QuietMavenTransferListener();
927 }
928 else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
929 {
930
931
932
933
934 transferListener = getConsoleTransferListener();
935 }
936 else
937 {
938 transferListener = getBatchTransferListener();
939 }
940
941 ExecutionListener executionListener = new ExecutionEventLogger();
942 executionListener = eventSpyDispatcher.chainListener( executionListener );
943
944 String alternatePomFile = null;
945 if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
946 {
947 alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
948 }
949
950 File userToolchainsFile;
951 if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
952 {
953 userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
954 userToolchainsFile = resolveFile( userToolchainsFile, workingDirectory );
955 }
956 else
957 {
958 userToolchainsFile = MavenCli.DEFAULT_USER_TOOLCHAINS_FILE;
959 }
960
961 request.setBaseDirectory( baseDirectory ).setGoals( goals )
962 .setSystemProperties( cliRequest.systemProperties )
963 .setUserProperties( cliRequest.userProperties )
964 .setReactorFailureBehavior( reactorFailureBehaviour )
965 .setRecursive( recursive )
966 .setShowErrors( showErrors )
967 .addActiveProfiles( activeProfiles )
968 .addInactiveProfiles( inactiveProfiles )
969 .setExecutionListener( executionListener )
970 .setTransferListener( transferListener )
971 .setUpdateSnapshots( updateSnapshots )
972 .setNoSnapshotUpdates( noSnapshotUpdates )
973 .setGlobalChecksumPolicy( globalChecksumPolicy )
974 .setUserToolchainsFile( userToolchainsFile );
975
976 if ( alternatePomFile != null )
977 {
978 File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
979 if ( pom.isDirectory() )
980 {
981 pom = new File( pom, "pom.xml" );
982 }
983
984 request.setPom( pom );
985 }
986 else
987 {
988 File pom = modelProcessor.locatePom( baseDirectory );
989
990 if ( pom.isFile() )
991 {
992 request.setPom( pom );
993 }
994 }
995
996 if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
997 {
998 request.setBaseDirectory( request.getPom().getParentFile() );
999 }
1000
1001 if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
1002 {
1003 request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
1004 }
1005
1006 if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
1007 {
1008 String[] projectOptionValues = commandLine.getOptionValues( CLIManager.PROJECT_LIST );
1009
1010 List<String> inclProjects = new ArrayList<String>();
1011 List<String> exclProjects = new ArrayList<String>();
1012
1013 if ( projectOptionValues != null )
1014 {
1015 for ( String projectOptionValue : projectOptionValues )
1016 {
1017 StringTokenizer projectTokens = new StringTokenizer( projectOptionValue, "," );
1018
1019 while ( projectTokens.hasMoreTokens() )
1020 {
1021 String projectAction = projectTokens.nextToken().trim();
1022
1023 if ( projectAction.startsWith( "-" ) || projectAction.startsWith( "!" ) )
1024 {
1025 exclProjects.add( projectAction.substring( 1 ) );
1026 }
1027 else if ( projectAction.startsWith( "+" ) )
1028 {
1029 inclProjects.add( projectAction.substring( 1 ) );
1030 }
1031 else
1032 {
1033 inclProjects.add( projectAction );
1034 }
1035 }
1036 }
1037 }
1038
1039 request.setSelectedProjects( inclProjects );
1040 request.setExcludedProjects( exclProjects );
1041 }
1042
1043 if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
1044 && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
1045 {
1046 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
1047 }
1048 else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
1049 && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
1050 {
1051 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
1052 }
1053 else if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
1054 && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
1055 {
1056 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
1057 }
1058
1059 String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1060
1061 if ( localRepoProperty == null )
1062 {
1063 localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1064 }
1065
1066 if ( localRepoProperty != null )
1067 {
1068 request.setLocalRepositoryPath( localRepoProperty );
1069 }
1070
1071
1072 request.setCacheNotFound( true );
1073 request.setCacheTransferError( false );
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083 final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS )
1084 ? commandLine.getOptionValue( CLIManager.THREADS )
1085 : request.getSystemProperties().getProperty(
1086 MavenCli.THREADS_DEPRECATED );
1087
1088 if ( threadConfiguration != null )
1089 {
1090
1091
1092
1093 request.setBuilderId( "multithreaded" );
1094
1095 if ( threadConfiguration.contains( "C" ) )
1096 {
1097 request.setDegreeOfConcurrency( calculateDegreeOfConcurrencyWithCoreMultiplier( threadConfiguration ) );
1098 }
1099 else
1100 {
1101 request.setDegreeOfConcurrency( Integer.valueOf( threadConfiguration ) );
1102 }
1103 }
1104
1105
1106
1107
1108 if ( commandLine.hasOption( CLIManager.BUILDER ) )
1109 {
1110 request.setBuilderId( commandLine.getOptionValue( CLIManager.BUILDER ) );
1111 }
1112
1113 return request;
1114 }
1115
1116 int calculateDegreeOfConcurrencyWithCoreMultiplier( String threadConfiguration )
1117 {
1118 return (int) ( Float.valueOf( threadConfiguration.replace( "C", "" ) ) * Runtime.getRuntime().availableProcessors() );
1119 }
1120
1121 static File resolveFile( File file, String workingDirectory )
1122 {
1123 if ( file == null )
1124 {
1125 return null;
1126 }
1127 else if ( file.isAbsolute() )
1128 {
1129 return file;
1130 }
1131 else if ( file.getPath().startsWith( File.separator ) )
1132 {
1133
1134 return file.getAbsoluteFile();
1135 }
1136 else
1137 {
1138 return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
1139 }
1140 }
1141
1142
1143
1144
1145
1146 static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
1147 {
1148 EnvironmentUtils.addEnvVars( systemProperties );
1149
1150
1151
1152
1153
1154
1155
1156 if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
1157 {
1158 String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
1159
1160 if ( defStrs != null )
1161 {
1162 for ( String defStr : defStrs )
1163 {
1164 setCliProperty( defStr, userProperties );
1165 }
1166 }
1167 }
1168
1169 systemProperties.putAll( System.getProperties() );
1170
1171
1172
1173
1174
1175
1176 Properties buildProperties = CLIReportingUtils.getBuildProperties();
1177
1178 String mavenVersion = buildProperties.getProperty( CLIReportingUtils.BUILD_VERSION_PROPERTY );
1179 systemProperties.setProperty( "maven.version", mavenVersion );
1180
1181 String mavenBuildVersion = CLIReportingUtils.createMavenVersionString( buildProperties );
1182 systemProperties.setProperty( "maven.build.version", mavenBuildVersion );
1183 }
1184
1185 private static void setCliProperty( String property, Properties properties )
1186 {
1187 String name;
1188
1189 String value;
1190
1191 int i = property.indexOf( "=" );
1192
1193 if ( i <= 0 )
1194 {
1195 name = property.trim();
1196
1197 value = "true";
1198 }
1199 else
1200 {
1201 name = property.substring( 0, i ).trim();
1202
1203 value = property.substring( i + 1 );
1204 }
1205
1206 properties.setProperty( name, value );
1207
1208
1209
1210
1211
1212
1213 System.setProperty( name, value );
1214 }
1215
1216 static class CliRequest
1217 {
1218 String[] args;
1219 CommandLine commandLine;
1220 ClassWorld classWorld;
1221 String workingDirectory;
1222 boolean debug;
1223 boolean quiet;
1224 boolean showErrors = true;
1225 Properties userProperties = new Properties();
1226 Properties systemProperties = new Properties();
1227 MavenExecutionRequest request;
1228
1229 CliRequest( String[] args, ClassWorld classWorld )
1230 {
1231 this.args = args;
1232 this.classWorld = classWorld;
1233 this.request = new DefaultMavenExecutionRequest();
1234 }
1235 }
1236
1237 static class ExitException
1238 extends Exception
1239 {
1240
1241 public int exitCode;
1242
1243 public ExitException( int exitCode )
1244 {
1245 this.exitCode = exitCode;
1246 }
1247
1248 }
1249
1250
1251
1252
1253
1254 protected TransferListener getConsoleTransferListener()
1255 {
1256 return new ConsoleMavenTransferListener( System.out );
1257 }
1258
1259 protected TransferListener getBatchTransferListener()
1260 {
1261 return new Slf4jMavenTransferListener();
1262 }
1263
1264 protected void customizeContainer( PlexusContainer container )
1265 {
1266 }
1267
1268 protected ModelProcessor createModelProcessor( PlexusContainer container )
1269 throws ComponentLookupException
1270 {
1271 return container.lookup( ModelProcessor.class );
1272 }
1273 }