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