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