This is an automated email from the ASF dual-hosted git repository. cstamas pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/maven-mvnd.git
The following commit(s) were added to refs/heads/master by this push: new 7b309de9 Support core extension more configuration (#1216) 7b309de9 is described below commit 7b309de9ab8e8ed4e65cb43f59c9a3e22edc69e0 Author: Jermaine Hua <crazy...@gmail.com> AuthorDate: Tue Dec 17 20:50:43 2024 +0800 Support core extension more configuration (#1216) Fixes #1163 Signed-off-by: crazyhzm <crazy...@apache.org> --- README.adoc | 2 +- .../mvndaemon/mvnd/client/DaemonParameters.java | 72 ++++++++-------------- .../org/mvndaemon/mvnd/common/Environment.java | 7 ++- .../org/apache/maven/cli/DaemonMavenParser.java | 58 +++++++++++++---- .../java/org/mvndaemon/mvnd/cli/EnvHelper.java | 2 +- dist/src/main/distro/conf/mvnd.properties | 2 +- .../org/mvndaemon/mvnd/it/ExtensionsNativeIT.java | 17 ++++- 7 files changed, 93 insertions(+), 67 deletions(-) diff --git a/README.adoc b/README.adoc index a4e26390..1b7a0123 100644 --- a/README.adoc +++ b/README.adoc @@ -185,7 +185,7 @@ A few special properties do not follow the above mechanism: * `mvnd.daemonStorage`: this property defines the location where mvnd stores its files (registry and daemon logs). This property can only be defined as a system property on the command line * `mvnd.id`: this property is used internally to identify the daemon being created * `mvnd.extClasspath`: internal option to specify the maven extension classpath -* `mvnd.coreExtensions`: internal option to specify the list of maven extension to register +* `mvnd.coreExtensionFilePath`: internal option to specify the maven extension configuration file path For a full list of available properties please see https://github.com/apache/maven-mvnd/blob/master/dist/src/main/distro/conf/mvnd.properties[/dist/src/main/distro/conf/mvnd.properties]. diff --git a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java index c26f6214..f63fb241 100644 --- a/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java +++ b/client/src/main/java/org/mvndaemon/mvnd/client/DaemonParameters.java @@ -18,8 +18,6 @@ */ package org.mvndaemon.mvnd.client; -import javax.xml.stream.XMLStreamException; - import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -30,13 +28,11 @@ import java.time.Duration; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Properties; -import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Consumer; import java.util.function.Function; @@ -45,8 +41,6 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.maven.api.cli.extensions.CoreExtension; -import org.apache.maven.cling.internal.extension.io.CoreExtensionsStaxReader; import org.mvndaemon.mvnd.common.Environment; import org.mvndaemon.mvnd.common.InterpolationHelper; import org.mvndaemon.mvnd.common.Os; @@ -291,7 +285,7 @@ public class DaemonParameters { /** * @return the number of threads (same syntax as Maven's {@code -T}/{@code --threads} option) to pass to the daemon - * unless the user passes his own `-T` or `--threads`. + * unless the user passes his own `-T` or `--threads`. */ public String threads() { return property(Environment.MVND_THREADS) @@ -321,7 +315,7 @@ public class DaemonParameters { /** * @return absolute normalized path to local Maven repository or {@code null} if the server is supposed to use the - * default + * default */ public Path mavenRepoLocal() { return property(Environment.MAVEN_REPO_LOCAL).asPath(); @@ -346,7 +340,6 @@ public class DaemonParameters { } /** - * * @return if mvnd should behave as maven */ public boolean serial() { @@ -354,8 +347,8 @@ public class DaemonParameters { } /** - * @param newUserDir where to change the current directory to - * @return a new {@link DaemonParameters} with {@code userDir} set to the given {@code newUserDir} + * @param newUserDir where to change the current directory to + * @return a new {@link DaemonParameters} with {@code userDir} set to the given {@code newUserDir} */ public DaemonParameters cd(Path newUserDir) { return derive(b -> b.put(Environment.USER_DIR, newUserDir)); @@ -457,14 +450,20 @@ public class DaemonParameters { if (env == Environment.MVND_EXT_CLASSPATH) { List<String> cp = parseExtClasspath(userHome()); return String.join(",", cp); - } else if (env == Environment.MVND_CORE_EXTENSIONS) { + } else if (env == Environment.MVND_CORE_EXTENSIONS_FILE_PATH) { try { - List<String> extensions = readCoreExtensionsDescriptor(multiModuleProjectDirectory()).stream() - .map(e -> e.getGroupId() + ":" + e.getArtifactId() + ":" + e.getVersion()) - .collect(Collectors.toList()); - return String.join(";", extensions); - } catch (IOException | XMLStreamException e) { - throw new RuntimeException("Unable to parse core extensions", e); + return resolveCoreExtensionFilePath(multiModuleProjectDirectory()); + } catch (IOException e) { + throw new RuntimeException("Unable to resolve core extension configuration file path", e); + } + } else if (env == Environment.MVND_CORE_EXTENSIONS_EXCLUDE) { + String exclusionsString = systemProperty(Environment.MVND_CORE_EXTENSIONS_EXCLUDE) + .orDefault() + .asString(); + if (exclusionsString != null) { + return exclusionsString; + } else { + return ""; } } else { return env.getDefault(); @@ -483,40 +482,15 @@ public class DaemonParameters { return jars; } - private static List<CoreExtension> readCoreExtensionsDescriptor(Path multiModuleProjectDirectory) - throws IOException, XMLStreamException { + private static String resolveCoreExtensionFilePath(Path multiModuleProjectDirectory) throws IOException { if (multiModuleProjectDirectory == null) { - return Collections.emptyList(); + return ""; } Path extensionsFile = multiModuleProjectDirectory.resolve(EXTENSIONS_FILENAME); if (!Files.exists(extensionsFile)) { - return Collections.emptyList(); - } - CoreExtensionsStaxReader parser = new CoreExtensionsStaxReader(); - List<CoreExtension> extensions; - try (InputStream is = Files.newInputStream(extensionsFile)) { - extensions = parser.read(is).getExtensions(); - } - return filterCoreExtensions(extensions); - } - - private static List<CoreExtension> filterCoreExtensions(List<CoreExtension> coreExtensions) { - Set<String> exclusions = new HashSet<>(); - String exclusionsString = systemProperty(Environment.MVND_CORE_EXTENSIONS_EXCLUDE) - .orDefault() - .asString(); - if (exclusionsString != null) { - exclusions.addAll(Arrays.stream(exclusionsString.split(",")) - .filter(e -> e != null && !e.trim().isEmpty()) - .collect(Collectors.toList())); - } - if (!exclusions.isEmpty()) { - return coreExtensions.stream() - .filter(e -> !exclusions.contains(e.getGroupId() + ":" + e.getArtifactId())) - .collect(Collectors.toList()); - } else { - return coreExtensions; + return ""; } + return extensionsFile.toAbsolutePath().toString(); } private static Properties loadProperties(Path path) { @@ -571,7 +545,9 @@ public class DaemonParameters { this.valueSupplier = valueSupplier; } - /** Mostly for debugging */ + /** + * Mostly for debugging + */ @Override public String toString() { return descriptionFunction.apply(new StringBuilder()).toString(); diff --git a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java index d70d637d..648914c4 100644 --- a/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java +++ b/common/src/main/java/org/mvndaemon/mvnd/common/Environment.java @@ -212,9 +212,10 @@ public enum Environment { */ MVND_EXT_CLASSPATH("mvnd.extClasspath", null, null, OptionType.STRING, Flags.DISCRIMINATING | Flags.INTERNAL), /** - * Internal option to specify the list of maven extension to register. + * Internal option to specify the maven extension configuration file path to register. */ - MVND_CORE_EXTENSIONS("mvnd.coreExtensions", null, null, OptionType.STRING, Flags.DISCRIMINATING | Flags.INTERNAL), + MVND_CORE_EXTENSIONS_FILE_PATH( + "mvnd.coreExtensionFilePath", null, null, OptionType.STRING, Flags.DISCRIMINATING | Flags.INTERNAL), /** * Internal option to specify comma separated list of maven extension G:As to exclude (to not load them from * .mvn/extensions.xml). This option makes possible for example that a project that with vanilla Maven would @@ -226,7 +227,7 @@ public enum Environment { null, "io.takari.maven:takari-smart-builder", OptionType.STRING, - Flags.OPTIONAL), + Flags.OPTIONAL | Flags.DISCRIMINATING), /** * The <code>-Xms</code> value to pass to the daemon. * This option takes precedence over options specified in <code>-Dmvnd.jvmArgs</code>. diff --git a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java index de0a352a..379bb06a 100644 --- a/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java +++ b/daemon/src/main/java/org/apache/maven/cli/DaemonMavenParser.java @@ -18,15 +18,25 @@ */ package org.apache.maven.cli; +import javax.xml.stream.XMLStreamException; + +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Stream; +import java.util.Set; +import java.util.stream.Collectors; import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.ParserException; import org.apache.maven.api.cli.extensions.CoreExtension; import org.apache.maven.api.cli.mvn.MavenOptions; +import org.apache.maven.cling.internal.extension.io.CoreExtensionsStaxReader; import org.apache.maven.cling.invoker.mvn.MavenParser; import org.mvndaemon.mvnd.common.Environment; @@ -53,16 +63,40 @@ public class DaemonMavenParser extends MavenParser { @Override protected List<CoreExtension> readCoreExtensionsDescriptor(LocalContext context) { - return Stream.of(Environment.MVND_CORE_EXTENSIONS.asString().split(";")) - .filter(s -> s != null && !s.isEmpty()) - .map(s -> { - String[] parts = s.split(":"); - return CoreExtension.newBuilder() - .groupId(parts[0]) - .artifactId(parts[1]) - .version(parts[2]) - .build(); - }) - .toList(); + String coreExtensionsFilePath = Environment.MVND_CORE_EXTENSIONS_FILE_PATH.asString(); + if (!coreExtensionsFilePath.isEmpty()) { + try { + return readCoreExtensionsDescriptor(Path.of(coreExtensionsFilePath)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else { + return new ArrayList<>(); + } + } + + private List<CoreExtension> readCoreExtensionsDescriptor(Path extensionsFile) + throws IOException, XMLStreamException { + + CoreExtensionsStaxReader parser = new CoreExtensionsStaxReader(); + List<CoreExtension> extensions; + try (InputStream is = Files.newInputStream(extensionsFile)) { + extensions = parser.read(is).getExtensions(); + } + return filterCoreExtensions(extensions); + } + + private static List<CoreExtension> filterCoreExtensions(List<CoreExtension> coreExtensions) { + String exclusionsString = Environment.MVND_CORE_EXTENSIONS_EXCLUDE.asString(); + Set<String> exclusions = Arrays.stream(exclusionsString.split(",")) + .filter(e -> e != null && !e.trim().isEmpty()) + .collect(Collectors.toSet()); + if (!exclusions.isEmpty()) { + return coreExtensions.stream() + .filter(e -> !exclusions.contains(e.getGroupId() + ":" + e.getArtifactId())) + .collect(Collectors.toList()); + } else { + return coreExtensions; + } } } diff --git a/daemon/src/main/java/org/mvndaemon/mvnd/cli/EnvHelper.java b/daemon/src/main/java/org/mvndaemon/mvnd/cli/EnvHelper.java index cfb83d81..c443abed 100644 --- a/daemon/src/main/java/org/mvndaemon/mvnd/cli/EnvHelper.java +++ b/daemon/src/main/java/org/mvndaemon/mvnd/cli/EnvHelper.java @@ -94,7 +94,7 @@ public class EnvHelper { } } - static String toCygwin(String path) { + public static String toCygwin(String path) { if (path.length() >= 3 && ":\\".equals(path.substring(1, 3))) { try { String p = path.endsWith("\\") ? path.substring(0, path.length() - 1) : path; diff --git a/dist/src/main/distro/conf/mvnd.properties b/dist/src/main/distro/conf/mvnd.properties index d528002e..8909cfb4 100644 --- a/dist/src/main/distro/conf/mvnd.properties +++ b/dist/src/main/distro/conf/mvnd.properties @@ -35,7 +35,7 @@ # a system property on the command line # - mvnd.id: this property is used internally to identify the daemon being created # - mvnd.extClasspath: internal option to specify the maven extension classpath -# - mvnd.coreExtensions: internal option to specify the list of maven extension to register +# - mvnd.coreExtensionFilePath: internal option to specify the maven extension configuration file path to register # # MVND_NO_BUFFERING diff --git a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/ExtensionsNativeIT.java b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/ExtensionsNativeIT.java index 66ffee87..d4d743aa 100644 --- a/integration-tests/src/test/java/org/mvndaemon/mvnd/it/ExtensionsNativeIT.java +++ b/integration-tests/src/test/java/org/mvndaemon/mvnd/it/ExtensionsNativeIT.java @@ -54,7 +54,6 @@ class ExtensionsNativeIT { client.execute(o, "-v").assertSuccess(); assertDaemonRegistrySize(1); DaemonInfo daemon = registry.getAll().iterator().next(); - assertTrue(daemon.getOptions().contains("mvnd.coreExtensions=fr.jcgay.maven:maven-profiler:3.0")); registry.awaitIdle(daemon.getId()); @@ -67,4 +66,20 @@ class ExtensionsNativeIT { .as("Daemon registry size should be " + size) .isEqualTo(size); } + + @Test + void coreExtensionFilePathOption() throws InterruptedException { + registry.killAll(); + assertDaemonRegistrySize(0); + + final TestClientOutput o = new TestClientOutput(); + client.execute(o, "-v").assertSuccess(); + assertDaemonRegistrySize(1); + DaemonInfo daemon = registry.getAll().iterator().next(); + + daemon.getOptions().stream() + .filter(s -> s.startsWith("mvnd.coreExtensionFilePath=")) + .findFirst() + .ifPresent(s -> assertTrue(s.endsWith(".mvn\\extensions.xml") || s.endsWith(".mvn/extensions.xml"))); + } }