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