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 com.google.common.base.Charsets;
23 import com.google.common.io.Files;
24 import com.google.inject.AbstractModule;
25 import org.apache.commons.cli.CommandLine;
26 import org.apache.commons.cli.ParseException;
27 import org.apache.commons.cli.UnrecognizedOptionException;
28 import org.apache.maven.BuildAbort;
29 import org.apache.maven.InternalErrorException;
30 import org.apache.maven.Maven;
31 import org.apache.maven.building.FileSource;
32 import org.apache.maven.building.Problem;
33 import org.apache.maven.building.Source;
34 import org.apache.maven.cli.configuration.ConfigurationProcessor;
35 import org.apache.maven.cli.configuration.SettingsXmlConfigurationProcessor;
36 import org.apache.maven.cli.event.DefaultEventSpyContext;
37 import org.apache.maven.cli.event.ExecutionEventLogger;
38 import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
39 import org.apache.maven.cli.internal.extension.model.CoreExtension;
40 import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader;
41 import org.apache.maven.cli.logging.Slf4jConfiguration;
42 import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
43 import org.apache.maven.cli.logging.Slf4jLoggerManager;
44 import org.apache.maven.cli.logging.Slf4jStdoutLogger;
45 import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
46 import org.apache.maven.cli.transfer.QuietMavenTransferListener;
47 import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
48 import org.apache.maven.eventspy.internal.EventSpyDispatcher;
49 import org.apache.maven.exception.DefaultExceptionHandler;
50 import org.apache.maven.exception.ExceptionHandler;
51 import org.apache.maven.exception.ExceptionSummary;
52 import org.apache.maven.execution.DefaultMavenExecutionRequest;
53 import org.apache.maven.execution.ExecutionListener;
54 import org.apache.maven.execution.MavenExecutionRequest;
55 import org.apache.maven.execution.MavenExecutionRequestPopulationException;
56 import org.apache.maven.execution.MavenExecutionRequestPopulator;
57 import org.apache.maven.execution.MavenExecutionResult;
58 import org.apache.maven.extension.internal.CoreExports;
59 import org.apache.maven.extension.internal.CoreExtensionEntry;
60 import org.apache.maven.lifecycle.LifecycleExecutionException;
61 import org.apache.maven.model.building.ModelProcessor;
62 import org.apache.maven.project.MavenProject;
63 import org.apache.maven.properties.internal.EnvironmentUtils;
64 import org.apache.maven.properties.internal.SystemProperties;
65 import org.apache.maven.shared.utils.logging.MessageBuilder;
66 import org.apache.maven.shared.utils.logging.MessageUtils;
67 import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
68 import org.apache.maven.toolchain.building.ToolchainsBuilder;
69 import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
70 import org.codehaus.plexus.ContainerConfiguration;
71 import org.codehaus.plexus.DefaultContainerConfiguration;
72 import org.codehaus.plexus.DefaultPlexusContainer;
73 import org.codehaus.plexus.PlexusConstants;
74 import org.codehaus.plexus.PlexusContainer;
75 import org.codehaus.plexus.classworlds.ClassWorld;
76 import org.codehaus.plexus.classworlds.realm.ClassRealm;
77 import org.codehaus.plexus.classworlds.realm.NoSuchRealmException;
78 import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
79 import org.codehaus.plexus.logging.LoggerManager;
80 import org.codehaus.plexus.util.StringUtils;
81 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
82 import org.eclipse.aether.transfer.TransferListener;
83 import org.slf4j.ILoggerFactory;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
86 import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
87 import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
88 import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
89 import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
90 import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
91
92 import java.io.BufferedInputStream;
93 import java.io.Console;
94 import java.io.File;
95 import java.io.FileInputStream;
96 import java.io.FileNotFoundException;
97 import java.io.FileOutputStream;
98 import java.io.IOException;
99 import java.io.InputStream;
100 import java.io.PrintStream;
101 import java.util.ArrayList;
102 import java.util.Collections;
103 import java.util.HashSet;
104 import java.util.LinkedHashMap;
105 import java.util.List;
106 import java.util.Map;
107 import java.util.Map.Entry;
108 import java.util.Properties;
109 import java.util.Set;
110 import java.util.StringTokenizer;
111 import java.util.regex.Matcher;
112 import java.util.regex.Pattern;
113
114 import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
115
116
117
118
119
120
121
122 public class MavenCli
123 {
124 public static final String LOCAL_REPO_PROPERTY = "maven.repo.local";
125
126 public static final String THREADS_DEPRECATED = "maven.threads.experimental";
127
128 public static final String MULTIMODULE_PROJECT_DIRECTORY = "maven.multiModuleProjectDirectory";
129
130 @SuppressWarnings( "checkstyle:constantname" )
131 public static final String userHome = System.getProperty( "user.home" );
132
133 @SuppressWarnings( "checkstyle:constantname" )
134 public static final File userMavenConfigurationHome = new File( userHome, ".m2" );
135
136
137
138
139 public static final File DEFAULT_USER_SETTINGS_FILE = SettingsXmlConfigurationProcessor.DEFAULT_USER_SETTINGS_FILE;
140
141
142
143
144 public static final File DEFAULT_GLOBAL_SETTINGS_FILE =
145 SettingsXmlConfigurationProcessor.DEFAULT_GLOBAL_SETTINGS_FILE;
146
147 public static final File DEFAULT_USER_TOOLCHAINS_FILE = new File( userMavenConfigurationHome, "toolchains.xml" );
148
149 public static final File DEFAULT_GLOBAL_TOOLCHAINS_FILE =
150 new File( System.getProperty( "maven.conf" ), "toolchains.xml" );
151
152 private static final String EXT_CLASS_PATH = "maven.ext.class.path";
153
154 private static final String EXTENSIONS_FILENAME = ".mvn/extensions.xml";
155
156 private static final String MVN_MAVEN_CONFIG = ".mvn/maven.config";
157
158 private ClassWorld classWorld;
159
160 private LoggerManager plexusLoggerManager;
161
162 private ILoggerFactory slf4jLoggerFactory;
163
164 private Logger slf4jLogger;
165
166 private EventSpyDispatcher eventSpyDispatcher;
167
168 private ModelProcessor modelProcessor;
169
170 private Maven maven;
171
172 private MavenExecutionRequestPopulator executionRequestPopulator;
173
174 private ToolchainsBuilder toolchainsBuilder;
175
176 private DefaultSecDispatcher dispatcher;
177
178 private Map<String, ConfigurationProcessor> configurationProcessors;
179
180 public MavenCli()
181 {
182 this( null );
183 }
184
185
186 public MavenCli( ClassWorld classWorld )
187 {
188 this.classWorld = classWorld;
189 }
190
191 public static void main( String[] args )
192 {
193 int result = main( args, null );
194
195 System.exit( result );
196 }
197
198
199
200
201 public static int main( String[] args, ClassWorld classWorld )
202 {
203 MavenCli cli = new MavenCli();
204
205 MessageUtils.systemInstall();
206 int result = cli.doMain( new CliRequest( args, classWorld ) );
207 MessageUtils.systemUninstall();
208
209 return result;
210 }
211
212
213 public static int doMain( String[] args, ClassWorld classWorld )
214 {
215 MavenCli cli = new MavenCli();
216 return cli.doMain( new CliRequest( args, classWorld ) );
217 }
218
219
220
221
222
223
224 public int doMain( String[] args, String workingDirectory, PrintStream stdout, PrintStream stderr )
225 {
226 PrintStream oldout = System.out;
227 PrintStream olderr = System.err;
228
229 final Set<String> realms;
230 if ( classWorld != null )
231 {
232 realms = new HashSet<>();
233 for ( ClassRealm realm : classWorld.getRealms() )
234 {
235 realms.add( realm.getId() );
236 }
237 }
238 else
239 {
240 realms = Collections.emptySet();
241 }
242
243 try
244 {
245 if ( stdout != null )
246 {
247 System.setOut( stdout );
248 }
249 if ( stderr != null )
250 {
251 System.setErr( stderr );
252 }
253
254 CliRequest cliRequest = new CliRequest( args, classWorld );
255 cliRequest.workingDirectory = workingDirectory;
256
257 return doMain( cliRequest );
258 }
259 finally
260 {
261 if ( classWorld != null )
262 {
263 for ( ClassRealm realm : new ArrayList<>( classWorld.getRealms() ) )
264 {
265 String realmId = realm.getId();
266 if ( !realms.contains( realmId ) )
267 {
268 try
269 {
270 classWorld.disposeRealm( realmId );
271 }
272 catch ( NoSuchRealmException ignored )
273 {
274
275 }
276 }
277 }
278 }
279 System.setOut( oldout );
280 System.setErr( olderr );
281 }
282 }
283
284
285 public int doMain( CliRequest cliRequest )
286 {
287 PlexusContainer localContainer = null;
288 try
289 {
290 initialize( cliRequest );
291 cli( cliRequest );
292 logging( cliRequest );
293 version( cliRequest );
294 properties( cliRequest );
295 localContainer = container( cliRequest );
296 commands( cliRequest );
297 configure( cliRequest );
298 toolchains( cliRequest );
299 populateRequest( cliRequest );
300 encryption( cliRequest );
301 repository( cliRequest );
302 return execute( cliRequest );
303 }
304 catch ( ExitException e )
305 {
306 return e.exitCode;
307 }
308 catch ( UnrecognizedOptionException e )
309 {
310
311 return 1;
312 }
313 catch ( BuildAbort e )
314 {
315 CLIReportingUtils.showError( slf4jLogger, "ABORTED", e, cliRequest.showErrors );
316
317 return 2;
318 }
319 catch ( Exception e )
320 {
321 CLIReportingUtils.showError( slf4jLogger, "Error executing Maven.", e, cliRequest.showErrors );
322
323 return 1;
324 }
325 finally
326 {
327 if ( localContainer != null )
328 {
329 localContainer.dispose();
330 }
331 }
332 }
333
334 void initialize( CliRequest cliRequest )
335 throws ExitException
336 {
337 if ( cliRequest.workingDirectory == null )
338 {
339 cliRequest.workingDirectory = System.getProperty( "user.dir" );
340 }
341
342 if ( cliRequest.multiModuleProjectDirectory == null )
343 {
344 String basedirProperty = System.getProperty( MULTIMODULE_PROJECT_DIRECTORY );
345 if ( basedirProperty == null )
346 {
347 System.err.format(
348 "-D%s system property is not set.", MULTIMODULE_PROJECT_DIRECTORY );
349 throw new ExitException( 1 );
350 }
351 File basedir = basedirProperty != null ? new File( basedirProperty ) : new File( "" );
352 try
353 {
354 cliRequest.multiModuleProjectDirectory = basedir.getCanonicalFile();
355 }
356 catch ( IOException e )
357 {
358 cliRequest.multiModuleProjectDirectory = basedir.getAbsoluteFile();
359 }
360 }
361
362
363
364
365
366 String mavenHome = System.getProperty( "maven.home" );
367
368 if ( mavenHome != null )
369 {
370 System.setProperty( "maven.home", new File( mavenHome ).getAbsolutePath() );
371 }
372 }
373
374 void cli( CliRequest cliRequest )
375 throws Exception
376 {
377
378
379
380
381 slf4jLogger = new Slf4jStdoutLogger();
382
383 CLIManager cliManager = new CLIManager();
384
385 List<String> args = new ArrayList<>();
386 CommandLine mavenConfig = null;
387 try
388 {
389 File configFile = new File( cliRequest.multiModuleProjectDirectory, MVN_MAVEN_CONFIG );
390
391 if ( configFile.isFile() )
392 {
393 for ( String arg : Files.toString( configFile, Charsets.UTF_8 ).split( "\\s+" ) )
394 {
395 if ( !arg.isEmpty() )
396 {
397 args.add( arg );
398 }
399 }
400
401 mavenConfig = cliManager.parse( args.toArray( new String[args.size()] ) );
402 List<?> unrecongized = mavenConfig.getArgList();
403 if ( !unrecongized.isEmpty() )
404 {
405 throw new ParseException( "Unrecognized maven.config entries: " + unrecongized );
406 }
407 }
408 }
409 catch ( ParseException e )
410 {
411 System.err.println( "Unable to parse maven.config: " + e.getMessage() );
412 cliManager.displayHelp( System.out );
413 throw e;
414 }
415
416 try
417 {
418 if ( mavenConfig == null )
419 {
420 cliRequest.commandLine = cliManager.parse( cliRequest.args );
421 }
422 else
423 {
424 cliRequest.commandLine = new MergedCommandLine( cliManager.parse( cliRequest.args ), mavenConfig );
425 }
426 }
427 catch ( ParseException e )
428 {
429 System.err.println( "Unable to parse command line options: " + e.getMessage() );
430 cliManager.displayHelp( System.out );
431 throw e;
432 }
433
434 if ( cliRequest.commandLine.hasOption( CLIManager.HELP ) )
435 {
436 cliManager.displayHelp( System.out );
437 throw new ExitException( 0 );
438 }
439
440 if ( cliRequest.commandLine.hasOption( CLIManager.VERSION ) )
441 {
442 System.out.println( CLIReportingUtils.showVersion() );
443 throw new ExitException( 0 );
444 }
445 }
446
447
448
449
450 private void logging( CliRequest cliRequest )
451 {
452 cliRequest.debug = cliRequest.commandLine.hasOption( CLIManager.DEBUG );
453 cliRequest.quiet = !cliRequest.debug && cliRequest.commandLine.hasOption( CLIManager.QUIET );
454 cliRequest.showErrors = cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.ERRORS );
455
456 slf4jLoggerFactory = LoggerFactory.getILoggerFactory();
457 Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration( slf4jLoggerFactory );
458
459 if ( cliRequest.debug )
460 {
461 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_DEBUG );
462 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.DEBUG );
463 }
464 else if ( cliRequest.quiet )
465 {
466 cliRequest.request.setLoggingLevel( MavenExecutionRequest.LOGGING_LEVEL_ERROR );
467 slf4jConfiguration.setRootLoggerLevel( Slf4jConfiguration.Level.ERROR );
468 }
469
470
471
472 if ( cliRequest.commandLine.hasOption( CLIManager.BATCH_MODE ) )
473 {
474 MessageUtils.setColorEnabled( false );
475 }
476
477 if ( cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
478 {
479 File logFile = new File( cliRequest.commandLine.getOptionValue( CLIManager.LOG_FILE ) );
480 logFile = resolveFile( logFile, cliRequest.workingDirectory );
481
482 MessageUtils.setColorEnabled( false );
483
484
485 try
486 {
487 PrintStream ps = new PrintStream( new FileOutputStream( logFile ) );
488 System.setOut( ps );
489 System.setErr( ps );
490 }
491 catch ( FileNotFoundException e )
492 {
493
494
495
496 }
497 }
498
499 slf4jConfiguration.activate();
500
501 plexusLoggerManager = new Slf4jLoggerManager();
502 slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
503 }
504
505 private void version( CliRequest cliRequest )
506 {
507 if ( cliRequest.debug || cliRequest.commandLine.hasOption( CLIManager.SHOW_VERSION ) )
508 {
509 System.out.println( CLIReportingUtils.showVersion() );
510 }
511 }
512
513 private void commands( CliRequest cliRequest )
514 {
515 if ( cliRequest.showErrors )
516 {
517 slf4jLogger.info( "Error stacktraces are turned on." );
518 }
519
520 if ( MavenExecutionRequest.CHECKSUM_POLICY_WARN.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
521 {
522 slf4jLogger.info( "Disabling strict checksum verification on all artifact downloads." );
523 }
524 else if ( MavenExecutionRequest.CHECKSUM_POLICY_FAIL.equals( cliRequest.request.getGlobalChecksumPolicy() ) )
525 {
526 slf4jLogger.info( "Enabling strict checksum verification on all artifact downloads." );
527 }
528
529 if ( slf4jLogger.isDebugEnabled() )
530 {
531 slf4jLogger.debug( "Message scheme: " + ( MessageUtils.isColorEnabled() ? "color" : "plain" ) );
532 if ( MessageUtils.isColorEnabled() )
533 {
534 MessageBuilder buff = MessageUtils.buffer();
535 buff.a( "Message styles: " );
536 buff.debug( "debug" ).a( ' ' );
537 buff.info( "info" ).a( ' ' );
538 buff.warning( "warning" ).a( ' ' );
539 buff.error( "error" ).a( ' ' );
540 buff.success( "success" ).a( ' ' );
541 buff.failure( "failure" ).a( ' ' );
542 buff.strong( "strong" ).a( ' ' );
543 buff.mojo( "mojo" ).a( ' ' );
544 buff.project( "project" );
545 slf4jLogger.debug( buff.toString() );
546 }
547 }
548 }
549
550
551
552 void properties( CliRequest cliRequest )
553 {
554 populateProperties( cliRequest.commandLine, cliRequest.systemProperties, cliRequest.userProperties );
555 }
556
557 private PlexusContainer container( CliRequest cliRequest )
558 throws Exception
559 {
560 if ( cliRequest.classWorld == null )
561 {
562 cliRequest.classWorld = new ClassWorld( "plexus.core", Thread.currentThread().getContextClassLoader() );
563 }
564
565 ClassRealm coreRealm = cliRequest.classWorld.getClassRealm( "plexus.core" );
566 if ( coreRealm == null )
567 {
568 coreRealm = cliRequest.classWorld.getRealms().iterator().next();
569 }
570
571 List<File> extClassPath = parseExtClasspath( cliRequest );
572
573 CoreExtensionEntry coreEntry = CoreExtensionEntry.discoverFrom( coreRealm );
574 List<CoreExtensionEntry> extensions =
575 loadCoreExtensions( cliRequest, coreRealm, coreEntry.getExportedArtifacts() );
576
577 ClassRealm containerRealm = setupContainerRealm( cliRequest.classWorld, coreRealm, extClassPath, extensions );
578
579 ContainerConfiguration cc = new DefaultContainerConfiguration().setClassWorld( cliRequest.classWorld ).setRealm(
580 containerRealm ).setClassPathScanning( PlexusConstants.SCANNING_INDEX ).setAutoWiring( true ).setName(
581 "maven" );
582
583 Set<String> exportedArtifacts = new HashSet<>( coreEntry.getExportedArtifacts() );
584 Set<String> exportedPackages = new HashSet<>( coreEntry.getExportedPackages() );
585 for ( CoreExtensionEntry extension : extensions )
586 {
587 exportedArtifacts.addAll( extension.getExportedArtifacts() );
588 exportedPackages.addAll( extension.getExportedPackages() );
589 }
590
591 final CoreExports exports = new CoreExports( containerRealm, exportedArtifacts, exportedPackages );
592
593 DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
594 {
595 @Override
596 protected void configure()
597 {
598 bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
599 bind( CoreExports.class ).toInstance( exports );
600 }
601 } );
602
603
604 container.setLookupRealm( null );
605
606 container.setLoggerManager( plexusLoggerManager );
607
608 for ( CoreExtensionEntry extension : extensions )
609 {
610 container.discoverComponents( extension.getClassRealm() );
611 }
612
613 customizeContainer( container );
614
615 container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
616
617 Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
618
619 eventSpyDispatcher = container.lookup( EventSpyDispatcher.class );
620
621 DefaultEventSpyContext eventSpyContext = new DefaultEventSpyContext();
622 Map<String, Object> data = eventSpyContext.getData();
623 data.put( "plexus", container );
624 data.put( "workingDirectory", cliRequest.workingDirectory );
625 data.put( "systemProperties", cliRequest.systemProperties );
626 data.put( "userProperties", cliRequest.userProperties );
627 data.put( "versionProperties", CLIReportingUtils.getBuildProperties() );
628 eventSpyDispatcher.init( eventSpyContext );
629
630
631 slf4jLogger = slf4jLoggerFactory.getLogger( this.getClass().getName() );
632
633 maven = container.lookup( Maven.class );
634
635 executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
636
637 modelProcessor = createModelProcessor( container );
638
639 configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
640
641 toolchainsBuilder = container.lookup( ToolchainsBuilder.class );
642
643 dispatcher = (DefaultSecDispatcher) container.lookup( SecDispatcher.class, "maven" );
644
645 return container;
646 }
647
648 private List<CoreExtensionEntry> loadCoreExtensions( CliRequest cliRequest, ClassRealm containerRealm,
649 Set<String> providedArtifacts )
650 {
651 if ( cliRequest.multiModuleProjectDirectory == null )
652 {
653 return Collections.emptyList();
654 }
655
656 File extensionsFile = new File( cliRequest.multiModuleProjectDirectory, EXTENSIONS_FILENAME );
657 if ( !extensionsFile.isFile() )
658 {
659 return Collections.emptyList();
660 }
661
662 try
663 {
664 List<CoreExtension> extensions = readCoreExtensionsDescriptor( extensionsFile );
665 if ( extensions.isEmpty() )
666 {
667 return Collections.emptyList();
668 }
669
670 ContainerConfiguration cc = new DefaultContainerConfiguration()
671 .setClassWorld( cliRequest.classWorld )
672 .setRealm( containerRealm )
673 .setClassPathScanning( PlexusConstants.SCANNING_INDEX )
674 .setAutoWiring( true )
675 .setName( "maven" );
676
677 DefaultPlexusContainer container = new DefaultPlexusContainer( cc, new AbstractModule()
678 {
679 @Override
680 protected void configure()
681 {
682 bind( ILoggerFactory.class ).toInstance( slf4jLoggerFactory );
683 }
684 } );
685
686 try
687 {
688 container.setLookupRealm( null );
689
690 container.setLoggerManager( plexusLoggerManager );
691
692 container.getLoggerManager().setThresholds( cliRequest.request.getLoggingLevel() );
693
694 Thread.currentThread().setContextClassLoader( container.getContainerRealm() );
695
696 executionRequestPopulator = container.lookup( MavenExecutionRequestPopulator.class );
697
698 configurationProcessors = container.lookupMap( ConfigurationProcessor.class );
699
700 configure( cliRequest );
701
702 MavenExecutionRequest request = DefaultMavenExecutionRequest.copy( cliRequest.request );
703
704 request = populateRequest( cliRequest, request );
705
706 request = executionRequestPopulator.populateDefaults( request );
707
708 BootstrapCoreExtensionManager resolver = container.lookup( BootstrapCoreExtensionManager.class );
709
710 return resolver.loadCoreExtensions( request, providedArtifacts, extensions );
711 }
712 finally
713 {
714 executionRequestPopulator = null;
715 container.dispose();
716 }
717 }
718 catch ( RuntimeException e )
719 {
720
721 throw e;
722 }
723 catch ( Exception e )
724 {
725 slf4jLogger.warn( "Failed to read extensions descriptor " + extensionsFile + ": " + e.getMessage() );
726 }
727 return Collections.emptyList();
728 }
729
730 private List<CoreExtension> readCoreExtensionsDescriptor( File extensionsFile )
731 throws IOException, XmlPullParserException
732 {
733 CoreExtensionsXpp3Reader parser = new CoreExtensionsXpp3Reader();
734
735 try ( InputStream is = new BufferedInputStream( new FileInputStream( extensionsFile ) ) )
736 {
737
738 return parser.read( is ).getExtensions();
739 }
740
741 }
742
743 private ClassRealm setupContainerRealm( ClassWorld classWorld, ClassRealm coreRealm, List<File> extClassPath,
744 List<CoreExtensionEntry> extensions )
745 throws Exception
746 {
747 if ( !extClassPath.isEmpty() || !extensions.isEmpty() )
748 {
749 ClassRealm extRealm = classWorld.newRealm( "maven.ext", null );
750
751 extRealm.setParentRealm( coreRealm );
752
753 slf4jLogger.debug( "Populating class realm " + extRealm.getId() );
754
755 for ( File file : extClassPath )
756 {
757 slf4jLogger.debug( " Included " + file );
758
759 extRealm.addURL( file.toURI().toURL() );
760 }
761
762 for ( CoreExtensionEntry entry : reverse( extensions ) )
763 {
764 Set<String> exportedPackages = entry.getExportedPackages();
765 ClassRealm realm = entry.getClassRealm();
766 for ( String exportedPackage : exportedPackages )
767 {
768 extRealm.importFrom( realm, exportedPackage );
769 }
770 if ( exportedPackages.isEmpty() )
771 {
772
773 extRealm.importFrom( realm, realm.getId() );
774 }
775 }
776
777 return extRealm;
778 }
779
780 return coreRealm;
781 }
782
783 private static <T> List<T> reverse( List<T> list )
784 {
785 List<T> copy = new ArrayList<>( list );
786 Collections.reverse( copy );
787 return copy;
788 }
789
790 private List<File> parseExtClasspath( CliRequest cliRequest )
791 {
792 String extClassPath = cliRequest.userProperties.getProperty( EXT_CLASS_PATH );
793 if ( extClassPath == null )
794 {
795 extClassPath = cliRequest.systemProperties.getProperty( EXT_CLASS_PATH );
796 }
797
798 List<File> jars = new ArrayList<>();
799
800 if ( StringUtils.isNotEmpty( extClassPath ) )
801 {
802 for ( String jar : StringUtils.split( extClassPath, File.pathSeparator ) )
803 {
804 File file = resolveFile( new File( jar ), cliRequest.workingDirectory );
805
806 slf4jLogger.debug( " Included " + file );
807
808 jars.add( file );
809 }
810 }
811
812 return jars;
813 }
814
815
816
817
818 private void encryption( CliRequest cliRequest )
819 throws Exception
820 {
821 if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_MASTER_PASSWORD ) )
822 {
823 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_MASTER_PASSWORD );
824
825 if ( passwd == null )
826 {
827 Console cons = System.console();
828 char[] password = ( cons == null ) ? null : cons.readPassword( "Master password: " );
829 if ( password != null )
830 {
831
832 passwd = String.copyValueOf( password );
833
834
835 java.util.Arrays.fill( password, ' ' );
836 }
837 }
838
839 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
840
841 System.out.println(
842 cipher.encryptAndDecorate( passwd, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION ) );
843
844 throw new ExitException( 0 );
845 }
846 else if ( cliRequest.commandLine.hasOption( CLIManager.ENCRYPT_PASSWORD ) )
847 {
848 String passwd = cliRequest.commandLine.getOptionValue( CLIManager.ENCRYPT_PASSWORD );
849
850 if ( passwd == null )
851 {
852 Console cons = System.console();
853 char[] password = ( cons == null ) ? null : cons.readPassword( "Password: " );
854 if ( password != null )
855 {
856
857 passwd = String.copyValueOf( password );
858
859
860 java.util.Arrays.fill( password, ' ' );
861 }
862 }
863
864 String configurationFile = dispatcher.getConfigurationFile();
865
866 if ( configurationFile.startsWith( "~" ) )
867 {
868 configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
869 }
870
871 String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
872
873 String master = null;
874
875 SettingsSecurity sec = SecUtil.read( file, true );
876 if ( sec != null )
877 {
878 master = sec.getMaster();
879 }
880
881 if ( master == null )
882 {
883 throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
884 }
885
886 DefaultPlexusCipher cipher = new DefaultPlexusCipher();
887 String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
888 System.out.println( cipher.encryptAndDecorate( passwd, masterPasswd ) );
889
890 throw new ExitException( 0 );
891 }
892 }
893
894 private void repository( CliRequest cliRequest )
895 throws Exception
896 {
897 if ( cliRequest.commandLine.hasOption( CLIManager.LEGACY_LOCAL_REPOSITORY ) || Boolean.getBoolean(
898 "maven.legacyLocalRepo" ) )
899 {
900 cliRequest.request.setUseLegacyLocalRepository( true );
901 }
902 }
903
904 private int execute( CliRequest cliRequest )
905 throws MavenExecutionRequestPopulationException
906 {
907 MavenExecutionRequest request = executionRequestPopulator.populateDefaults( cliRequest.request );
908
909 eventSpyDispatcher.onEvent( request );
910
911 MavenExecutionResult result = maven.execute( request );
912
913 eventSpyDispatcher.onEvent( result );
914
915 eventSpyDispatcher.close();
916
917 if ( result.hasExceptions() )
918 {
919 ExceptionHandler handler = new DefaultExceptionHandler();
920
921 Map<String, String> references = new LinkedHashMap<>();
922
923 MavenProject project = null;
924
925 for ( Throwable exception : result.getExceptions() )
926 {
927 ExceptionSummary summary = handler.handleException( exception );
928
929 logSummary( summary, references, "", cliRequest.showErrors );
930
931 if ( project == null && exception instanceof LifecycleExecutionException )
932 {
933 project = ( (LifecycleExecutionException) exception ).getProject();
934 }
935 }
936
937 slf4jLogger.error( "" );
938
939 if ( !cliRequest.showErrors )
940 {
941 slf4jLogger.error( "To see the full stack trace of the errors, re-run Maven with the "
942 + buffer().strong( "-e" ) + " switch." );
943 }
944 if ( !slf4jLogger.isDebugEnabled() )
945 {
946 slf4jLogger.error( "Re-run Maven using the " + buffer().strong( "-X" )
947 + " switch to enable full debug logging." );
948 }
949
950 if ( !references.isEmpty() )
951 {
952 slf4jLogger.error( "" );
953 slf4jLogger.error( "For more information about the errors and possible solutions"
954 + ", please read the following articles:" );
955
956 for ( Map.Entry<String, String> entry : references.entrySet() )
957 {
958 slf4jLogger.error( buffer().strong( entry.getValue() ) + " " + entry.getKey() );
959 }
960 }
961
962 if ( project != null && !project.equals( result.getTopologicallySortedProjects().get( 0 ) ) )
963 {
964 slf4jLogger.error( "" );
965 slf4jLogger.error( "After correcting the problems, you can resume the build with the command" );
966 slf4jLogger.error( buffer().a( " " ).strong( "mvn <goals> -rf :"
967 + project.getArtifactId() ).toString() );
968 }
969
970 if ( MavenExecutionRequest.REACTOR_FAIL_NEVER.equals( cliRequest.request.getReactorFailureBehavior() ) )
971 {
972 slf4jLogger.info( "Build failures were ignored." );
973
974 return 0;
975 }
976 else
977 {
978 return 1;
979 }
980 }
981 else
982 {
983 return 0;
984 }
985 }
986
987 private void logSummary( ExceptionSummary summary, Map<String, String> references, String indent,
988 boolean showErrors )
989 {
990 String referenceKey = "";
991
992 if ( StringUtils.isNotEmpty( summary.getReference() ) )
993 {
994 referenceKey = references.get( summary.getReference() );
995 if ( referenceKey == null )
996 {
997 referenceKey = "[Help " + ( references.size() + 1 ) + "]";
998 references.put( summary.getReference(), referenceKey );
999 }
1000 }
1001
1002 String msg = summary.getMessage();
1003
1004 if ( StringUtils.isNotEmpty( referenceKey ) )
1005 {
1006 if ( msg.indexOf( '\n' ) < 0 )
1007 {
1008 msg += " -> " + buffer().strong( referenceKey );
1009 }
1010 else
1011 {
1012 msg += "\n-> " + buffer().strong( referenceKey );
1013 }
1014 }
1015
1016 String[] lines = msg.split( "(\r\n)|(\r)|(\n)" );
1017 String currentColor = "";
1018
1019 for ( int i = 0; i < lines.length; i++ )
1020 {
1021
1022 String line = currentColor + lines[i];
1023
1024
1025 Matcher matcher = LAST_ANSI_SEQUENCE.matcher( line );
1026 String nextColor = "";
1027 if ( matcher.find() )
1028 {
1029 nextColor = matcher.group( 1 );
1030 if ( ANSI_RESET.equals( nextColor ) )
1031 {
1032
1033 nextColor = "";
1034 }
1035 }
1036
1037
1038 line = indent + line + ( "".equals( nextColor ) ? "" : ANSI_RESET );
1039
1040 if ( ( i == lines.length - 1 ) && ( showErrors
1041 || ( summary.getException() instanceof InternalErrorException ) ) )
1042 {
1043 slf4jLogger.error( line, summary.getException() );
1044 }
1045 else
1046 {
1047 slf4jLogger.error( line );
1048 }
1049
1050 currentColor = nextColor;
1051 }
1052
1053 indent += " ";
1054
1055 for ( ExceptionSummary child : summary.getChildren() )
1056 {
1057 logSummary( child, references, indent, showErrors );
1058 }
1059 }
1060
1061 private static final Pattern LAST_ANSI_SEQUENCE = Pattern.compile( "(\u001B\\[[;\\d]*[ -/]*[@-~])[^\u001B]*$" );
1062
1063 private static final String ANSI_RESET = "\u001B\u005Bm";
1064
1065 private void configure( CliRequest cliRequest )
1066 throws Exception
1067 {
1068
1069
1070
1071
1072
1073
1074 cliRequest.request.setEventSpyDispatcher( eventSpyDispatcher );
1075
1076
1077
1078
1079
1080
1081
1082
1083 int userSuppliedConfigurationProcessorCount = configurationProcessors.size() - 1;
1084
1085 if ( userSuppliedConfigurationProcessorCount == 0 )
1086 {
1087
1088
1089
1090
1091 configurationProcessors.get( SettingsXmlConfigurationProcessor.HINT ).process( cliRequest );
1092 }
1093 else if ( userSuppliedConfigurationProcessorCount == 1 )
1094 {
1095
1096
1097
1098 for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
1099 {
1100 String hint = entry.getKey();
1101 if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
1102 {
1103 ConfigurationProcessor configurationProcessor = entry.getValue();
1104 configurationProcessor.process( cliRequest );
1105 }
1106 }
1107 }
1108 else if ( userSuppliedConfigurationProcessorCount > 1 )
1109 {
1110
1111
1112
1113 StringBuilder sb = new StringBuilder(
1114 String.format( "\nThere can only be one user supplied ConfigurationProcessor, there are %s:\n\n",
1115 userSuppliedConfigurationProcessorCount ) );
1116 for ( Entry<String, ConfigurationProcessor> entry : configurationProcessors.entrySet() )
1117 {
1118 String hint = entry.getKey();
1119 if ( !hint.equals( SettingsXmlConfigurationProcessor.HINT ) )
1120 {
1121 ConfigurationProcessor configurationProcessor = entry.getValue();
1122 sb.append( String.format( "%s\n", configurationProcessor.getClass().getName() ) );
1123 }
1124 }
1125 sb.append( String.format( "\n" ) );
1126 throw new Exception( sb.toString() );
1127 }
1128 }
1129
1130 private void toolchains( CliRequest cliRequest )
1131 throws Exception
1132 {
1133 File userToolchainsFile;
1134
1135 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
1136 {
1137 userToolchainsFile =
1138 new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
1139 userToolchainsFile = resolveFile( userToolchainsFile, cliRequest.workingDirectory );
1140
1141 if ( !userToolchainsFile.isFile() )
1142 {
1143 throw new FileNotFoundException(
1144 "The specified user toolchains file does not exist: " + userToolchainsFile );
1145 }
1146 }
1147 else
1148 {
1149 userToolchainsFile = DEFAULT_USER_TOOLCHAINS_FILE;
1150 }
1151
1152 File globalToolchainsFile;
1153
1154 if ( cliRequest.commandLine.hasOption( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) )
1155 {
1156 globalToolchainsFile =
1157 new File( cliRequest.commandLine.getOptionValue( CLIManager.ALTERNATE_GLOBAL_TOOLCHAINS ) );
1158 globalToolchainsFile = resolveFile( globalToolchainsFile, cliRequest.workingDirectory );
1159
1160 if ( !globalToolchainsFile.isFile() )
1161 {
1162 throw new FileNotFoundException(
1163 "The specified global toolchains file does not exist: " + globalToolchainsFile );
1164 }
1165 }
1166 else
1167 {
1168 globalToolchainsFile = DEFAULT_GLOBAL_TOOLCHAINS_FILE;
1169 }
1170
1171 cliRequest.request.setGlobalToolchainsFile( globalToolchainsFile );
1172 cliRequest.request.setUserToolchainsFile( userToolchainsFile );
1173
1174 DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
1175 if ( globalToolchainsFile.isFile() )
1176 {
1177 toolchainsRequest.setGlobalToolchainsSource( new FileSource( globalToolchainsFile ) );
1178 }
1179 if ( userToolchainsFile.isFile() )
1180 {
1181 toolchainsRequest.setUserToolchainsSource( new FileSource( userToolchainsFile ) );
1182 }
1183
1184 eventSpyDispatcher.onEvent( toolchainsRequest );
1185
1186 slf4jLogger.debug(
1187 "Reading global toolchains from " + getLocation( toolchainsRequest.getGlobalToolchainsSource(),
1188 globalToolchainsFile ) );
1189 slf4jLogger.debug( "Reading user toolchains from " + getLocation( toolchainsRequest.getUserToolchainsSource(),
1190 userToolchainsFile ) );
1191
1192 ToolchainsBuildingResult toolchainsResult = toolchainsBuilder.build( toolchainsRequest );
1193
1194 eventSpyDispatcher.onEvent( toolchainsRequest );
1195
1196 executionRequestPopulator.populateFromToolchains( cliRequest.request,
1197 toolchainsResult.getEffectiveToolchains() );
1198
1199 if ( !toolchainsResult.getProblems().isEmpty() && slf4jLogger.isWarnEnabled() )
1200 {
1201 slf4jLogger.warn( "" );
1202 slf4jLogger.warn( "Some problems were encountered while building the effective toolchains" );
1203
1204 for ( Problem problem : toolchainsResult.getProblems() )
1205 {
1206 slf4jLogger.warn( problem.getMessage() + " @ " + problem.getLocation() );
1207 }
1208
1209 slf4jLogger.warn( "" );
1210 }
1211 }
1212
1213 private Object getLocation( Source source, File defaultLocation )
1214 {
1215 if ( source != null )
1216 {
1217 return source.getLocation();
1218 }
1219 return defaultLocation;
1220 }
1221
1222 private MavenExecutionRequest populateRequest( CliRequest cliRequest )
1223 {
1224 return populateRequest( cliRequest, cliRequest.request );
1225 }
1226
1227 private MavenExecutionRequest populateRequest( CliRequest cliRequest, MavenExecutionRequest request )
1228 {
1229 CommandLine commandLine = cliRequest.commandLine;
1230 String workingDirectory = cliRequest.workingDirectory;
1231 boolean quiet = cliRequest.quiet;
1232 boolean showErrors = cliRequest.showErrors;
1233
1234 String[] deprecatedOptions = { "up", "npu", "cpu", "npr" };
1235 for ( String deprecatedOption : deprecatedOptions )
1236 {
1237 if ( commandLine.hasOption( deprecatedOption ) )
1238 {
1239 slf4jLogger.warn( "Command line option -" + deprecatedOption
1240 + " is deprecated and will be removed in future Maven versions." );
1241 }
1242 }
1243
1244
1245
1246
1247
1248
1249 if ( commandLine.hasOption( CLIManager.BATCH_MODE ) )
1250 {
1251 request.setInteractiveMode( false );
1252 }
1253
1254 boolean noSnapshotUpdates = false;
1255 if ( commandLine.hasOption( CLIManager.SUPRESS_SNAPSHOT_UPDATES ) )
1256 {
1257 noSnapshotUpdates = true;
1258 }
1259
1260
1261
1262
1263
1264 @SuppressWarnings( "unchecked" ) List<String> goals = commandLine.getArgList();
1265
1266 boolean recursive = true;
1267
1268
1269 String reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
1270
1271 if ( commandLine.hasOption( CLIManager.NON_RECURSIVE ) )
1272 {
1273 recursive = false;
1274 }
1275
1276 if ( commandLine.hasOption( CLIManager.FAIL_FAST ) )
1277 {
1278 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_FAST;
1279 }
1280 else if ( commandLine.hasOption( CLIManager.FAIL_AT_END ) )
1281 {
1282 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_AT_END;
1283 }
1284 else if ( commandLine.hasOption( CLIManager.FAIL_NEVER ) )
1285 {
1286 reactorFailureBehaviour = MavenExecutionRequest.REACTOR_FAIL_NEVER;
1287 }
1288
1289 if ( commandLine.hasOption( CLIManager.OFFLINE ) )
1290 {
1291 request.setOffline( true );
1292 }
1293
1294 boolean updateSnapshots = false;
1295
1296 if ( commandLine.hasOption( CLIManager.UPDATE_SNAPSHOTS ) )
1297 {
1298 updateSnapshots = true;
1299 }
1300
1301 String globalChecksumPolicy = null;
1302
1303 if ( commandLine.hasOption( CLIManager.CHECKSUM_FAILURE_POLICY ) )
1304 {
1305 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
1306 }
1307 else if ( commandLine.hasOption( CLIManager.CHECKSUM_WARNING_POLICY ) )
1308 {
1309 globalChecksumPolicy = MavenExecutionRequest.CHECKSUM_POLICY_WARN;
1310 }
1311
1312 File baseDirectory = new File( workingDirectory, "" ).getAbsoluteFile();
1313
1314
1315
1316
1317
1318 List<String> activeProfiles = new ArrayList<>();
1319
1320 List<String> inactiveProfiles = new ArrayList<>();
1321
1322 if ( commandLine.hasOption( CLIManager.ACTIVATE_PROFILES ) )
1323 {
1324 String[] profileOptionValues = commandLine.getOptionValues( CLIManager.ACTIVATE_PROFILES );
1325 if ( profileOptionValues != null )
1326 {
1327 for ( String profileOptionValue : profileOptionValues )
1328 {
1329 StringTokenizer profileTokens = new StringTokenizer( profileOptionValue, "," );
1330
1331 while ( profileTokens.hasMoreTokens() )
1332 {
1333 String profileAction = profileTokens.nextToken().trim();
1334
1335 if ( profileAction.startsWith( "-" ) || profileAction.startsWith( "!" ) )
1336 {
1337 inactiveProfiles.add( profileAction.substring( 1 ) );
1338 }
1339 else if ( profileAction.startsWith( "+" ) )
1340 {
1341 activeProfiles.add( profileAction.substring( 1 ) );
1342 }
1343 else
1344 {
1345 activeProfiles.add( profileAction );
1346 }
1347 }
1348 }
1349 }
1350 }
1351
1352 TransferListener transferListener;
1353
1354 if ( quiet )
1355 {
1356 transferListener = new QuietMavenTransferListener();
1357 }
1358 else if ( request.isInteractiveMode() && !cliRequest.commandLine.hasOption( CLIManager.LOG_FILE ) )
1359 {
1360
1361
1362
1363
1364 transferListener = getConsoleTransferListener( cliRequest.commandLine.hasOption( CLIManager.DEBUG ) );
1365 }
1366 else
1367 {
1368 transferListener = getBatchTransferListener();
1369 }
1370
1371 ExecutionListener executionListener = new ExecutionEventLogger();
1372 if ( eventSpyDispatcher != null )
1373 {
1374 executionListener = eventSpyDispatcher.chainListener( executionListener );
1375 }
1376
1377 String alternatePomFile = null;
1378 if ( commandLine.hasOption( CLIManager.ALTERNATE_POM_FILE ) )
1379 {
1380 alternatePomFile = commandLine.getOptionValue( CLIManager.ALTERNATE_POM_FILE );
1381 }
1382
1383 File userToolchainsFile;
1384 if ( commandLine.hasOption( CLIManager.ALTERNATE_USER_TOOLCHAINS ) )
1385 {
1386 userToolchainsFile = new File( commandLine.getOptionValue( CLIManager.ALTERNATE_USER_TOOLCHAINS ) );
1387 userToolchainsFile = resolveFile( userToolchainsFile, workingDirectory );
1388 }
1389 else
1390 {
1391 userToolchainsFile = MavenCli.DEFAULT_USER_TOOLCHAINS_FILE;
1392 }
1393
1394 request.setBaseDirectory( baseDirectory ).setGoals( goals ).setSystemProperties(
1395 cliRequest.systemProperties ).setUserProperties( cliRequest.userProperties ).setReactorFailureBehavior(
1396 reactorFailureBehaviour )
1397 .setRecursive( recursive )
1398 .setShowErrors( showErrors )
1399 .addActiveProfiles( activeProfiles )
1400 .addInactiveProfiles( inactiveProfiles )
1401 .setExecutionListener( executionListener ).setTransferListener(
1402 transferListener )
1403 .setUpdateSnapshots( updateSnapshots )
1404 .setNoSnapshotUpdates( noSnapshotUpdates )
1405 .setGlobalChecksumPolicy( globalChecksumPolicy )
1406 .setMultiModuleProjectDirectory( cliRequest.multiModuleProjectDirectory );
1407
1408 if ( alternatePomFile != null )
1409 {
1410 File pom = resolveFile( new File( alternatePomFile ), workingDirectory );
1411 if ( pom.isDirectory() )
1412 {
1413 pom = new File( pom, "pom.xml" );
1414 }
1415
1416 request.setPom( pom );
1417 }
1418 else if ( modelProcessor != null )
1419 {
1420 File pom = modelProcessor.locatePom( baseDirectory );
1421
1422 if ( pom.isFile() )
1423 {
1424 request.setPom( pom );
1425 }
1426 }
1427
1428 if ( ( request.getPom() != null ) && ( request.getPom().getParentFile() != null ) )
1429 {
1430 request.setBaseDirectory( request.getPom().getParentFile() );
1431 }
1432
1433 if ( commandLine.hasOption( CLIManager.RESUME_FROM ) )
1434 {
1435 request.setResumeFrom( commandLine.getOptionValue( CLIManager.RESUME_FROM ) );
1436 }
1437
1438 if ( commandLine.hasOption( CLIManager.PROJECT_LIST ) )
1439 {
1440 String[] projectOptionValues = commandLine.getOptionValues( CLIManager.PROJECT_LIST );
1441
1442 List<String> inclProjects = new ArrayList<>();
1443 List<String> exclProjects = new ArrayList<>();
1444
1445 if ( projectOptionValues != null )
1446 {
1447 for ( String projectOptionValue : projectOptionValues )
1448 {
1449 StringTokenizer projectTokens = new StringTokenizer( projectOptionValue, "," );
1450
1451 while ( projectTokens.hasMoreTokens() )
1452 {
1453 String projectAction = projectTokens.nextToken().trim();
1454
1455 if ( projectAction.startsWith( "-" ) || projectAction.startsWith( "!" ) )
1456 {
1457 exclProjects.add( projectAction.substring( 1 ) );
1458 }
1459 else if ( projectAction.startsWith( "+" ) )
1460 {
1461 inclProjects.add( projectAction.substring( 1 ) );
1462 }
1463 else
1464 {
1465 inclProjects.add( projectAction );
1466 }
1467 }
1468 }
1469 }
1470
1471 request.setSelectedProjects( inclProjects );
1472 request.setExcludedProjects( exclProjects );
1473 }
1474
1475 if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && !commandLine.hasOption(
1476 CLIManager.ALSO_MAKE_DEPENDENTS ) )
1477 {
1478 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_UPSTREAM );
1479 }
1480 else if ( !commandLine.hasOption( CLIManager.ALSO_MAKE ) && commandLine.hasOption(
1481 CLIManager.ALSO_MAKE_DEPENDENTS ) )
1482 {
1483 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM );
1484 }
1485 else if ( commandLine.hasOption( CLIManager.ALSO_MAKE ) && commandLine.hasOption(
1486 CLIManager.ALSO_MAKE_DEPENDENTS ) )
1487 {
1488 request.setMakeBehavior( MavenExecutionRequest.REACTOR_MAKE_BOTH );
1489 }
1490
1491 String localRepoProperty = request.getUserProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1492
1493 if ( localRepoProperty == null )
1494 {
1495 localRepoProperty = request.getSystemProperties().getProperty( MavenCli.LOCAL_REPO_PROPERTY );
1496 }
1497
1498 if ( localRepoProperty != null )
1499 {
1500 request.setLocalRepositoryPath( localRepoProperty );
1501 }
1502
1503 request.setCacheNotFound( true );
1504 request.setCacheTransferError( false );
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514 final String threadConfiguration = commandLine.hasOption( CLIManager.THREADS )
1515 ? commandLine.getOptionValue( CLIManager.THREADS )
1516 : request.getSystemProperties().getProperty(
1517 MavenCli.THREADS_DEPRECATED );
1518
1519 if ( threadConfiguration != null )
1520 {
1521
1522
1523
1524 request.setBuilderId( "multithreaded" );
1525
1526 if ( threadConfiguration.contains( "C" ) )
1527 {
1528 request.setDegreeOfConcurrency( calculateDegreeOfConcurrencyWithCoreMultiplier( threadConfiguration ) );
1529 }
1530 else
1531 {
1532 request.setDegreeOfConcurrency( Integer.valueOf( threadConfiguration ) );
1533 }
1534 }
1535
1536
1537
1538
1539 if ( commandLine.hasOption( CLIManager.BUILDER ) )
1540 {
1541 request.setBuilderId( commandLine.getOptionValue( CLIManager.BUILDER ) );
1542 }
1543
1544 return request;
1545 }
1546
1547 int calculateDegreeOfConcurrencyWithCoreMultiplier( String threadConfiguration )
1548 {
1549 int procs = Runtime.getRuntime().availableProcessors();
1550 return (int) ( Float.valueOf( threadConfiguration.replace( "C", "" ) ) * procs );
1551 }
1552
1553 static File resolveFile( File file, String workingDirectory )
1554 {
1555 if ( file == null )
1556 {
1557 return null;
1558 }
1559 else if ( file.isAbsolute() )
1560 {
1561 return file;
1562 }
1563 else if ( file.getPath().startsWith( File.separator ) )
1564 {
1565
1566 return file.getAbsoluteFile();
1567 }
1568 else
1569 {
1570 return new File( workingDirectory, file.getPath() ).getAbsoluteFile();
1571 }
1572 }
1573
1574
1575
1576
1577
1578 static void populateProperties( CommandLine commandLine, Properties systemProperties, Properties userProperties )
1579 {
1580 EnvironmentUtils.addEnvVars( systemProperties );
1581
1582
1583
1584
1585
1586
1587
1588 if ( commandLine.hasOption( CLIManager.SET_SYSTEM_PROPERTY ) )
1589 {
1590 String[] defStrs = commandLine.getOptionValues( CLIManager.SET_SYSTEM_PROPERTY );
1591
1592 if ( defStrs != null )
1593 {
1594 for ( String defStr : defStrs )
1595 {
1596 setCliProperty( defStr, userProperties );
1597 }
1598 }
1599 }
1600
1601 SystemProperties.addSystemProperties( systemProperties );
1602
1603
1604
1605
1606
1607
1608 Properties buildProperties = CLIReportingUtils.getBuildProperties();
1609
1610 String mavenVersion = buildProperties.getProperty( CLIReportingUtils.BUILD_VERSION_PROPERTY );
1611 systemProperties.setProperty( "maven.version", mavenVersion );
1612
1613 String mavenBuildVersion = CLIReportingUtils.createMavenVersionString( buildProperties );
1614 systemProperties.setProperty( "maven.build.version", mavenBuildVersion );
1615 }
1616
1617 private static void setCliProperty( String property, Properties properties )
1618 {
1619 String name;
1620
1621 String value;
1622
1623 int i = property.indexOf( '=' );
1624
1625 if ( i <= 0 )
1626 {
1627 name = property.trim();
1628
1629 value = "true";
1630 }
1631 else
1632 {
1633 name = property.substring( 0, i ).trim();
1634
1635 value = property.substring( i + 1 );
1636 }
1637
1638 properties.setProperty( name, value );
1639
1640
1641
1642
1643
1644
1645 System.setProperty( name, value );
1646 }
1647
1648 static class ExitException
1649 extends Exception
1650 {
1651 @SuppressWarnings( "checkstyle:visibilitymodifier" )
1652 public int exitCode;
1653
1654 public ExitException( int exitCode )
1655 {
1656 this.exitCode = exitCode;
1657 }
1658 }
1659
1660
1661
1662
1663
1664 protected TransferListener getConsoleTransferListener( boolean printResourceNames )
1665 {
1666 return new ConsoleMavenTransferListener( System.out, printResourceNames );
1667 }
1668
1669 protected TransferListener getBatchTransferListener()
1670 {
1671 return new Slf4jMavenTransferListener();
1672 }
1673
1674 protected void customizeContainer( PlexusContainer container )
1675 {
1676 }
1677
1678 protected ModelProcessor createModelProcessor( PlexusContainer container )
1679 throws ComponentLookupException
1680 {
1681 return container.lookup( ModelProcessor.class );
1682 }
1683 }