Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider properties defined in .mvn/maven.config #552

Merged
merged 1 commit into from
Feb 16, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
Expand All @@ -23,6 +27,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
Expand All @@ -32,11 +37,14 @@
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.ParseException;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.MavenArtifactRepository;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.artifact.repository.metadata.Plugin;
import org.apache.maven.cli.CLIManager;
import org.apache.maven.execution.MavenExecutionRequest;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.model.Build;
Expand Down Expand Up @@ -69,6 +77,9 @@

public class MavenProjectCache {

private static final String MVN_FOLDER = ".mvn";
private static final String MAVEN_CONFIG = "maven.config";

private static final Logger LOGGER = Logger.getLogger(MavenProjectCache.class.getName());
private MavenLemminxExtension plugin;
private final Map<String, LoadedMavenProjectProvider> projectCache;
Expand Down Expand Up @@ -162,8 +173,9 @@ public LoadedMavenProject build(FileModelSource source, CancelChecker cancelChec
MavenProject project = null;
File file = source.getFile();
try {
ProjectBuildingResult buildResult = projectBuilder.build(
source, newProjectBuildingRequest());
ProjectBuildingRequest request = newProjectBuildingRequest(file);

ProjectBuildingResult buildResult = projectBuilder.build(source, request);
cancelChecker.checkCanceled();
project = buildResult.getProject();
problems.addAll(buildResult.getProblems());
Expand Down Expand Up @@ -337,7 +349,7 @@ public Optional<MavenProject> getSnapshotProject(File file) {
}

try {
return Optional.of(projectBuilder.build(file, newProjectBuildingRequest()).getProject());
return Optional.of(projectBuilder.build(file, newProjectBuildingRequest(file)).getProject());
} catch (ProjectBuildingException e) {
List<ProjectBuildingResult> result = e.getResults();
if (result != null && result.size() == 1 && result.get(0).getProject() != null) {
Expand All @@ -364,7 +376,7 @@ public Optional<MavenProject> getSnapshotProject(File file) {
*/
public MavenProject getSnapshotProject(DOMDocument document, String profileId, boolean resolve) {
// it would be nice to directly rebuild from Model instead of re-parsing text
ProjectBuildingRequest request = newProjectBuildingRequest(resolve);
ProjectBuildingRequest request = newProjectBuildingRequest(resolve, getFileForDocument(document));
if (profileId != null) {
request.setActiveProfileIds(List.of(profileId));
}
Expand All @@ -386,24 +398,28 @@ public MavenProject getSnapshotProject(DOMDocument document, String profileId, b
}

/**
* Creates a new default Maven Project Building request (with dependency
* resolve enabled)
* Creates a new default Maven Project Building request (with dependency resolve
* enabled)
*
* @param projectFile the project file or base directory of the building request
*
* @return A ProjectBuildingRequest object
*/
public ProjectBuildingRequest newProjectBuildingRequest() {
return newProjectBuildingRequest(true);
public ProjectBuildingRequest newProjectBuildingRequest(File projectFile) {
return newProjectBuildingRequest(true, projectFile);
}

/**
* Creates a new default Maven Project Building request
*
* @param resolveDependencies a boolean indicating if the dependency
* resolve is to be enabled on the request.
* @param resolveDependencies a boolean indicating if the dependency resolve is
* to be enabled on the request.
* @param projectFile the project file or base directory of the building
* request
*
* @return A ProjectBuildingRequest object
*/
public ProjectBuildingRequest newProjectBuildingRequest(boolean resolveDependencies) {
public ProjectBuildingRequest newProjectBuildingRequest(boolean resolveDependencies, File projectFile) {
ProjectBuildingRequest request = new DefaultProjectBuildingRequest();
MavenExecutionRequest mavenRequest = mavenSession.getRequest();
request.setSystemProperties(mavenRequest.getSystemProperties());
Expand All @@ -415,7 +431,38 @@ public ProjectBuildingRequest newProjectBuildingRequest(boolean resolveDependenc
request.setResolveDependencies(resolveDependencies);

// See: https://issues.apache.org/jira/browse/MRESOLVER-374
request.getUserProperties().setProperty("aether.syncContext.named.factory", "noop");
Properties userProperties = request.getUserProperties();
userProperties.setProperty("aether.syncContext.named.factory", "noop");
File multiModuleProjectDirectory = computeMultiModuleProjectDirectory(projectFile);
if (multiModuleProjectDirectory != null) {
File mavenConfig = new File(multiModuleProjectDirectory, MAVEN_CONFIG);
if (mavenConfig.isFile()) {
try {
CLIManager manager = new CLIManager();
String[] args;
try (Stream<String> lines = Files.lines(mavenConfig.toPath(), Charset.defaultCharset())) {
args = lines.filter(arg -> !arg.isEmpty()).toArray(String[]::new);
}
CommandLine commandline = manager.parse(args);
if (commandline.hasOption(CLIManager.SET_USER_PROPERTY)) {
String[] configUserProperties = commandline.getOptionValues(CLIManager.SET_USER_PROPERTY);
if (configUserProperties != null) {
for (String property : configUserProperties) {
int index = property.indexOf('=');
if (index <= 0) {
userProperties.setProperty(property.trim(), "true");
} else {
userProperties.setProperty(property.substring(0, index).trim(),
property.substring(index + 1).trim());
}
}
}
}
} catch (IOException | ParseException e) {
// TODO how to best propagate this?!?
}
}
}
return request;
}
}
Expand Down Expand Up @@ -573,4 +620,38 @@ public CompletableFuture<LoadedMavenProject> getLoadedMavenProject(String uriStr
}
return provider.getLoadedMavenProject();
}

/**
* @param file a base file or directory, may be <code>null</code>
* @return the value for `maven.multiModuleProjectDirectory` as defined in Maven
* launcher
*/
public static File computeMultiModuleProjectDirectory(File file) {
if (file == null) {
return null;
}
final File basedir = file.isDirectory() ? file : file.getParentFile();
for (File root = basedir; root != null; root = root.getParentFile()) {
if (new File(root, MVN_FOLDER).isDirectory()) {
return root;
}
}
return null;
}

private static File getFileForDocument(DOMDocument document) {
String documentURI = document.getDocumentURI();
if (documentURI == null) {
return null;
}
if (documentURI.toLowerCase().startsWith("file:")) {
try {
return new File(new URI(documentURI));
} catch (URISyntaxException e) {
return null;
}
}
return new File(documentURI);
}

}
Loading