[MNG-8322] Use the new ToolchainsBuilder and SettingsBuilder (#1778)

This commit is contained in:
Guillaume Nodet 2024-10-17 11:25:53 +02:00 committed by GitHub
parent 95e59f2437
commit 69b34f4f3c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 1666 additions and 110 deletions

View File

@ -20,6 +20,7 @@ package org.apache.maven.api.services;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.BiFunction;
@ -138,6 +139,11 @@ public interface Interpolator extends Service {
};
}
@SafeVarargs
static Function<String, String> chain(Function<String, String>... functions) {
return chain(List.of(functions));
}
/**
* Memoizes a given function that takes a String input and produces a String output.
* This method creates a new function that caches the results of the original function,

View File

@ -21,6 +21,7 @@ package org.apache.maven.api.services;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Optional;
import java.util.function.Function;
import org.apache.maven.api.Session;
import org.apache.maven.api.annotations.Experimental;
@ -65,6 +66,14 @@ public interface SettingsBuilderRequest {
@Nonnull
Optional<Source> getUserSettingsSource();
/**
* The optional interpolation source used for interpolation.
*
* @return the interpolation source for interpolation
*/
@Nonnull
Optional<Function<String, String>> getInterpolationSource();
@Nonnull
static SettingsBuilderRequest build(
@Nonnull Session session, @Nonnull Source installationSettingsSource, @Nonnull Source userSettingsSource) {
@ -125,6 +134,7 @@ public interface SettingsBuilderRequest {
Source installationSettingsSource;
Source projectSettingsSource;
Source userSettingsSource;
Function<String, String> interpolationSource;
public SettingsBuilderRequestBuilder session(Session session) {
this.session = session;
@ -146,26 +156,38 @@ public interface SettingsBuilderRequest {
return this;
}
public SettingsBuilderRequestBuilder interpolationSource(Function<String, String> interpolationSource) {
this.interpolationSource = interpolationSource;
return this;
}
public SettingsBuilderRequest build() {
return new DefaultSettingsBuilderRequest(
session, installationSettingsSource, projectSettingsSource, userSettingsSource);
session,
installationSettingsSource,
projectSettingsSource,
userSettingsSource,
interpolationSource);
}
private static class DefaultSettingsBuilderRequest extends BaseRequest implements SettingsBuilderRequest {
private final Source installationSettingsSource;
private final Source projectSettingsSource;
private final Source userSettingsSource;
private final Function<String, String> interpolationSource;
@SuppressWarnings("checkstyle:ParameterNumber")
DefaultSettingsBuilderRequest(
@Nonnull Session session,
@Nullable Source installationSettingsSource,
@Nullable Source projectSettingsSource,
@Nullable Source userSettingsSource) {
@Nullable Source userSettingsSource,
@Nullable Function<String, String> interpolationSource) {
super(session);
this.installationSettingsSource = installationSettingsSource;
this.projectSettingsSource = projectSettingsSource;
this.userSettingsSource = userSettingsSource;
this.interpolationSource = interpolationSource;
}
@Nonnull
@ -185,6 +207,12 @@ public interface SettingsBuilderRequest {
public Optional<Source> getUserSettingsSource() {
return Optional.ofNullable(userSettingsSource);
}
@Nonnull
@Override
public Optional<Function<String, String>> getInterpolationSource() {
return Optional.ofNullable(interpolationSource);
}
}
}
}

View File

@ -225,9 +225,14 @@ public class DefaultSettingsBuilder implements SettingsBuilder {
}
private Settings interpolate(Settings settings, SettingsBuilderRequest request, List<BuilderProblem> problems) {
Map<String, String> userProperties = request.getSession().getUserProperties();
Map<String, String> systemProperties = request.getSession().getSystemProperties();
Function<String, String> src = Interpolator.chain(List.of(userProperties::get, systemProperties::get));
Function<String, String> src;
if (request.getInterpolationSource().isPresent()) {
src = request.getInterpolationSource().get();
} else {
Map<String, String> userProperties = request.getSession().getUserProperties();
Map<String, String> systemProperties = request.getSession().getSystemProperties();
src = Interpolator.chain(userProperties::get, systemProperties::get);
}
return new SettingsTransformer(value -> value != null ? interpolator.interpolate(value, src) : null)
.visit(settings);
}

View File

@ -56,13 +56,16 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder {
private final Interpolator interpolator;
private final ToolchainsXmlFactory toolchainsXmlFactory;
public DefaultToolchainsBuilder() {
this(new DefaultInterpolator());
this(new DefaultInterpolator(), new DefaultToolchainsXmlFactory());
}
@Inject
public DefaultToolchainsBuilder(Interpolator interpolator) {
public DefaultToolchainsBuilder(Interpolator interpolator, ToolchainsXmlFactory toolchainsXmlFactory) {
this.interpolator = interpolator;
this.toolchainsXmlFactory = toolchainsXmlFactory;
}
@Override
@ -110,25 +113,21 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder {
if (is == null) {
return PersistedToolchains.newInstance();
}
toolchains = request.getSession()
.getService(ToolchainsXmlFactory.class)
.read(XmlReaderRequest.builder()
.inputStream(is)
.location(toolchainsSource.getLocation())
.strict(true)
.build());
toolchains = toolchainsXmlFactory.read(XmlReaderRequest.builder()
.inputStream(is)
.location(toolchainsSource.getLocation())
.strict(true)
.build());
} catch (XmlReaderException e) {
InputStream is = toolchainsSource.openStream();
if (is == null) {
return PersistedToolchains.newInstance();
}
toolchains = request.getSession()
.getService(ToolchainsXmlFactory.class)
.read(XmlReaderRequest.builder()
.inputStream(is)
.location(toolchainsSource.getLocation())
.strict(false)
.build());
toolchains = toolchainsXmlFactory.read(XmlReaderRequest.builder()
.inputStream(is)
.location(toolchainsSource.getLocation())
.strict(false)
.build());
Location loc = e.getCause() instanceof XMLStreamException xe ? xe.getLocation() : null;
problems.add(new DefaultBuilderProblem(
toolchainsSource.getLocation(),
@ -168,7 +167,7 @@ public class DefaultToolchainsBuilder implements ToolchainsBuilder {
PersistedToolchains toolchains, ToolchainsBuilderRequest request, List<BuilderProblem> problems) {
Map<String, String> userProperties = request.getSession().getUserProperties();
Map<String, String> systemProperties = request.getSession().getSystemProperties();
Function<String, String> src = Interpolator.chain(List.of(userProperties::get, systemProperties::get));
Function<String, String> src = Interpolator.chain(userProperties::get, systemProperties::get);
return new MavenToolchainsTransformer(value -> value != null ? interpolator.interpolate(value, src) : null)
.visit(toolchains);
}

View File

@ -1741,7 +1741,7 @@ public class DefaultModelBuilder implements ModelBuilder {
try {
Map<String, String> map1 = context.getUserProperties();
Map<String, String> map2 = context.getSystemProperties();
return interpolator.interpolate(s, Interpolator.chain(List.of(map1::get, map2::get)));
return interpolator.interpolate(s, Interpolator.chain(map1::get, map2::get));
} catch (InterpolatorException e) {
problems.add(Severity.ERROR, Version.BASE, e.getMessage(), e);
}
@ -1873,7 +1873,7 @@ public class DefaultModelBuilder implements ModelBuilder {
Map<String, String> map1 = request.getSession().getUserProperties();
Map<String, String> map2 = model.getProperties();
Map<String, String> map3 = request.getSession().getSystemProperties();
Function<String, String> cb = Interpolator.chain(List.of(map1::get, map2::get, map3::get));
Function<String, String> cb = Interpolator.chain(map1::get, map2::get, map3::get);
try {
String interpolated =
interpolator.interpolate(interpolatedModel.getParent().getVersion(), cb);

View File

@ -352,6 +352,7 @@ public class ApiRunner {
// local repository
String localRepository = settings.getLocalRepository() != null
&& !settings.getLocalRepository().isEmpty()
? settings.getLocalRepository()
: mavenUserHome.resolve("repository").toString();
LocalRepositoryManager llm = system.newLocalRepositoryManager(rsession, new LocalRepository(localRepository));

View File

@ -25,6 +25,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
@ -33,14 +34,27 @@ import java.util.Properties;
import java.util.function.Function;
import org.apache.maven.api.Constants;
import org.apache.maven.api.Session;
import org.apache.maven.api.cli.Invoker;
import org.apache.maven.api.cli.InvokerException;
import org.apache.maven.api.cli.InvokerRequest;
import org.apache.maven.api.cli.Logger;
import org.apache.maven.api.cli.Options;
import org.apache.maven.api.services.BuilderProblem;
import org.apache.maven.api.services.Interpolator;
import org.apache.maven.api.services.Lookup;
import org.apache.maven.api.services.MavenException;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.SettingsBuilder;
import org.apache.maven.api.services.SettingsBuilderRequest;
import org.apache.maven.api.services.SettingsBuilderResult;
import org.apache.maven.api.services.Source;
import org.apache.maven.api.settings.Mirror;
import org.apache.maven.api.settings.Profile;
import org.apache.maven.api.settings.Proxy;
import org.apache.maven.api.settings.Repository;
import org.apache.maven.api.settings.Server;
import org.apache.maven.api.settings.Settings;
import org.apache.maven.artifact.InvalidRepositoryException;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
@ -54,7 +68,9 @@ import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
import org.apache.maven.cli.transfer.SimplexTransferListener;
import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
import org.apache.maven.cling.invoker.mvn.ProtoSession;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.internal.impl.SettingsUtilsV4;
import org.apache.maven.jline.FastTerminal;
import org.apache.maven.jline.MessageUtils;
import org.apache.maven.logging.BuildEventListener;
@ -62,18 +78,6 @@ import org.apache.maven.logging.LoggingOutputStream;
import org.apache.maven.logging.ProjectBuildLogAppender;
import org.apache.maven.logging.SimpleBuildEventListener;
import org.apache.maven.logging.api.LogLevelRecorder;
import org.apache.maven.settings.Mirror;
import org.apache.maven.settings.Profile;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Repository;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;
import org.apache.maven.settings.SettingsUtils;
import org.apache.maven.settings.building.DefaultSettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuilder;
import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingResult;
import org.apache.maven.settings.building.SettingsProblem;
import org.apache.maven.slf4j.MavenSimpleLogger;
import org.eclipse.aether.transfer.TransferListener;
import org.jline.jansi.AnsiConsole;
@ -84,7 +88,6 @@ import org.slf4j.LoggerFactory;
import org.slf4j.spi.LocationAwareLogger;
import static java.util.Objects.requireNonNull;
import static org.apache.maven.cling.invoker.Utils.toFile;
import static org.apache.maven.cling.invoker.Utils.toMavenExecutionRequestLoggingLevel;
import static org.apache.maven.cling.invoker.Utils.toProperties;
@ -122,6 +125,7 @@ public abstract class LookupInvoker<
public final Function<String, Path> cwdResolver;
public final Function<String, Path> installationResolver;
public final Function<String, Path> userResolver;
public final Session session;
protected LookupInvokerContext(LookupInvoker<O, R, C> invoker, R invokerRequest) {
this.invoker = invoker;
@ -136,6 +140,12 @@ public abstract class LookupInvoker<
this.userResolver = s ->
invokerRequest.userHomeDirectory().resolve(s).normalize().toAbsolutePath();
this.logger = invokerRequest.parserRequest().logger();
Map<String, String> user = new HashMap<>(invokerRequest.userProperties());
user.put("session.rootDirectory", invokerRequest.rootDirectory().toString());
user.put("session.topDirectory", invokerRequest.topDirectory().toString());
Map<String, String> system = new HashMap<>(invokerRequest.systemProperties());
this.session = ProtoSession.create(user, system);
}
public Logger logger;
@ -535,36 +545,32 @@ public abstract class LookupInvoker<
context.projectSettingsPath = projectSettingsFile;
context.userSettingsPath = userSettingsFile;
SettingsBuildingRequest settingsRequest = new DefaultSettingsBuildingRequest();
settingsRequest.setGlobalSettingsFile(toFile(installationSettingsFile));
settingsRequest.setProjectSettingsFile(toFile(projectSettingsFile));
settingsRequest.setUserSettingsFile(toFile(userSettingsFile));
settingsRequest.setSystemProperties(toProperties(context.invokerRequest.systemProperties()));
Properties props = toProperties(context.invokerRequest.userProperties());
props.put(
"session.rootDirectory", context.invokerRequest.rootDirectory().toString());
props.put("session.topDirectory", context.invokerRequest.topDirectory().toString());
Function<String, String> interpolationSource = Interpolator.chain(
context.invokerRequest.userProperties()::get, context.invokerRequest.systemProperties()::get);
SettingsBuilderRequest settingsRequest = SettingsBuilderRequest.builder()
.session(context.session)
.installationSettingsSource(
installationSettingsFile != null && Files.exists(installationSettingsFile)
? Source.fromPath(installationSettingsFile)
: null)
.projectSettingsSource(
projectSettingsFile != null && Files.exists(projectSettingsFile)
? Source.fromPath(projectSettingsFile)
: null)
.userSettingsSource(
userSettingsFile != null && Files.exists(userSettingsFile)
? Source.fromPath(userSettingsFile)
: null)
.interpolationSource(interpolationSource)
.build();
settingsRequest.setUserProperties(props);
customizeSettingsRequest(context, settingsRequest);
context.logger.debug("Reading installation settings from '"
+ (settingsRequest.getGlobalSettingsSource() != null
? settingsRequest.getGlobalSettingsSource().getLocation()
: settingsRequest.getGlobalSettingsFile())
+ "'");
context.logger.debug("Reading project settings from '"
+ (settingsRequest.getProjectSettingsSource() != null
? settingsRequest.getProjectSettingsSource().getLocation()
: settingsRequest.getProjectSettingsFile())
+ "'");
context.logger.debug("Reading user settings from '"
+ (settingsRequest.getUserSettingsSource() != null
? settingsRequest.getUserSettingsSource().getLocation()
: settingsRequest.getUserSettingsFile())
+ "'");
context.logger.debug("Reading installation settings from '" + installationSettingsFile + "'");
context.logger.debug("Reading project settings from '" + projectSettingsFile + "'");
context.logger.debug("Reading user settings from '" + userSettingsFile + "'");
SettingsBuildingResult settingsResult = settingsBuilder.build(settingsRequest);
SettingsBuilderResult settingsResult = settingsBuilder.build(settingsRequest);
customizeSettingsResult(context, settingsResult);
context.effectiveSettings = settingsResult.getEffectiveSettings();
@ -575,17 +581,17 @@ public abstract class LookupInvoker<
context.logger.warn("");
context.logger.warn("Some problems were encountered while building the effective settings");
for (SettingsProblem problem : settingsResult.getProblems()) {
for (BuilderProblem problem : settingsResult.getProblems()) {
context.logger.warn(problem.getMessage() + " @ " + problem.getLocation());
}
context.logger.warn("");
}
}
protected void customizeSettingsRequest(C context, SettingsBuildingRequest settingsBuildingRequest)
protected void customizeSettingsRequest(C context, SettingsBuilderRequest settingsBuilderRequest)
throws Exception {}
protected void customizeSettingsResult(C context, SettingsBuildingResult settingsBuildingResult) throws Exception {}
protected void customizeSettingsResult(C context, SettingsBuilderResult settingsBuilderResult) throws Exception {}
protected boolean mayDisableInteractiveMode(C context, boolean proposedInteractive) {
if (!context.invokerRequest.options().forceInteractive().orElse(false)) {
@ -676,7 +682,7 @@ public abstract class LookupInvoker<
request.setPluginGroups(settings.getPluginGroups());
request.setLocalRepositoryPath(settings.getLocalRepository());
for (Server server : settings.getServers()) {
request.addServer(server);
request.addServer(new org.apache.maven.settings.Server(server));
}
// <proxies>
@ -695,7 +701,7 @@ public abstract class LookupInvoker<
if (!proxy.isActive()) {
continue;
}
request.addProxy(proxy);
request.addProxy(new org.apache.maven.settings.Proxy(proxy));
}
// <mirrors>
@ -707,12 +713,13 @@ public abstract class LookupInvoker<
// </mirrors>
for (Mirror mirror : settings.getMirrors()) {
request.addMirror(mirror);
request.addMirror(new org.apache.maven.settings.Mirror(mirror));
}
for (Repository remoteRepository : settings.getRepositories()) {
try {
request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(remoteRepository));
request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(
new org.apache.maven.settings.Repository(remoteRepository)));
} catch (InvalidRepositoryException e) {
// do nothing for now
}
@ -720,7 +727,8 @@ public abstract class LookupInvoker<
for (Repository pluginRepository : settings.getPluginRepositories()) {
try {
request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository(pluginRepository));
request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository(
new org.apache.maven.settings.Repository(pluginRepository)));
} catch (InvalidRepositoryException e) {
// do nothing for now
}
@ -728,13 +736,15 @@ public abstract class LookupInvoker<
request.setActiveProfiles(settings.getActiveProfiles());
for (Profile rawProfile : settings.getProfiles()) {
request.addProfile(SettingsUtils.convertFromSettingsProfile(rawProfile));
request.addProfile(
new org.apache.maven.model.Profile(SettingsUtilsV4.convertFromSettingsProfile(rawProfile)));
if (settings.getActiveProfiles().contains(rawProfile.getId())) {
List<Repository> remoteRepositories = rawProfile.getRepositories();
for (Repository remoteRepository : remoteRepositories) {
try {
request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(remoteRepository));
request.addRemoteRepository(MavenRepositorySystem.buildArtifactRepository(
new org.apache.maven.settings.Repository(remoteRepository)));
} catch (InvalidRepositoryException e) {
// do nothing for now
}
@ -743,8 +753,8 @@ public abstract class LookupInvoker<
List<Repository> pluginRepositories = rawProfile.getPluginRepositories();
for (Repository pluginRepository : pluginRepositories) {
try {
request.addPluginArtifactRepository(
MavenRepositorySystem.buildArtifactRepository(pluginRepository));
request.addPluginArtifactRepository(MavenRepositorySystem.buildArtifactRepository(
new org.apache.maven.settings.Repository(pluginRepository)));
} catch (InvalidRepositoryException e) {
// do nothing for now
}

View File

@ -36,6 +36,7 @@ import org.apache.maven.api.cli.Logger;
import org.apache.maven.api.cli.Options;
import org.apache.maven.api.cli.extensions.CoreExtension;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.api.services.SettingsBuilder;
import org.apache.maven.cli.ExtensionConfigurationModule;
import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
import org.apache.maven.cli.logging.Slf4jLoggerManager;
@ -49,7 +50,6 @@ import org.apache.maven.extension.internal.CoreExports;
import org.apache.maven.extension.internal.CoreExtensionEntry;
import org.apache.maven.session.scope.internal.SessionScope;
import org.apache.maven.session.scope.internal.SessionScopeModule;
import org.apache.maven.settings.building.SettingsBuilder;
import org.codehaus.plexus.ContainerConfiguration;
import org.codehaus.plexus.DefaultContainerConfiguration;
import org.codehaus.plexus.DefaultPlexusContainer;

View File

@ -37,8 +37,14 @@ import org.apache.maven.api.cli.Logger;
import org.apache.maven.api.cli.mvn.MavenInvoker;
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
import org.apache.maven.api.cli.mvn.MavenOptions;
import org.apache.maven.building.FileSource;
import org.apache.maven.building.Problem;
import org.apache.maven.api.services.BuilderProblem;
import org.apache.maven.api.services.SettingsBuilderRequest;
import org.apache.maven.api.services.SettingsBuilderResult;
import org.apache.maven.api.services.Source;
import org.apache.maven.api.services.ToolchainsBuilder;
import org.apache.maven.api.services.ToolchainsBuilderRequest;
import org.apache.maven.api.services.ToolchainsBuilderResult;
import org.apache.maven.api.services.model.ModelProcessor;
import org.apache.maven.cli.CLIReportingUtils;
import org.apache.maven.cli.event.ExecutionEventLogger;
import org.apache.maven.cling.invoker.LookupInvoker;
@ -59,13 +65,7 @@ import org.apache.maven.jline.MessageUtils;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.logging.LoggingExecutionListener;
import org.apache.maven.logging.MavenTransferListener;
import org.apache.maven.model.building.ModelProcessor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.building.SettingsBuildingRequest;
import org.apache.maven.settings.building.SettingsBuildingResult;
import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
import org.apache.maven.toolchain.building.ToolchainsBuilder;
import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
import org.codehaus.plexus.PlexusContainer;
import org.eclipse.aether.DefaultRepositoryCache;
import org.eclipse.aether.transfer.TransferListener;
@ -162,16 +162,16 @@ public abstract class DefaultMavenInvoker<
}
@Override
protected void customizeSettingsRequest(C context, SettingsBuildingRequest settingsBuildingRequest) {
protected void customizeSettingsRequest(C context, SettingsBuilderRequest settingsBuilderRequest) {
if (context.eventSpyDispatcher != null) {
context.eventSpyDispatcher.onEvent(settingsBuildingRequest);
context.eventSpyDispatcher.onEvent(settingsBuilderRequest);
}
}
@Override
protected void customizeSettingsResult(C context, SettingsBuildingResult settingsBuildingResult) {
protected void customizeSettingsResult(C context, SettingsBuilderResult settingsBuilderResult) throws Exception {
if (context.eventSpyDispatcher != null) {
context.eventSpyDispatcher.onEvent(settingsBuildingResult);
context.eventSpyDispatcher.onEvent(settingsBuilderResult);
}
}
@ -217,39 +217,36 @@ public abstract class DefaultMavenInvoker<
context.mavenExecutionRequest.setUserToolchainsFile(
userToolchainsFile != null ? userToolchainsFile.toFile() : null);
DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
if (installationToolchainsFile != null && Files.isRegularFile(installationToolchainsFile)) {
toolchainsRequest.setGlobalToolchainsSource(new FileSource(installationToolchainsFile));
}
if (userToolchainsFile != null && Files.isRegularFile(userToolchainsFile)) {
toolchainsRequest.setUserToolchainsSource(new FileSource(userToolchainsFile));
}
ToolchainsBuilderRequest toolchainsRequest = ToolchainsBuilderRequest.builder()
.session(context.session)
.installationToolchainsSource(
installationToolchainsFile != null && Files.isRegularFile(installationToolchainsFile)
? Source.fromPath(installationToolchainsFile)
: null)
.userToolchainsSource(
userToolchainsFile != null && Files.isRegularFile(userToolchainsFile)
? Source.fromPath(userToolchainsFile)
: null)
.build();
context.eventSpyDispatcher.onEvent(toolchainsRequest);
context.logger.debug("Reading installation toolchains from '"
+ (toolchainsRequest.getGlobalToolchainsSource() != null
? toolchainsRequest.getGlobalToolchainsSource().getLocation()
: installationToolchainsFile)
+ "'");
context.logger.debug("Reading user toolchains from '"
+ (toolchainsRequest.getUserToolchainsSource() != null
? toolchainsRequest.getUserToolchainsSource().getLocation()
: userToolchainsFile)
+ "'");
context.logger.debug("Reading installation toolchains from '" + installationToolchainsFile + "'");
context.logger.debug("Reading user toolchains from '" + userToolchainsFile + "'");
ToolchainsBuildingResult toolchainsResult = context.toolchainsBuilder.build(toolchainsRequest);
ToolchainsBuilderResult toolchainsResult = context.toolchainsBuilder.build(toolchainsRequest);
context.eventSpyDispatcher.onEvent(toolchainsResult);
context.mavenExecutionRequestPopulator.populateFromToolchains(
context.mavenExecutionRequest, toolchainsResult.getEffectiveToolchains());
context.mavenExecutionRequest,
new org.apache.maven.toolchain.model.PersistedToolchains(toolchainsResult.getEffectiveToolchains()));
if (!toolchainsResult.getProblems().isEmpty()) {
context.logger.warn("");
context.logger.warn("Some problems were encountered while building the effective toolchains");
for (Problem problem : toolchainsResult.getProblems()) {
for (BuilderProblem problem : toolchainsResult.getProblems()) {
context.logger.warn(problem.getMessage() + " @ " + problem.getLocation());
}

View File

@ -0,0 +1,409 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.cling.invoker.mvn;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.Instant;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.maven.api.Artifact;
import org.apache.maven.api.Lifecycle;
import org.apache.maven.api.Packaging;
import org.apache.maven.api.ProducedArtifact;
import org.apache.maven.api.Project;
import org.apache.maven.api.RemoteRepository;
import org.apache.maven.api.Session;
import org.apache.maven.api.Type;
import org.apache.maven.api.Version;
import org.apache.maven.api.di.Provides;
import org.apache.maven.api.di.SessionScoped;
import org.apache.maven.api.model.PluginContainer;
import org.apache.maven.api.model.Profile;
import org.apache.maven.api.services.ArtifactManager;
import org.apache.maven.api.services.LifecycleRegistry;
import org.apache.maven.api.services.Lookup;
import org.apache.maven.api.services.MavenException;
import org.apache.maven.api.services.PackagingRegistry;
import org.apache.maven.api.services.RepositoryFactory;
import org.apache.maven.api.services.SettingsBuilder;
import org.apache.maven.api.services.TypeRegistry;
import org.apache.maven.api.settings.Settings;
import org.apache.maven.api.spi.TypeProvider;
import org.apache.maven.di.Injector;
import org.apache.maven.di.Key;
import org.apache.maven.di.impl.DIException;
import org.apache.maven.internal.impl.AbstractSession;
import org.apache.maven.internal.impl.InternalSession;
import org.apache.maven.internal.impl.di.SessionScope;
import org.eclipse.aether.DefaultRepositorySystemSession;
import org.eclipse.aether.RepositorySystem;
import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.impl.RemoteRepositoryManager;
import org.eclipse.aether.repository.LocalRepository;
import org.eclipse.aether.repository.LocalRepositoryManager;
public class ProtoSession extends AbstractSession {
private final Map<String, String> userProperties;
private final Map<String, String> systemProperties;
private final Instant startTime = Instant.now();
ProtoSession(RepositorySystemSession session, RepositorySystem repositorySystem, Lookup lookup) {
this(session, repositorySystem, Collections.emptyList(), null, lookup, new Context(Map.of(), Map.of()));
}
protected ProtoSession(
RepositorySystemSession session,
RepositorySystem repositorySystem,
List<RemoteRepository> repositories,
List<org.eclipse.aether.repository.RemoteRepository> resolverRepositories,
Lookup lookup,
Context context) {
super(session, repositorySystem, repositories, resolverRepositories, lookup);
userProperties = context.userProperties;
systemProperties = context.systemProperties;
}
/**
*
*/
public static Session create() {
Map<String, String> properties = new HashMap<>();
// Env variables prefixed with "env."
System.getenv().forEach((k, v) -> properties.put("env." + k, v));
// Java System properties
System.getProperties().forEach((k, v) -> properties.put(k.toString(), v.toString()));
// create session
return create(Map.of(), properties);
}
/**
* Create a new session.
*/
public static Session create(Map<String, String> userProperties, Map<String, String> systemProperties) {
Injector injector = Injector.create();
injector.bindInstance(Injector.class, injector);
injector.bindInstance(Context.class, new Context(userProperties, systemProperties));
injector.bindImplicit(Providers.class);
injector.discover(ProtoSession.class.getClassLoader());
Session session = injector.getInstance(Session.class);
SessionScope scope = new SessionScope();
scope.enter();
scope.seed(Session.class, session);
injector.bindScope(SessionScoped.class, scope);
return session;
}
record Context(Map<String, String> userProperties, Map<String, String> systemProperties) {}
@Override
protected Session newSession(RepositorySystemSession session, List<RemoteRepository> repositories) {
return new ProtoSession(
session, repositorySystem, repositories, null, lookup, new Context(userProperties, systemProperties));
}
@Override
public Settings getSettings() {
return Settings.newInstance();
}
@Override
public Map<String, String> getUserProperties() {
return Map.of();
}
@Override
public Map<String, String> getSystemProperties() {
return systemProperties;
}
@Override
public Map<String, String> getEffectiveProperties(Project project) {
HashMap<String, String> result = new HashMap<>(getSystemProperties());
if (project != null) {
result.putAll(project.getModel().getProperties());
}
result.putAll(getUserProperties());
return result;
}
@Override
public Version getMavenVersion() {
return null;
}
@Override
public int getDegreeOfConcurrency() {
return 0;
}
@Override
public Instant getStartTime() {
return startTime;
}
@Override
public Path getTopDirectory() {
return null;
}
@Override
public Path getRootDirectory() {
throw new IllegalStateException();
}
@Override
public List<Project> getProjects() {
return List.of();
}
@Override
public Map<String, Object> getPluginContext(Project project) {
throw new UnsupportedInStandaloneModeException();
}
static class Providers {
@Provides
@SuppressWarnings("unused")
static Lookup newLookup(Injector injector) {
return new Lookup() {
@Override
public <T> T lookup(Class<T> type) {
try {
return injector.getInstance(type);
} catch (DIException e) {
throw new MavenException("Unable to locate instance of type " + type, e);
}
}
@Override
public <T> T lookup(Class<T> type, String name) {
try {
return injector.getInstance(Key.of(type, name));
} catch (DIException e) {
throw new MavenException("Unable to locate instance of type " + type, e);
}
}
@Override
public <T> Optional<T> lookupOptional(Class<T> type) {
try {
return Optional.of(injector.getInstance(type));
} catch (DIException e) {
return Optional.empty();
}
}
@Override
public <T> Optional<T> lookupOptional(Class<T> type, String name) {
try {
return Optional.of(injector.getInstance(Key.of(type, name)));
} catch (DIException e) {
return Optional.empty();
}
}
@Override
public <T> List<T> lookupList(Class<T> type) {
return injector.getInstance(new Key<List<T>>() {});
}
@Override
public <T> Map<String, T> lookupMap(Class<T> type) {
return injector.getInstance(new Key<Map<String, T>>() {});
}
};
}
@Provides
@SuppressWarnings("unused")
static ArtifactManager newArtifactManager() {
return new ArtifactManager() {
private final Map<Artifact, Path> paths = new ConcurrentHashMap<>();
@Override
public Optional<Path> getPath(Artifact artifact) {
return Optional.ofNullable(paths.get(artifact));
}
@Override
public void setPath(ProducedArtifact artifact, Path path) {
paths.put(artifact, path);
}
};
}
@Provides
@SuppressWarnings("unused")
static PackagingRegistry newPackagingRegistry(TypeRegistry typeRegistry) {
return id -> Optional.of(new DumbPackaging(id, typeRegistry.require(id), Map.of()));
}
@Provides
@SuppressWarnings("unused")
static TypeRegistry newTypeRegistry(List<TypeProvider> providers) {
return new TypeRegistry() {
@Override
public Optional<Type> lookup(String id) {
return providers.stream()
.flatMap(p -> p.provides().stream())
.filter(t -> Objects.equals(id, t.id()))
.findAny();
}
};
}
@Provides
@SuppressWarnings("unused")
static LifecycleRegistry newLifecycleRegistry() {
return new LifecycleRegistry() {
@Override
public Iterator<Lifecycle> iterator() {
return Collections.emptyIterator();
}
@Override
public Optional<Lifecycle> lookup(String id) {
return Optional.empty();
}
@Override
public List<String> computePhases(Lifecycle lifecycle) {
return List.of();
}
};
}
@Provides
@SuppressWarnings("unused")
static RepositorySystemSupplier newRepositorySystemSupplier() {
return new RepositorySystemSupplier();
}
@Provides
@SuppressWarnings("unused")
static RepositorySystem newRepositorySystem(RepositorySystemSupplier repositorySystemSupplier) {
return repositorySystemSupplier.getRepositorySystem();
}
@Provides
@SuppressWarnings("unused")
static RemoteRepositoryManager newRemoteRepositoryManager(RepositorySystemSupplier repositorySystemSupplier) {
return repositorySystemSupplier.getRemoteRepositoryManager();
}
@Provides
@SuppressWarnings("unused")
static Session newSession(RepositorySystem system, Lookup lookup, Context context) {
// SettingsDecrypter settingsDecrypter =
// (SettingsDecrypter)Objects.requireNonNull(this.createSettingsDecrypter(preBoot));
// new DefaultProfileSelector(List.of(
// new JdkVersionProfileActivator(),
// new PropertyProfileActivator(),
// new OperatingSystemProfileActivator(),
// new FileProfileActivator(new ProfileActivationFilePathInterpolator(
// new DefaultPathTranslator(), new DefaultRootLocator()))));
Map<String, String> properties = context.systemProperties;
Path userHome = Paths.get(properties.get("user.home"));
Path mavenUserHome = userHome.resolve(".m2");
Path mavenSystemHome = properties.containsKey("maven.home")
? Paths.get(properties.get("maven.home"))
: properties.containsKey("env.MAVEN_HOME") ? Paths.get(properties.get("env.MAVEN_HOME")) : null;
DefaultRepositorySystemSession rsession = new DefaultRepositorySystemSession(h -> false);
rsession.setSystemProperties(properties);
rsession.setConfigProperties(properties);
ProtoSession session = new ProtoSession(
rsession,
system,
List.of(lookup.lookup(RepositoryFactory.class)
.createRemote("central", "https://repo.maven.apache.org/maven2")),
null,
lookup,
context);
Settings settings = session.getService(SettingsBuilder.class)
.build(
session,
mavenSystemHome != null ? mavenSystemHome.resolve("settings.xml") : null,
mavenUserHome.resolve("settings.xml"))
.getEffectiveSettings();
settings.getProfiles();
// local repository
String localRepository = settings.getLocalRepository() != null
? settings.getLocalRepository()
: mavenUserHome.resolve("repository").toString();
LocalRepositoryManager llm =
system.newLocalRepositoryManager(rsession, new LocalRepository(localRepository));
rsession.setLocalRepositoryManager(llm);
// active proxies
// TODO
// active profiles
// DefaultSession defaultSession = new DefaultSession(
// rsession,
// system,
// List.of(lookup.lookup(RepositoryFactory.class)
// .createRemote("central", "https://repo.maven.apache.org/maven2")),
// null,
// lookup);
Profile profile = session.getService(SettingsBuilder.class)
.convert(org.apache.maven.api.settings.Profile.newBuilder()
.repositories(settings.getRepositories())
.pluginRepositories(settings.getPluginRepositories())
.build());
RepositoryFactory repositoryFactory = session.getService(RepositoryFactory.class);
List<RemoteRepository> repositories = profile.getRepositories().stream()
.map(repositoryFactory::createRemote)
.toList();
InternalSession s = (InternalSession) session.withRemoteRepositories(repositories);
InternalSession.associate(rsession, s);
return s;
// List<RemoteRepository> repositories = repositoryFactory.createRemote();
// session.getService(SettingsBuilder.class).convert()
// settings.getDelegate().getRepositories().stream()
// .map(r -> SettingsUtilsV4.)
// defaultSession.getService(RepositoryFactory.class).createRemote()
// return defaultSession;
}
}
static class UnsupportedInStandaloneModeException extends MavenException {}
record DumbPackaging(String id, Type type, Map<String, PluginContainer> plugins) implements Packaging {}
}

View File

@ -27,7 +27,7 @@ import org.apache.maven.api.cli.InvokerException;
import org.apache.maven.api.cli.mvn.MavenOptions;
import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvoker;
import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvokerRequest;
import org.apache.maven.utils.Os;
import org.apache.maven.internal.impl.model.profile.Os;
import static java.util.Objects.requireNonNull;

View File

@ -32,6 +32,7 @@ import org.apache.maven.api.services.xml.XmlReaderRequest;
import org.apache.maven.building.Source;
import org.apache.maven.building.StringSource;
import org.apache.maven.internal.impl.DefaultToolchainsXmlFactory;
import org.apache.maven.internal.impl.model.DefaultInterpolator;
import org.apache.maven.toolchain.model.PersistedToolchains;
import org.apache.maven.toolchain.model.ToolchainModel;
import org.codehaus.plexus.interpolation.os.OperatingSystemUtils;
@ -72,7 +73,9 @@ class DefaultToolchainsBuilderTest {
OperatingSystemUtils.setEnvVarSource(new TestEnvVarSource(envVarMap));
toolchainBuilder = new DefaultToolchainsBuilder(
new org.apache.maven.internal.impl.DefaultToolchainsBuilder(), toolchainsXmlFactory);
new org.apache.maven.internal.impl.DefaultToolchainsBuilder(
new DefaultInterpolator(), toolchainsXmlFactory),
toolchainsXmlFactory);
}
@Test