1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.cling.invoker;
20
21 import java.io.FileNotFoundException;
22 import java.io.IOException;
23 import java.io.PrintWriter;
24 import java.nio.file.Files;
25 import java.nio.file.Path;
26 import java.util.ArrayList;
27 import java.util.HashSet;
28 import java.util.List;
29 import java.util.Locale;
30 import java.util.Map;
31 import java.util.Properties;
32 import java.util.function.Consumer;
33 import java.util.function.Function;
34
35 import org.apache.maven.api.Constants;
36 import org.apache.maven.api.ProtoSession;
37 import org.apache.maven.api.cli.Invoker;
38 import org.apache.maven.api.cli.InvokerException;
39 import org.apache.maven.api.cli.InvokerRequest;
40 import org.apache.maven.api.cli.Logger;
41 import org.apache.maven.api.cli.Options;
42 import org.apache.maven.api.services.BuilderProblem;
43 import org.apache.maven.api.services.Interpolator;
44 import org.apache.maven.api.services.Lookup;
45 import org.apache.maven.api.services.MavenException;
46 import org.apache.maven.api.services.MessageBuilder;
47 import org.apache.maven.api.services.SettingsBuilder;
48 import org.apache.maven.api.services.SettingsBuilderRequest;
49 import org.apache.maven.api.services.SettingsBuilderResult;
50 import org.apache.maven.api.services.Source;
51 import org.apache.maven.api.settings.Mirror;
52 import org.apache.maven.api.settings.Profile;
53 import org.apache.maven.api.settings.Proxy;
54 import org.apache.maven.api.settings.Repository;
55 import org.apache.maven.api.settings.Server;
56 import org.apache.maven.api.settings.Settings;
57 import org.apache.maven.api.spi.PropertyContributor;
58 import org.apache.maven.artifact.InvalidRepositoryException;
59 import org.apache.maven.artifact.repository.ArtifactRepository;
60 import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
61 import org.apache.maven.artifact.repository.MavenArtifactRepository;
62 import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
63 import org.apache.maven.bridge.MavenRepositorySystem;
64 import org.apache.maven.cling.invoker.spi.PropertyContributorsHolder;
65 import org.apache.maven.cling.logging.Slf4jConfiguration;
66 import org.apache.maven.cling.logging.Slf4jConfigurationFactory;
67 import org.apache.maven.cling.utils.CLIReportingUtils;
68 import org.apache.maven.execution.MavenExecutionRequest;
69 import org.apache.maven.internal.impl.SettingsUtilsV4;
70 import org.apache.maven.jline.FastTerminal;
71 import org.apache.maven.jline.MessageUtils;
72 import org.apache.maven.logging.LoggingOutputStream;
73 import org.apache.maven.logging.api.LogLevelRecorder;
74 import org.apache.maven.slf4j.MavenSimpleLogger;
75 import org.jline.terminal.Terminal;
76 import org.jline.terminal.TerminalBuilder;
77 import org.jline.terminal.impl.AbstractPosixTerminal;
78 import org.jline.terminal.spi.TerminalExt;
79 import org.slf4j.LoggerFactory;
80 import org.slf4j.spi.LocationAwareLogger;
81
82 import static java.util.Objects.requireNonNull;
83 import static org.apache.maven.cling.invoker.Utils.toMavenExecutionRequestLoggingLevel;
84 import static org.apache.maven.cling.invoker.Utils.toProperties;
85
86
87
88
89
90
91 public abstract class LookupInvoker<C extends LookupContext> implements Invoker {
92 protected final ProtoLookup protoLookup;
93
94 public LookupInvoker(ProtoLookup protoLookup) {
95 this.protoLookup = requireNonNull(protoLookup);
96 }
97
98 @Override
99 public int invoke(InvokerRequest invokerRequest) throws InvokerException {
100 requireNonNull(invokerRequest);
101
102 Properties oldProps = (Properties) System.getProperties().clone();
103 ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
104 try (C context = createContext(invokerRequest)) {
105 try {
106 if (context.containerCapsule != null
107 && context.containerCapsule.currentThreadClassLoader().isPresent()) {
108 Thread.currentThread()
109 .setContextClassLoader(context.containerCapsule
110 .currentThreadClassLoader()
111 .get());
112 }
113 return doInvoke(context);
114 } catch (InvokerException.ExitException e) {
115 return e.getExitCode();
116 } catch (Exception e) {
117 throw handleException(context, e);
118 }
119 } finally {
120 Thread.currentThread().setContextClassLoader(oldCL);
121 System.setProperties(oldProps);
122 }
123 }
124
125 protected int doInvoke(C context) throws Exception {
126 pushCoreProperties(context);
127 validate(context);
128 prepare(context);
129 configureLogging(context);
130 createTerminal(context);
131 activateLogging(context);
132 helpOrVersionAndMayExit(context);
133 preCommands(context);
134 container(context);
135 postContainer(context);
136 pushUserProperties(context);
137 lookup(context);
138 init(context);
139 postCommands(context);
140 settings(context);
141 return execute(context);
142 }
143
144 protected InvokerException handleException(C context, Exception e) throws InvokerException {
145 boolean showStackTrace = context.invokerRequest.options().showErrors().orElse(false);
146 if (showStackTrace) {
147 context.logger.error(
148 "Error executing " + context.invokerRequest.parserRequest().commandName() + ".", e);
149 } else {
150 context.logger.error(
151 "Error executing " + context.invokerRequest.parserRequest().commandName() + ".");
152 context.logger.error(e.getMessage());
153 for (Throwable cause = e.getCause(); cause != null && cause != cause.getCause(); cause = cause.getCause()) {
154 context.logger.error("Caused by: " + cause.getMessage());
155 }
156 }
157 return new InvokerException(e.getMessage(), e);
158 }
159
160 protected abstract C createContext(InvokerRequest invokerRequest) throws InvokerException;
161
162 protected void pushCoreProperties(C context) throws Exception {
163 System.setProperty(
164 Constants.MAVEN_HOME,
165 context.invokerRequest.installationDirectory().toString());
166 }
167
168 protected void pushUserProperties(C context) throws Exception {
169 ProtoSession protoSession = context.protoSession;
170 HashSet<String> sys = new HashSet<>(protoSession.getSystemProperties().keySet());
171 protoSession.getUserProperties().entrySet().stream()
172 .filter(k -> !sys.contains(k.getKey()))
173 .forEach(k -> System.setProperty(k.getKey(), k.getValue()));
174 }
175
176 protected void validate(C context) throws Exception {}
177
178 protected void prepare(C context) throws Exception {}
179
180 protected void configureLogging(C context) throws Exception {
181
182 Options mavenOptions = context.invokerRequest.options();
183 Map<String, String> userProperties = context.protoSession.getUserProperties();
184 String styleColor = mavenOptions
185 .color()
186 .orElse(userProperties.getOrDefault(
187 Constants.MAVEN_STYLE_COLOR_PROPERTY, userProperties.getOrDefault("style.color", "auto")));
188 if ("always".equals(styleColor) || "yes".equals(styleColor) || "force".equals(styleColor)) {
189 context.coloredOutput = true;
190 } else if ("never".equals(styleColor) || "no".equals(styleColor) || "none".equals(styleColor)) {
191 context.coloredOutput = false;
192 } else if (!"auto".equals(styleColor) && !"tty".equals(styleColor) && !"if-tty".equals(styleColor)) {
193 throw new IllegalArgumentException(
194 "Invalid color configuration value '" + styleColor + "'. Supported are 'auto', 'always', 'never'.");
195 } else {
196 boolean isBatchMode = !mavenOptions.forceInteractive().orElse(false)
197 && mavenOptions.nonInteractive().orElse(false);
198 if (isBatchMode || mavenOptions.logFile().isPresent()) {
199 context.coloredOutput = false;
200 }
201 }
202
203 context.loggerFactory = LoggerFactory.getILoggerFactory();
204 context.slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(context.loggerFactory);
205
206 context.loggerLevel = Slf4jConfiguration.Level.INFO;
207 if (mavenOptions.verbose().orElse(false)) {
208 context.loggerLevel = Slf4jConfiguration.Level.DEBUG;
209 } else if (mavenOptions.quiet().orElse(false)) {
210 context.loggerLevel = Slf4jConfiguration.Level.ERROR;
211 }
212 context.slf4jConfiguration.setRootLoggerLevel(context.loggerLevel);
213
214
215 }
216
217 protected void createTerminal(C context) {
218 MessageUtils.systemInstall(
219 builder -> {
220 builder.streams(
221 context.invokerRequest.in().orElse(null),
222 context.invokerRequest.out().orElse(null));
223 builder.systemOutput(TerminalBuilder.SystemOutput.ForcedSysOut);
224
225
226
227 builder.exec(false);
228 if (context.coloredOutput != null) {
229 builder.color(context.coloredOutput);
230 }
231 },
232 terminal -> doConfigureWithTerminal(context, terminal));
233
234 context.terminal = MessageUtils.getTerminal();
235
236
237 context.closeables.add(MessageUtils::systemUninstall);
238 MessageUtils.registerShutdownHook();
239 if (context.coloredOutput != null) {
240 MessageUtils.setColorEnabled(context.coloredOutput);
241 }
242 }
243
244 protected void doConfigureWithTerminal(C context, Terminal terminal) {
245 Options options = context.invokerRequest.options();
246 if (options.rawStreams().isEmpty() || !options.rawStreams().get()) {
247 MavenSimpleLogger stdout = (MavenSimpleLogger) context.loggerFactory.getLogger("stdout");
248 MavenSimpleLogger stderr = (MavenSimpleLogger) context.loggerFactory.getLogger("stderr");
249 stdout.setLogLevel(LocationAwareLogger.INFO_INT);
250 stderr.setLogLevel(LocationAwareLogger.INFO_INT);
251 System.setOut(new LoggingOutputStream(s -> stdout.info("[stdout] " + s)).printStream());
252 System.setErr(new LoggingOutputStream(s -> stderr.warn("[stderr] " + s)).printStream());
253
254 }
255 }
256
257 protected Consumer<String> determineWriter(C context) {
258 if (context.writer == null) {
259 context.writer = doDetermineWriter(context);
260 }
261 return context.writer;
262 }
263
264 protected Consumer<String> doDetermineWriter(C context) {
265 Options options = context.invokerRequest.options();
266 if (options.logFile().isPresent()) {
267 Path logFile = context.cwdResolver.apply(options.logFile().get());
268 try {
269 PrintWriter printWriter = new PrintWriter(Files.newBufferedWriter(logFile), true);
270 context.closeables.add(printWriter);
271 return printWriter::println;
272 } catch (IOException e) {
273 throw new MavenException("Unable to redirect logging to " + logFile, e);
274 }
275 } else {
276
277
278 return msg -> {
279 PrintWriter pw = context.terminal.writer();
280 pw.println(msg);
281 pw.flush();
282 };
283 }
284 }
285
286 protected void activateLogging(C context) throws Exception {
287 InvokerRequest invokerRequest = context.invokerRequest;
288 Options mavenOptions = invokerRequest.options();
289
290 context.slf4jConfiguration.activate();
291 org.slf4j.Logger l = context.loggerFactory.getLogger(this.getClass().getName());
292 context.logger = (level, message, error) -> l.atLevel(org.slf4j.event.Level.valueOf(level.name()))
293 .setCause(error)
294 .log(message);
295
296 if (mavenOptions.failOnSeverity().isPresent()) {
297 String logLevelThreshold = mavenOptions.failOnSeverity().get();
298 if (context.loggerFactory instanceof LogLevelRecorder recorder) {
299 LogLevelRecorder.Level level =
300 switch (logLevelThreshold.toLowerCase(Locale.ENGLISH)) {
301 case "warn", "warning" -> LogLevelRecorder.Level.WARN;
302 case "error" -> LogLevelRecorder.Level.ERROR;
303 default -> throw new IllegalArgumentException(
304 logLevelThreshold
305 + " is not a valid log severity threshold. Valid severities are WARN/WARNING and ERROR.");
306 };
307 recorder.setMaxLevelAllowed(level);
308 context.logger.info("Enabled to break the build on log level " + logLevelThreshold + ".");
309 } else {
310 context.logger.warn("Expected LoggerFactory to be of type '" + LogLevelRecorder.class.getName()
311 + "', but found '"
312 + context.loggerFactory.getClass().getName() + "' instead. "
313 + "The --fail-on-severity flag will not take effect.");
314 }
315 }
316 }
317
318 protected void helpOrVersionAndMayExit(C context) throws Exception {
319 InvokerRequest invokerRequest = context.invokerRequest;
320 if (invokerRequest.options().help().isPresent()) {
321 Consumer<String> writer = determineWriter(context);
322 invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), writer);
323 throw new InvokerException.ExitException(0);
324 }
325 if (invokerRequest.options().showVersionAndExit().isPresent()) {
326 showVersion(context);
327 throw new InvokerException.ExitException(0);
328 }
329 }
330
331 protected void showVersion(C context) {
332 Consumer<String> writer = determineWriter(context);
333 InvokerRequest invokerRequest = context.invokerRequest;
334 if (invokerRequest.options().quiet().orElse(false)) {
335 writer.accept(CLIReportingUtils.showVersionMinimal());
336 } else if (invokerRequest.options().verbose().orElse(false)) {
337 writer.accept(CLIReportingUtils.showVersion(
338 ProcessHandle.current().info().commandLine().orElse(null), describe(context.terminal)));
339
340 } else {
341 writer.accept(CLIReportingUtils.showVersion());
342 }
343 }
344
345 protected String describe(Terminal terminal) {
346 if (terminal == null) {
347 return null;
348 }
349 if (terminal instanceof FastTerminal ft) {
350 terminal = ft.getTerminal();
351 }
352 List<String> subs = new ArrayList<>();
353 subs.add("type=" + terminal.getType());
354 if (terminal instanceof TerminalExt te) {
355 subs.add("provider=" + te.getProvider().name());
356 }
357 if (terminal instanceof AbstractPosixTerminal pt) {
358 subs.add("pty=" + pt.getPty().getClass().getName());
359 }
360 return terminal.getClass().getSimpleName() + " (" + String.join(", ", subs) + ")";
361 }
362
363 protected void preCommands(C context) throws Exception {
364 Options mavenOptions = context.invokerRequest.options();
365 boolean verbose = mavenOptions.verbose().orElse(false);
366 boolean version = mavenOptions.showVersion().orElse(false);
367 if (verbose || version) {
368 showVersion(context);
369 }
370 }
371
372 protected void container(C context) throws Exception {
373 context.containerCapsule = createContainerCapsuleFactory().createContainerCapsule(this, context);
374 context.closeables.add(context::closeContainer);
375 context.lookup = context.containerCapsule.getLookup();
376
377
378 org.slf4j.Logger l = context.loggerFactory.getLogger(this.getClass().getName());
379 context.logger = (level, message, error) -> l.atLevel(org.slf4j.event.Level.valueOf(level.name()))
380 .setCause(error)
381 .log(message);
382 }
383
384 protected ContainerCapsuleFactory<C> createContainerCapsuleFactory() {
385 return new PlexusContainerCapsuleFactory<>();
386 }
387
388 protected void postContainer(C context) throws Exception {
389 ProtoSession protoSession = context.protoSession;
390 for (PropertyContributor propertyContributor : context.lookup
391 .lookup(PropertyContributorsHolder.class)
392 .getPropertyContributors()
393 .values()) {
394 protoSession = protoSession.toBuilder()
395 .withUserProperties(propertyContributor.contribute(protoSession))
396 .build();
397 }
398 context.protoSession = protoSession;
399 }
400
401 protected void lookup(C context) throws Exception {}
402
403 protected void init(C context) throws Exception {}
404
405 protected void postCommands(C context) throws Exception {
406 InvokerRequest invokerRequest = context.invokerRequest;
407 Logger logger = context.logger;
408 if (invokerRequest.options().showErrors().orElse(false)) {
409 logger.info("Error stacktraces are turned on.");
410 }
411 if (context.invokerRequest.options().verbose().orElse(false)) {
412 logger.debug("Message scheme: " + (MessageUtils.isColorEnabled() ? "color" : "plain"));
413 if (MessageUtils.isColorEnabled()) {
414 MessageBuilder buff = MessageUtils.builder();
415 buff.a("Message styles: ");
416 buff.trace("trace").a(' ');
417 buff.debug("debug").a(' ');
418 buff.info("info").a(' ');
419 buff.warning("warning").a(' ');
420 buff.error("error").a(' ');
421 buff.success("success").a(' ');
422 buff.failure("failure").a(' ');
423 buff.strong("strong").a(' ');
424 buff.mojo("mojo").a(' ');
425 buff.project("project");
426 logger.debug(buff.toString());
427 }
428 }
429 }
430
431 protected void settings(C context) throws Exception {
432 settings(context, context.lookup.lookup(SettingsBuilder.class));
433 }
434
435 protected void settings(C context, SettingsBuilder settingsBuilder) throws Exception {
436 Options mavenOptions = context.invokerRequest.options();
437 Path userSettingsFile = null;
438
439 if (mavenOptions.altUserSettings().isPresent()) {
440 userSettingsFile =
441 context.cwdResolver.apply(mavenOptions.altUserSettings().get());
442
443 if (!Files.isRegularFile(userSettingsFile)) {
444 throw new FileNotFoundException("The specified user settings file does not exist: " + userSettingsFile);
445 }
446 } else {
447 String userSettingsFileStr =
448 context.protoSession.getUserProperties().get(Constants.MAVEN_USER_SETTINGS);
449 if (userSettingsFileStr != null) {
450 userSettingsFile = context.userResolver.apply(userSettingsFileStr);
451 }
452 }
453
454 Path projectSettingsFile = null;
455
456 if (mavenOptions.altProjectSettings().isPresent()) {
457 projectSettingsFile =
458 context.cwdResolver.apply(mavenOptions.altProjectSettings().get());
459
460 if (!Files.isRegularFile(projectSettingsFile)) {
461 throw new FileNotFoundException(
462 "The specified project settings file does not exist: " + projectSettingsFile);
463 }
464 } else {
465 String projectSettingsFileStr =
466 context.protoSession.getUserProperties().get(Constants.MAVEN_PROJECT_SETTINGS);
467 if (projectSettingsFileStr != null) {
468 projectSettingsFile = context.cwdResolver.apply(projectSettingsFileStr);
469 }
470 }
471
472 Path installationSettingsFile = null;
473
474 if (mavenOptions.altInstallationSettings().isPresent()) {
475 installationSettingsFile = context.cwdResolver.apply(
476 mavenOptions.altInstallationSettings().get());
477
478 if (!Files.isRegularFile(installationSettingsFile)) {
479 throw new FileNotFoundException(
480 "The specified installation settings file does not exist: " + installationSettingsFile);
481 }
482 } else {
483 String installationSettingsFileStr =
484 context.protoSession.getUserProperties().get(Constants.MAVEN_INSTALLATION_SETTINGS);
485 if (installationSettingsFileStr != null) {
486 installationSettingsFile = context.installationResolver.apply(installationSettingsFileStr);
487 }
488 }
489
490 Function<String, String> interpolationSource = Interpolator.chain(
491 context.protoSession.getUserProperties()::get, context.protoSession.getSystemProperties()::get);
492 SettingsBuilderRequest settingsRequest = SettingsBuilderRequest.builder()
493 .session(context.protoSession)
494 .installationSettingsSource(
495 installationSettingsFile != null && Files.exists(installationSettingsFile)
496 ? Source.fromPath(installationSettingsFile)
497 : null)
498 .projectSettingsSource(
499 projectSettingsFile != null && Files.exists(projectSettingsFile)
500 ? Source.fromPath(projectSettingsFile)
501 : null)
502 .userSettingsSource(
503 userSettingsFile != null && Files.exists(userSettingsFile)
504 ? Source.fromPath(userSettingsFile)
505 : null)
506 .interpolationSource(interpolationSource)
507 .build();
508
509 customizeSettingsRequest(context, settingsRequest);
510
511 context.logger.debug("Reading installation settings from '" + installationSettingsFile + "'");
512 context.logger.debug("Reading project settings from '" + projectSettingsFile + "'");
513 context.logger.debug("Reading user settings from '" + userSettingsFile + "'");
514
515 SettingsBuilderResult settingsResult = settingsBuilder.build(settingsRequest);
516 customizeSettingsResult(context, settingsResult);
517
518 context.effectiveSettings = settingsResult.getEffectiveSettings();
519 context.interactive = mayDisableInteractiveMode(context, context.effectiveSettings.isInteractiveMode());
520 context.localRepositoryPath = localRepositoryPath(context);
521
522 if (!settingsResult.getProblems().isEmpty()) {
523 context.logger.warn("");
524 context.logger.warn("Some problems were encountered while building the effective settings");
525
526 for (BuilderProblem problem : settingsResult.getProblems()) {
527 context.logger.warn(problem.getMessage() + " @ " + problem.getLocation());
528 }
529 context.logger.warn("");
530 }
531 }
532
533 protected void customizeSettingsRequest(C context, SettingsBuilderRequest settingsBuilderRequest)
534 throws Exception {}
535
536 protected void customizeSettingsResult(C context, SettingsBuilderResult settingsBuilderResult) throws Exception {}
537
538 protected boolean mayDisableInteractiveMode(C context, boolean proposedInteractive) {
539 if (!context.invokerRequest.options().forceInteractive().orElse(false)) {
540 if (context.invokerRequest.options().nonInteractive().orElse(false)) {
541 return false;
542 } else {
543 boolean runningOnCI = isRunningOnCI(context);
544 if (runningOnCI) {
545 context.logger.info(
546 "Making this build non-interactive, because the environment variable CI equals \"true\"."
547 + " Disable this detection by removing that variable or adding --force-interactive.");
548 return false;
549 }
550 }
551 }
552 return proposedInteractive;
553 }
554
555 protected Path localRepositoryPath(C context) {
556
557 String userDefinedLocalRepo = context.protoSession.getUserProperties().get(Constants.MAVEN_REPO_LOCAL);
558 if (userDefinedLocalRepo == null) {
559 userDefinedLocalRepo = context.protoSession.getUserProperties().get(Constants.MAVEN_REPO_LOCAL);
560 if (userDefinedLocalRepo != null) {
561 context.logger.warn("The property '" + Constants.MAVEN_REPO_LOCAL
562 + "' has been set using a JVM system property which is deprecated. "
563 + "The property can be passed as a Maven argument or in the Maven project configuration file,"
564 + "usually located at ${session.rootDirectory}/.mvn/maven.properties.");
565 }
566 }
567 if (userDefinedLocalRepo != null) {
568 return context.cwdResolver.apply(userDefinedLocalRepo);
569 }
570
571 userDefinedLocalRepo = context.effectiveSettings.getLocalRepository();
572 if (userDefinedLocalRepo != null && !userDefinedLocalRepo.isEmpty()) {
573 return context.userResolver.apply(userDefinedLocalRepo);
574 }
575
576 return context.userResolver
577 .apply(context.protoSession.getUserProperties().get(Constants.MAVEN_USER_CONF))
578 .resolve("repository");
579 }
580
581 protected void populateRequest(C context, Lookup lookup, MavenExecutionRequest request) throws Exception {
582 populateRequestFromSettings(request, context.effectiveSettings);
583
584 Options options = context.invokerRequest.options();
585 request.setLoggingLevel(toMavenExecutionRequestLoggingLevel(context.loggerLevel));
586 request.setLocalRepositoryPath(context.localRepositoryPath.toFile());
587 request.setLocalRepository(createLocalArtifactRepository(context.localRepositoryPath));
588
589 request.setInteractiveMode(context.interactive);
590 request.setShowErrors(options.showErrors().orElse(false));
591 request.setBaseDirectory(context.invokerRequest.topDirectory().toFile());
592 request.setSystemProperties(toProperties(context.protoSession.getSystemProperties()));
593 request.setUserProperties(toProperties(context.protoSession.getUserProperties()));
594
595 request.setTopDirectory(context.invokerRequest.topDirectory());
596 if (context.invokerRequest.rootDirectory().isPresent()) {
597 request.setMultiModuleProjectDirectory(
598 context.invokerRequest.rootDirectory().get().toFile());
599 request.setRootDirectory(context.invokerRequest.rootDirectory().get());
600 }
601
602 request.addPluginGroup("org.apache.maven.plugins");
603 request.addPluginGroup("org.codehaus.mojo");
604 }
605
606
607
608
609 @Deprecated
610 private ArtifactRepository createLocalArtifactRepository(Path baseDirectory) {
611 DefaultRepositoryLayout layout = new DefaultRepositoryLayout();
612 ArtifactRepositoryPolicy blah = new ArtifactRepositoryPolicy(
613 true, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS, ArtifactRepositoryPolicy.CHECKSUM_POLICY_IGNORE);
614 return new MavenArtifactRepository(
615 "local", "file://" + baseDirectory.toUri().getRawPath(), layout, blah, blah);
616 }
617
618 protected void populateRequestFromSettings(MavenExecutionRequest request, Settings settings) throws Exception {
619 if (settings == null) {
620 return;
621 }
622 request.setOffline(settings.isOffline());
623 request.setInteractiveMode(settings.isInteractiveMode());
624 request.setPluginGroups(settings.getPluginGroups());
625 request.setLocalRepositoryPath(settings.getLocalRepository());
626 for (Server server : settings.getServers()) {
627 request.addServer(new org.apache.maven.settings.Server(server));
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642 for (Proxy proxy : settings.getProxies()) {
643 if (!proxy.isActive()) {
644 continue;
645 }
646 request.addProxy(new org.apache.maven.settings.Proxy(proxy));
647 }
648
649
650
651
652
653
654
655
656
657 for (Mirror mirror : settings.getMirrors()) {
658 request.addMirror(new org.apache.maven.settings.Mirror(mirror));
659 }
660
661 for (Repository remoteRepository : settings.getRepositories()) {
662 try {
663 request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(
664 new org.apache.maven.settings.Repository(remoteRepository)));
665 } catch (InvalidRepositoryException e) {
666
667 }
668 }
669
670 for (Repository pluginRepository : settings.getPluginRepositories()) {
671 try {
672 request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository(
673 new org.apache.maven.settings.Repository(pluginRepository)));
674 } catch (InvalidRepositoryException e) {
675
676 }
677 }
678
679 request.setActiveProfiles(settings.getActiveProfiles());
680 for (Profile rawProfile : settings.getProfiles()) {
681 request.addProfile(
682 new org.apache.maven.model.Profile(SettingsUtilsV4.convertFromSettingsProfile(rawProfile)));
683
684 if (settings.getActiveProfiles().contains(rawProfile.getId())) {
685 List<Repository> remoteRepositories = rawProfile.getRepositories();
686 for (Repository remoteRepository : remoteRepositories) {
687 try {
688 request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(
689 new org.apache.maven.settings.Repository(remoteRepository)));
690 } catch (InvalidRepositoryException e) {
691
692 }
693 }
694
695 List<Repository> pluginRepositories = rawProfile.getPluginRepositories();
696 for (Repository pluginRepository : pluginRepositories) {
697 try {
698 request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository(
699 new org.apache.maven.settings.Repository(pluginRepository)));
700 } catch (InvalidRepositoryException e) {
701
702 }
703 }
704 }
705 }
706 }
707
708 protected int calculateDegreeOfConcurrency(String threadConfiguration) {
709 try {
710 if (threadConfiguration.endsWith("C")) {
711 String str = threadConfiguration.substring(0, threadConfiguration.length() - 1);
712 float coreMultiplier = Float.parseFloat(str);
713
714 if (coreMultiplier <= 0.0f) {
715 throw new IllegalArgumentException("Invalid threads core multiplier value: '" + threadConfiguration
716 + "'. Value must be positive.");
717 }
718
719 int procs = Runtime.getRuntime().availableProcessors();
720 int threads = (int) (coreMultiplier * procs);
721 return threads == 0 ? 1 : threads;
722 } else {
723 int threads = Integer.parseInt(threadConfiguration);
724 if (threads <= 0) {
725 throw new IllegalArgumentException(
726 "Invalid threads value: '" + threadConfiguration + "'. Value must be positive.");
727 }
728 return threads;
729 }
730 } catch (NumberFormatException e) {
731 throw new IllegalArgumentException("Invalid threads value: '" + threadConfiguration
732 + "'. Supported are int and float values ending with C.");
733 }
734 }
735
736 protected boolean isRunningOnCI(C context) {
737 String ciEnv = context.protoSession.getSystemProperties().get("env.CI");
738 return ciEnv != null && !"false".equals(ciEnv);
739 }
740
741 protected abstract int execute(C context) throws Exception;
742 }