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