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 container.setLoggerManager( new MavenLoggerManager( logger ) );
378
379 customizeContainer( container );
380
381 if ( cliRequest.classWorld == classWorld )
382 {
383 this.container = container;
384 }
385 }
386
387 container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
388
389 Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
390
391 eventSpyDispatcher = container.lookup( EventSpyDispatcher.class );
392
393 DefaultEventSpyContext eventSpyContext = new DefaultEventSpyContext();
394 Map<String, Object> data = eventSpyContext.getData();
395 data.put( "plexus", container );
396 data.put( "workingDirectory", cliRequest.workingDirectory );
397 data.put( "systemProperties", cliRequest.systemProperties );
398 data.put( "userProperties", cliRequest.userProperties );
399 data.put( "versionProperties", CLIReportingUtils.getBuildProperties() );
400 eventSpyDispatcher.init( eventSpyContext );
401
402
403 logger = container.getLoggerManager().getLoggerForComponent( MavenCli.class.getName(), null );
404
405 maven = container.lookup( Maven.class );
406
407 executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
408
409 modelProcessor = createModelProcessor( container );
410
411 settingsBuilder = container.lookup( SettingsBuilder.class );
412
413 dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
414 }
415
416 private PrintStreamLogger setupLogger( CliRequest cliRequest )
417 {
418 PrintStreamLogger logger = new PrintStreamLogger( new PrintStreamLogger.Provider()
419 {
420 public PrintStream getStream()
421 {
422 return System.out;
423 }
424 } );
425
426 logger.setThreshold( cliRequest.request.getLoggingLevel() );
427
428 return logger;
429 }
430
431 private ClassRealm setupContainerRealm( CliRequest cliRequest )
432 throws Exception
433 {
434 ClassRealm containerRealm = null;
435
436 String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
437 if ( extClassPath == null )
438 {
439 extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
440 }
441
442 if ( StringUtils.isNotEmpty( extClassPath ) )
443 {
444 String[] jars = StringUtils.split( extClassPath, File.pathSeparator );
445
446 if ( jars.length > 0 )
447 {
448 ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
449 if ( coreRealm == null )
450 {
451 coreRealm = (ClassRealm) cliRequest.classWorld.getRealms().iterator().next();
452 }
453
454 ClassRealm extRealm = cliRequest.classWorld.newRealm( "maven.ext", null );
455
456 logger.debug( "Populating class realm " + extRealm.getId() );
457
458 for ( String jar : jars )
459 {
460 File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
461
462 logger.debug( " Included " + file );
463
464 extRealm.addURL( file.toURI().toURL() );
465 }
466
467 extRealm.setParentRealm( coreRealm );
468
469 containerRealm = extRealm;
470 }
471 }
472
473 return containerRealm;
474 }
475
476 protected void customizeContainer( PlexusContainer container )
477 {
478 }
479
480
481
482
483 private void encryption( CliRequest cliRequest )
484 throws Exception
485 {
486 if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
487 {
488 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
489
490 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
491
492 System.out.println( cipher.encryptAndDecorate( passwd, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
493
494 throw new ExitException( 0 );
495 }
496 else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
497 {
498 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
499
500 String configurationFile = dispatcher.getConfigurationFile();
501
502 if ( configurationFile.startsWith( "~" ) )
503 {
504 configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
505 }
506
507 String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
508
509 String master = null;
510
511 SettingsSecurity sec = SecUtil.read( file, true );
512 if ( sec != null )
513 {
514 master = sec.getMaster();
515 }
516
517 if ( master == null )
518 {
519 throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
520 }
521
522 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
523 String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
524 System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
525
526 throw new ExitException( 0 );
527 }
528 }
529
530 private int execute( CliRequest cliRequest )
531 {
532 eventSpyDispatcher.onEvent( cliRequest.request );
533
534 MavenExecutionResult result = maven.execute( cliRequest.request );
535
536 eventSpyDispatcher.onEvent( result );
537
538 eventSpyDispatcher.close();
539
540 if ( result.hasExceptions() )
541 {
542 ExceptionHandler handler = new DefaultExceptionHandler();
543
544 Map<String, String> references = new LinkedHashMap<String, String>();
545
546 MavenProject project = null;
547
548 for ( Throwable exception : result.getExceptions() )
549 {
550 ExceptionSummary summary = handler.handleException( exception );
551
552 logSummary( summary, references, "", cliRequest.showErrors );
553
554 if ( project == null && exception instanceof LifecycleExecutionException )
555 {
556 project = ( (LifecycleExecutionException) exception ).getProject();
557 }
558 }
559
560 logger.error( "" );
561
562 if ( !cliRequest.showErrors )
563 {
564 logger.error( "To see the full stack trace of the errors, re-run Maven with the -e switch." );
565 }
566 if ( !logger.isDebugEnabled() )
567 {
568 logger.error( "Re-run Maven using the -X switch to enable full debug logging." );
569 }
570
571 if ( !references.isEmpty() )
572 {
573 logger.error( "" );
574 logger.error( "For more information about the errors and possible solutions"
575 + ", please read the following articles:" );
576
577 for ( Map.Entry<String, String> entry : references.entrySet() )
578 {
579 logger.error( entry.getValue() + " " + entry.getKey() );
580 }
581 }
582
583 if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) )
584 {
585 logger.error( "" );
586 logger.error( "After correcting the problems, you can resume the build with the command" );
587 logger.error( " mvn <goals> -rf :" + project.getArtifactId() );
588 }
589
590 if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) )
591 {
592 logger.info( "Build failures were ignored." );
593
594 return 0;
595 }
596 else
597 {
598 return 1;
599 }
600 }
601 else
602 {
603 return 0;
604 }
605 }
606
607 private void logSummary( ExceptionSummary summary, Map<String, String> references, String indent,
608 boolean showErrors )
609 {
610 String referenceKey = "";
611
612 if ( StringUtils.isNotEmpty( summary.getReference() ) )
613 {
614 referenceKey = references.get( summary.getReference() );
615 if ( referenceKey == null )
616 {
617 referenceKey = "[Help " + ( references.size() + 1 ) + "]";
618 references.put( summary.getReference(), referenceKey );
619 }
620 }
621
622 String msg = summary.getMessage();
623
624 if ( StringUtils.isNotEmpty( referenceKey ) )
625 {
626 if ( msg.indexOf( '\n' ) < 0 )
627 {
628 msg += " -> " + referenceKey;
629 }
630 else
631 {
632 msg += "\n-> " + referenceKey;
633 }
634 }
635
636 String[] lines = msg.split( "(\r\n)|(\r)|(\n)" );
637
638 for ( int i = 0; i < lines.length; i++ )
639 {
640 String line = indent + lines[i].trim();
641
642 if ( i == lines.length - 1 && ( showErrors || ( summary.getException() instanceof InternalErrorException ) ) )
643 {
644 logger.error( line, summary.getException() );
645 }
646 else
647 {
648 logger.error( line );
649 }
650 }
651
652 indent += " ";
653
654 for ( ExceptionSummary child : summary.getChildren() )
655 {
656 logSummary( child, references, indent, showErrors );
657 }
658 }
659
660 protected ModelProcessor createModelProcessor( PlexusContainer container )
661 throws ComponentLookupException
662 {
663 return container.lookup( ModelProcessor.class );
664 }
665
666 private void settings( CliRequest cliRequest )
667 throws Exception
668 {
669 File userSettingsFile;
670
671 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_SETTINGS ) )
672 {
673 userSettingsFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_SETTINGS ) );
674 userSettingsFile = resolveFile( userSettingsFile, cliRequest.workingDirectory );
675
676 if ( !userSettingsFile.isFile() )
677 {
678 throw new FileNotFoundException( "The specified user settings file does not exist: "
679 + userSettingsFile );
680 }
681 }
682 else
683 {
684 userSettingsFile = DEFAULT_USER_SETTINGS_FILE;
685 }
686
687 File globalSettingsFile;
688
689 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) )
690 {
691 globalSettingsFile =
692 new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_SETTINGS ) );
693 globalSettingsFile = resolveFile( globalSettingsFile, cliRequest.workingDirectory );
694
695 if ( !globalSettingsFile.isFile() )
696 {
697 throw new FileNotFoundException( "The specified global settings file does not exist: "
698 + globalSettingsFile );
699 }
700 }
701 else
702 {
703 globalSettingsFile = DEFAULT_GLOBAL_SETTINGS_FILE;
704 }
705
706 cliRequest.request.setGlobalSettingsFile( globalSettingsFile );
707 cliRequest.request.setUserSettingsFile( userSettingsFile );
708
709 SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
710 settingsRequest.setGlobalSettingsFile( globalSettingsFile );
711 settingsRequest.setUserSettingsFile( userSettingsFile );
712 settingsRequest.setSystemProperties( cliRequest.systemProperties );
713 settingsRequest.setUserProperties( cliRequest.userProperties );
714
715 eventSpyDispatcher.onEvent( settingsRequest );
716
717 logger.debug( "Reading global settings from "
718 + getSettingsLocation( settingsRequest.getGlobalSettingsSource(), settingsRequest.getGlobalSettingsFile() ) );
719 logger.debug( "Reading user settings from "
720 + getSettingsLocation( settingsRequest.getUserSettingsSource(), settingsRequest.getUserSettingsFile() ) );
721
722 SettingsBuildingResult settingsResult = settingsBuilder.build( settingsRequest );
723
724 eventSpyDispatcher.onEvent( settingsResult );
725
726 executionRequestPopulator.populateFromSettings( cliRequest.request, settingsResult.getEffectiveSettings() );
727
728 if ( !settingsResult.getProblems().isEmpty() && logger.isWarnEnabled() )
729 {
730 logger.warn( "" );
731 logger.warn( "Some problems were encountered while building the effective settings" );
732
733 for ( SettingsProblem problem : settingsResult.getProblems() )
734 {
735 logger.warn( problem.getMessage() + " @ " + problem.getLocation() );
736 }
737
738 logger.warn( "" );
739 }
740 }
741
742 private Object getSettingsLocation( SettingsSource source, File file )
743 {
744 if ( source != null )
745 {
746 return source.getLocation();
747 }
748 return file;
749 }
750
751 private MavenExecutionRequest populateRequest( CliRequest cliRequest )
752 {
753 MavenExecutionRequest request = cliRequest.request;
754 CommandLine commandLine = cliRequest.commandLine;
755 String workingDirectory = cliRequest.workingDirectory;
756 boolean quiet = cliRequest.quiet;
757 boolean showErrors = cliRequest.showErrors;
758
759 String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
760 for ( String deprecatedOption : deprecatedOptions )
761 {
762 if ( commandLine.hasOption( deprecatedOption ) )
763 {
764 logger.warn( "Command line option -" + deprecatedOption
765 + " is deprecated and will be removed in future Maven versions." );
766 }
767 }
768
769
770
771
772
773
774 if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
775 {
776 request.setInteractiveMode( false );
777 }
778
779 boolean noSnapshotUpdates = false;
780 if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
781 {
782 noSnapshotUpdates = true;
783 }
784
785
786
787
788
789 @SuppressWarnings("unchecked")
790 List<String> goals = commandLine.getArgList();
791
792 boolean recursive = true;
793
794
795 String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
796
797 if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
798 {
799 recursive = false;
800 }
801
802 if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
803 {
804 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
805 }
806 else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
807 {
808 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
809 }
810 else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
811 {
812 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
813 }
814
815 if ( commandLine.hasOption( CLIManager.OFFLINE ) )
816 {
817 request.setOffline( true );
818 }
819
820 boolean updateSnapshots = false;
821
822 if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
823 {
824 updateSnapshots = true;
825 }
826
827 String globalChecksumPolicy = null;
828
829 if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
830 {
831 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
832 }
833 else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
834 {
835 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
836 }
837
838 File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
839
840
841
842
843
844 List<String> activeProfiles = new ArrayList<String>();
845
846 List<String> inactiveProfiles = new ArrayList<String>();
847
848 if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
849 {
850 String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
851 if ( profileOptionValues != null )
852 {
853 for ( int i = 0; i < profileOptionValues.length; ++i )
854 {
855 StringTokenizer profileTokens = new StringTokenizer( profileOptionValues[i], "," );
856
857 while ( profileTokens.hasMoreTokens() )
858 {
859 String profileAction = profileTokens.nextToken().trim();
860
861 if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
862 {
863 inactiveProfiles.add( profileAction.substring( 1 ) );
864 }
865 else if ( profileAction.startsWith( "+" ) )
866 {
867 activeProfiles.add( profileAction.substring( 1 ) );
868 }
869 else
870 {
871 activeProfiles.add( profileAction );
872 }
873 }
874 }
875 }
876 }
877
878 TransferListener transferListener;
879
880 if ( quiet )
881 {
882 transferListener = new QuietMavenTransferListener();
883 }
884 else if ( request.isInteractiveMode() )
885 {
886 transferListener = new ConsoleMavenTransferListener( System.out );
887 }
888 else
889 {
890 transferListener = new BatchModeMavenTransferListener( System.out );
891 }
892
893 ExecutionListener executionListener = new ExecutionEventLogger( logger );
894 executionListener = eventSpyDispatcher.chainListener( executionListener );
895
896 String alternatePomFile = null;
897 if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
898 {
899 alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
900 }
901
902 File userToolchainsFile;
903 if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
904 {
905 userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
906 userToolchainsFile = resolveFile( userToolchainsFile, workingDirectory );
907 }
908 else
909 {
910 userToolchainsFile = MavenCli.DEFAULT_USER_TOOLCHAINS_FILE;
911 }
912
913 request.setBaseDirectory( baseDirectory ).setGoals( goals )
914 .setSystemProperties( cliRequest.systemProperties )
915 .setUserProperties( cliRequest.userProperties )
916 .setReactorFailureBehavior( reactorFailureBehaviour )
917 .setRecursive( recursive )
918 .setShowErrors( showErrors )
919 .addActiveProfiles( activeProfiles )
920 .addInactiveProfiles( inactiveProfiles )
921 .setExecutionListener( executionListener )
922 .setTransferListener( transferListener )
923 .setUpdateSnapshots( updateSnapshots )
924 .setNoSnapshotUpdates( noSnapshotUpdates )
925 .setGlobalChecksumPolicy( globalChecksumPolicy )
926 .setUserToolchainsFile( userToolchainsFile );
927
928 if ( alternatePomFile != null )
929 {
930 File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
931
932 request.setPom( pom );
933 }
934 else
935 {
936 File pom = modelProcessor.locatePom( baseDirectory );
937
938 if ( pom.isFile() )
939 {
940 request.setPom( pom );
941 }
942 }
943
944 if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
945 {
946 request.setBaseDirectory( request.getPom().getParentFile() );
947 }
948
949 if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
950 {
951 request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
952 }
953
954 if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
955 {
956 String[] values = commandLine.getOptionValues( CLIManager.PROJECT_LIST );
957 List<String> projects = new ArrayList<String>();
958 for ( int i = 0; i < values.length; i++ )
959 {
960 String[] tmp = StringUtils.split( values[i], "," );
961 projects.addAll( Arrays.asList( tmp ) );
962 }
963 request.setSelectedProjects( projects );
964 }
965
966 if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
967 && !commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
968 {
969 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
970 }
971 else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE )
972 && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
973 {
974 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
975 }
976 else if ( commandLine.hasOption( CLIManager.ALSO_MAKE )
977 && commandLine.hasOption( CLIManager.ALSO_MAKE_DEPENDENTS ) )
978 {
979 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
980 }
981
982 String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
983
984 if ( localRepoProperty == null )
985 {
986 localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
987 }
988
989 if ( localRepoProperty != null )
990 {
991 request.setLocalRepositoryPath( localRepoProperty );
992 }
993
994 final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS )
995 ? commandLine.getOptionValue( CLIManager.THREADS )
996 : request.getSystemProperties().getProperty(
997 MavenCli.THREADS_DEPRECATED );
998
999 if ( threadConfiguration != null )
1000 {
1001 request.setPerCoreThreadCount( threadConfiguration.contains( "C" ) );
1002 if ( threadConfiguration.contains( "W" ) )
1003 {
1004 LifecycleWeaveBuilder.setWeaveMode( request.getUserProperties() );
1005 }
1006 request.setThreadCount( threadConfiguration.replace( "C", "" ).replace( "W", "" ).replace( "auto", "" ) );
1007 }
1008
1009 request.setCacheNotFound( true );
1010 request.setCacheTransferError( false );
1011
1012 return request;
1013 }
1014
1015 static File resolveFile( File file, String workingDirectory )
1016 {
1017 if ( file == null )
1018 {
1019 return null;
1020 }
1021 else if ( file.isAbsolute() )
1022 {
1023 return file;
1024 }
1025 else if ( file.getPath().startsWith( File.separator ) )
1026 {
1027
1028 return file.getAbsoluteFile();
1029 }
1030 else
1031 {
1032 return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
1033 }
1034 }
1035
1036
1037
1038
1039
1040 static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
1041 {
1042 EnvironmentUtils.addEnvVars( systemProperties );
1043
1044
1045
1046
1047
1048
1049
1050 if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
1051 {
1052 String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
1053
1054 if ( defStrs != null )
1055 {
1056 for ( int i = 0; i < defStrs.length; ++i )
1057 {
1058 setCliProperty( defStrs[i], userProperties );
1059 }
1060 }
1061 }
1062
1063 systemProperties.putAll( System.getProperties() );
1064 }
1065
1066 private static void setCliProperty( String property, Properties properties )
1067 {
1068 String name;
1069
1070 String value;
1071
1072 int i = property.indexOf( "=" );
1073
1074 if ( i <= 0 )
1075 {
1076 name = property.trim();
1077
1078 value = "true";
1079 }
1080 else
1081 {
1082 name = property.substring( 0, i ).trim();
1083
1084 value = property.substring( i + 1 );
1085 }
1086
1087 properties.setProperty( name, value );
1088
1089
1090
1091
1092
1093
1094 System.setProperty( name, value );
1095 }
1096
1097 static class CliRequest
1098 {
1099 String[] args;
1100 CommandLine commandLine;
1101 ClassWorld classWorld;
1102 String workingDirectory;
1103 boolean debug;
1104 boolean quiet;
1105 boolean showErrors = true;
1106 PrintStream fileStream;
1107 Properties userProperties = new Properties();
1108 Properties systemProperties = new Properties();
1109 MavenExecutionRequest request;
1110
1111 CliRequest( String[] args, ClassWorld classWorld )
1112 {
1113 this.args = args;
1114 this.classWorld = classWorld;
1115 this.request = new DefaultMavenExecutionRequest();
1116 }
1117 }
1118
1119 static class ExitException
1120 extends Exception
1121 {
1122
1123 public int exitCode;
1124
1125 public ExitException( int exitCode )
1126 {
1127 this.exitCode = exitCode;
1128 }
1129
1130 }
1131
1132 }