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