diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/local/LocalMavenParser.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/local/LocalMavenParser.java deleted file mode 100644 index 42d631450c73..000000000000 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/local/LocalMavenParser.java +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.api.cli.mvn.local; - -import org.apache.maven.api.annotations.Experimental; -import org.apache.maven.api.cli.mvn.MavenInvokerRequest; -import org.apache.maven.api.cli.mvn.MavenOptions; -import org.apache.maven.api.cli.mvn.MavenParser; - -/** - * Local parser. - * - * @since 4.0.0 - */ -@Experimental -public interface LocalMavenParser extends MavenParser> {} diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenInvoker.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenInvoker.java index 903c7ce9922b..ec9f9e0161a6 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenInvoker.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenInvoker.java @@ -21,6 +21,8 @@ import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.cli.InvokerException; import org.apache.maven.api.cli.mvn.MavenInvoker; +import org.apache.maven.api.cli.mvn.MavenInvokerRequest; +import org.apache.maven.api.cli.mvn.MavenOptions; /** * Resident invoker. Instance is shut down when this instance is closed. @@ -28,7 +30,7 @@ * @since 4.0.0 */ @Experimental -public interface ResidentMavenInvoker extends MavenInvoker { +public interface ResidentMavenInvoker extends MavenInvoker> { /** * Closes cleanly the daemon. */ diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenInvokerRequest.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenInvokerRequest.java deleted file mode 100644 index 987dc57b5a3d..000000000000 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenInvokerRequest.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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.api.cli.mvn.resident; - -import java.util.List; -import java.util.Optional; - -import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.cli.mvn.MavenInvokerRequest; - -public interface ResidentMavenInvokerRequest extends MavenInvokerRequest { - /** - * Returns the list of extra JVM arguments to be passed to the forked Maven process. - * These arguments allow for customization of the JVM environment in which Maven will run. - * - * @return an Optional containing the list of extra JVM arguments, or empty if not specified - */ - @Nonnull - Optional> jvmArguments(); -} diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenOptions.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenOptions.java deleted file mode 100644 index 8561cddeeac9..000000000000 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenOptions.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * 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.api.cli.mvn.resident; - -import java.util.Collection; -import java.util.Map; -import java.util.Optional; - -import org.apache.maven.api.annotations.Experimental; -import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.cli.mvn.MavenOptions; - -/** - * Resident options. - */ -@Experimental -public interface ResidentMavenOptions extends MavenOptions { - /** - * Indicates whether raw streams should be used with daemon. - * - * @return an {@link Optional} containing true if raw streams are enabled, false if disabled, or empty if not specified - */ - @Nonnull - Optional rawStreams(); - - /** - * Returns a new instance of {@link MavenOptions} with values interpolated using the given properties. - * - * @param properties a collection of property maps to use for interpolation - * @return a new MavenOptions instance with interpolated values - */ - @Nonnull - ResidentMavenOptions interpolate(@Nonnull Collection> properties); -} diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenParser.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenParser.java deleted file mode 100644 index 8d383b050c38..000000000000 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/resident/ResidentMavenParser.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.api.cli.mvn.resident; - -import org.apache.maven.api.annotations.Experimental; -import org.apache.maven.api.cli.mvn.MavenParser; - -/** - * Resident parser. - * - * @since 4.0.0 - */ -@Experimental -public interface ResidentMavenParser extends MavenParser {} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java b/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java index ac9130bd31b9..b8b204d5f470 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java @@ -26,8 +26,8 @@ import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.cling.invoker.ProtoLogger; import org.apache.maven.cling.invoker.ProtoLookup; +import org.apache.maven.cling.invoker.mvn.DefaultMavenParser; import org.apache.maven.cling.invoker.mvn.local.DefaultLocalMavenInvoker; -import org.apache.maven.cling.invoker.mvn.local.DefaultLocalMavenParser; import org.apache.maven.jline.JLineMessageBuilderFactory; import org.codehaus.plexus.classworlds.ClassWorld; @@ -67,6 +67,6 @@ protected Invoker> createInvoker() { @Override protected MavenInvokerRequest parseArguments(String[] args) throws ParserException, IOException { - return new DefaultLocalMavenParser().mvn(args, new ProtoLogger(), new JLineMessageBuilderFactory()); + return new DefaultMavenParser().mvn(args, new ProtoLogger(), new JLineMessageBuilderFactory()); } } diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java index 9c426776c3e6..b7d5620f9c92 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java @@ -121,6 +121,7 @@ protected LookupInvokerContext(LookupInvoker invoker, R invokerRequest) public Logger logger; public ILoggerFactory loggerFactory; + public Slf4jConfiguration slf4jConfiguration; public Slf4jConfiguration.Level loggerLevel; public ContainerCapsule containerCapsule; public Lookup lookup; @@ -156,6 +157,7 @@ public int invoke(R invokerRequest) throws InvokerException { validate(context); prepare(context); logging(context); + activateLogging(context); if (invokerRequest.options().help().isPresent()) { invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), context.stdOut); @@ -231,7 +233,7 @@ protected void logging(C context) throws Exception { } context.loggerFactory = LoggerFactory.getILoggerFactory(); - Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(context.loggerFactory); + context.slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(context.loggerFactory); context.loggerLevel = Slf4jConfiguration.Level.INFO; if (mavenOptions.verbose().orElse(false)) { @@ -239,7 +241,7 @@ protected void logging(C context) throws Exception { } else if (mavenOptions.quiet().orElse(false)) { context.loggerLevel = Slf4jConfiguration.Level.ERROR; } - slf4jConfiguration.setRootLoggerLevel(context.loggerLevel); + context.slf4jConfiguration.setRootLoggerLevel(context.loggerLevel); // else fall back to default log level specified in conf // see https://issues.apache.org/jira/browse/MNG-2570 @@ -255,8 +257,13 @@ protected void logging(C context) throws Exception { throw new InvokerException("Cannot set up log " + e.getMessage(), e); } } + } + + protected void activateLogging(C context) throws Exception { + R invokerRequest = context.invokerRequest; + Options mavenOptions = invokerRequest.options(); - slf4jConfiguration.activate(); + context.slf4jConfiguration.activate(); org.slf4j.Logger l = context.loggerFactory.getLogger(this.getClass().getName()); context.logger = (level, message, error) -> l.atLevel(org.slf4j.event.Level.valueOf(level.name())) .setCause(error) diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java index 848bdd10e9b0..7ae89a59bdcb 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/PlexusContainerCapsuleFactory.java @@ -28,6 +28,7 @@ import java.util.function.Function; import com.google.inject.AbstractModule; +import com.google.inject.Module; import org.apache.maven.api.Constants; import org.apache.maven.api.cli.InvokerException; import org.apache.maven.api.cli.InvokerRequest; @@ -103,16 +104,9 @@ protected PlexusContainer container(C context) throws Exception { exportedArtifacts.addAll(extension.getExportedArtifacts()); exportedPackages.addAll(extension.getExportedPackages()); } - final CoreExports exports = new CoreExports(containerRealm, exportedArtifacts, exportedPackages); + CoreExports exports = new CoreExports(containerRealm, exportedArtifacts, exportedPackages); Thread.currentThread().setContextClassLoader(containerRealm); - DefaultPlexusContainer container = new DefaultPlexusContainer(cc, new AbstractModule() { - @Override - protected void configure() { - bind(ILoggerFactory.class).toInstance(context.loggerFactory); - bind(CoreExports.class).toInstance(exports); - bind(MessageBuilderFactory.class).toInstance(context.invokerRequest.messageBuilderFactory()); - } - }); + DefaultPlexusContainer container = new DefaultPlexusContainer(cc, getCustomModule(context, exports)); // NOTE: To avoid inconsistencies, we'll use the TCCL exclusively for lookups container.setLookupRealm(null); @@ -157,6 +151,22 @@ protected void configure() { return container; } + /** + * Note: overriding this method should be avoided. Preferred way to replace Maven components is the "normal" way + * where the components are on index (are annotated with JSR330 annotations and Sisu index is created) and, they + * have priorities set. + */ + protected Module getCustomModule(C context, CoreExports exports) { + return new AbstractModule() { + @Override + protected void configure() { + bind(ILoggerFactory.class).toInstance(context.loggerFactory); + bind(CoreExports.class).toInstance(exports); + bind(MessageBuilderFactory.class).toInstance(context.invokerRequest.messageBuilderFactory()); + } + }; + } + protected void customizeContainerConfiguration(C context, ContainerConfiguration configuration) throws Exception {} protected void customizeContainer(C context, PlexusContainer container) throws Exception {} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/BaseMavenParser.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/BaseMavenParser.java new file mode 100644 index 000000000000..f7fd7d368b29 --- /dev/null +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/BaseMavenParser.java @@ -0,0 +1,87 @@ +/* + * 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.io.IOException; +import java.nio.charset.Charset; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Stream; + +import org.apache.maven.api.cli.Options; +import org.apache.maven.api.cli.ParserException; +import org.apache.maven.api.cli.ParserRequest; +import org.apache.maven.api.cli.extensions.CoreExtension; +import org.apache.maven.api.cli.mvn.MavenInvokerRequest; +import org.apache.maven.api.cli.mvn.MavenOptions; +import org.apache.maven.api.cli.mvn.MavenParser; +import org.apache.maven.cling.invoker.BaseParser; + +public abstract class BaseMavenParser> extends BaseParser + implements MavenParser { + @SuppressWarnings("ParameterNumber") + @Override + protected abstract R getInvokerRequest( + ParserRequest parserRequest, + Path cwd, + Path installationDirectory, + Path userHomeDirectory, + Map userProperties, + Map systemProperties, + Path topDirectory, + Path rootDirectory, + ArrayList extensions, + Options options); + + @Override + protected List parseCliOptions(Path rootDirectory, List args) throws ParserException, IOException { + ArrayList result = new ArrayList<>(); + // CLI args + result.add(parseMavenCliOptions(args)); + // maven.config; if exists + Path mavenConfig = rootDirectory.resolve(".mvn/maven.config"); + if (Files.isRegularFile(mavenConfig)) { + result.add(parseMavenConfigOptions(mavenConfig)); + } + return result; + } + + protected O parseMavenCliOptions(List args) throws ParserException { + return parseArgs(Options.SOURCE_CLI, args); + } + + protected O parseMavenConfigOptions(Path configFile) throws ParserException, IOException { + try (Stream lines = Files.lines(configFile, Charset.defaultCharset())) { + List args = + lines.filter(arg -> !arg.isEmpty() && !arg.startsWith("#")).toList(); + O options = parseArgs("maven.config", args); + if (options.goals().isPresent()) { + // This file can only contain options, not args (goals or phases) + throw new ParserException("Unrecognized maven.config file entries: " + + options.goals().get()); + } + return options; + } + } + + protected abstract O parseArgs(String source, List args) throws ParserException; +} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java index d8a6b982f4a6..271304b227ba 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenInvoker.java @@ -76,7 +76,7 @@ public abstract class DefaultMavenInvoker< extends LookupInvoker implements MavenInvoker { @SuppressWarnings("VisibilityModifier") - protected static class MavenContext< + public static class MavenContext< O extends MavenOptions, R extends MavenInvokerRequest, C extends DefaultMavenInvoker.MavenContext> diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenParser.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenParser.java index 49f3f5674775..9f8574a4344a 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenParser.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/DefaultMavenParser.java @@ -18,15 +18,12 @@ */ package org.apache.maven.cling.invoker.mvn; -import java.io.IOException; -import java.nio.charset.Charset; -import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.Map; -import java.util.stream.Stream; +import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.ParserException; import org.apache.maven.api.cli.ParserRequest; @@ -34,13 +31,12 @@ import org.apache.maven.api.cli.mvn.MavenInvokerRequest; import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.api.cli.mvn.MavenParser; -import org.apache.maven.cling.invoker.BaseParser; -public abstract class DefaultMavenParser> - extends BaseParser implements MavenParser { +public class DefaultMavenParser extends BaseMavenParser> + implements MavenParser> { @SuppressWarnings("ParameterNumber") @Override - protected abstract R getInvokerRequest( + protected DefaultMavenInvokerRequest getInvokerRequest( ParserRequest parserRequest, Path cwd, Path installationDirectory, @@ -50,38 +46,34 @@ protected abstract R getInvokerRequest( Path topDirectory, Path rootDirectory, ArrayList extensions, - Options options); + Options options) { + return new DefaultMavenInvokerRequest<>( + parserRequest, + cwd, + installationDirectory, + userHomeDirectory, + userProperties, + systemProperties, + topDirectory, + rootDirectory, + parserRequest.in(), + parserRequest.out(), + parserRequest.err(), + extensions, + (MavenOptions) options); + } @Override - protected List parseCliOptions(Path rootDirectory, List args) throws ParserException, IOException { - ArrayList result = new ArrayList<>(); - // CLI args - result.add(parseMavenCliOptions(args)); - // maven.config; if exists - Path mavenConfig = rootDirectory.resolve(".mvn/maven.config"); - if (Files.isRegularFile(mavenConfig)) { - result.add(parseMavenConfigOptions(mavenConfig)); + protected MavenOptions parseArgs(String source, List args) throws ParserException { + try { + return CommonsCliMavenOptions.parse(source, args.toArray(new String[0])); + } catch (ParseException e) { + throw new ParserException("Failed to parse source " + source, e.getCause()); } - return result; - } - - protected O parseMavenCliOptions(List args) throws ParserException { - return parseArgs(Options.SOURCE_CLI, args); } - protected O parseMavenConfigOptions(Path configFile) throws ParserException, IOException { - try (Stream lines = Files.lines(configFile, Charset.defaultCharset())) { - List args = - lines.filter(arg -> !arg.isEmpty() && !arg.startsWith("#")).toList(); - O options = parseArgs("maven.config", args); - if (options.goals().isPresent()) { - // This file can only contain options, not args (goals or phases) - throw new ParserException("Unrecognized maven.config file entries: " - + options.goals().get()); - } - return options; - } + @Override + protected MavenOptions assembleOptions(List parsedOptions) { + return LayeredMavenOptions.layerMavenOptions(parsedOptions); } - - protected abstract O parseArgs(String source, List args) throws ParserException; } diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenParser.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenParser.java index 194e6841b4e8..8e240e709726 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenParser.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/forked/DefaultForkedMavenParser.java @@ -31,11 +31,11 @@ import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvokerRequest; import org.apache.maven.api.cli.mvn.forked.ForkedMavenParser; +import org.apache.maven.cling.invoker.mvn.BaseMavenParser; import org.apache.maven.cling.invoker.mvn.CommonsCliMavenOptions; -import org.apache.maven.cling.invoker.mvn.DefaultMavenParser; import org.apache.maven.cling.invoker.mvn.LayeredMavenOptions; -public class DefaultForkedMavenParser extends DefaultMavenParser +public class DefaultForkedMavenParser extends BaseMavenParser implements ForkedMavenParser { @SuppressWarnings("ParameterNumber") @@ -76,6 +76,7 @@ protected List getJvmArguments(Path rootDirectory) { return null; } + // TODO: same is in DefaultMavenParser!!! (duplication) @Override protected MavenOptions parseArgs(String source, List args) throws ParserException { try { @@ -85,6 +86,7 @@ protected MavenOptions parseArgs(String source, List args) throws Parser } } + // TODO: same is in DefaultMavenParser!!! (duplication) @Override protected MavenOptions assembleOptions(List parsedOptions) { return LayeredMavenOptions.layerMavenOptions(parsedOptions); diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvoker.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvoker.java index 7a7a1554aa51..529af514cf3a 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvoker.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvoker.java @@ -29,7 +29,7 @@ public class DefaultLocalMavenInvoker MavenOptions, MavenInvokerRequest, DefaultLocalMavenInvoker.LocalContext> implements LocalMavenInvoker { - protected static class LocalContext + public static class LocalContext extends DefaultMavenInvoker.MavenContext< MavenOptions, MavenInvokerRequest, DefaultLocalMavenInvoker.LocalContext> { protected LocalContext(DefaultLocalMavenInvoker invoker, MavenInvokerRequest invokerRequest) { diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenParser.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenParser.java deleted file mode 100644 index d3fde3193c7d..000000000000 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenParser.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * 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.local; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; - -import org.apache.commons.cli.ParseException; -import org.apache.maven.api.cli.Options; -import org.apache.maven.api.cli.ParserException; -import org.apache.maven.api.cli.ParserRequest; -import org.apache.maven.api.cli.extensions.CoreExtension; -import org.apache.maven.api.cli.mvn.MavenInvokerRequest; -import org.apache.maven.api.cli.mvn.MavenOptions; -import org.apache.maven.api.cli.mvn.local.LocalMavenParser; -import org.apache.maven.cling.invoker.mvn.CommonsCliMavenOptions; -import org.apache.maven.cling.invoker.mvn.DefaultMavenInvokerRequest; -import org.apache.maven.cling.invoker.mvn.DefaultMavenParser; -import org.apache.maven.cling.invoker.mvn.LayeredMavenOptions; - -public class DefaultLocalMavenParser extends DefaultMavenParser> - implements LocalMavenParser { - @SuppressWarnings("ParameterNumber") - @Override - protected DefaultMavenInvokerRequest getInvokerRequest( - ParserRequest parserRequest, - Path cwd, - Path installationDirectory, - Path userHomeDirectory, - Map userProperties, - Map systemProperties, - Path topDirectory, - Path rootDirectory, - ArrayList extensions, - Options options) { - return new DefaultMavenInvokerRequest<>( - parserRequest, - cwd, - installationDirectory, - userHomeDirectory, - userProperties, - systemProperties, - topDirectory, - rootDirectory, - parserRequest.in(), - parserRequest.out(), - parserRequest.err(), - extensions, - (MavenOptions) options); - } - - @Override - protected MavenOptions parseArgs(String source, List args) throws ParserException { - try { - return CommonsCliMavenOptions.parse(source, args.toArray(new String[0])); - } catch (ParseException e) { - throw new ParserException("Failed to parse source " + source, e.getCause()); - } - } - - @Override - protected MavenOptions assembleOptions(List parsedOptions) { - return LayeredMavenOptions.layerMavenOptions(parsedOptions); - } -} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/CommonsCliResidentMavenOptions.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/CommonsCliResidentMavenOptions.java deleted file mode 100644 index 47e838271d0e..000000000000 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/CommonsCliResidentMavenOptions.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * 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.resident; - -import java.util.Collection; -import java.util.List; -import java.util.ListIterator; -import java.util.Map; -import java.util.Optional; - -import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.Option; -import org.apache.commons.cli.Options; -import org.apache.commons.cli.ParseException; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions; -import org.apache.maven.cling.invoker.mvn.CommonsCliMavenOptions; -import org.codehaus.plexus.interpolation.BasicInterpolator; -import org.codehaus.plexus.interpolation.InterpolationException; - -import static org.apache.maven.cling.invoker.Utils.createInterpolator; - -public class CommonsCliResidentMavenOptions extends CommonsCliMavenOptions implements ResidentMavenOptions { - public static CommonsCliResidentMavenOptions parse(String source, String[] args) throws ParseException { - CLIManager cliManager = new CLIManager(); - return new CommonsCliResidentMavenOptions(source, cliManager, cliManager.parse(args)); - } - - protected CommonsCliResidentMavenOptions(String source, CLIManager cliManager, CommandLine commandLine) { - super(source, cliManager, commandLine); - } - - @Override - public Optional rawStreams() { - if (commandLine.hasOption(CLIManager.RAW_STREAMS)) { - return Optional.of(Boolean.TRUE); - } - return Optional.empty(); - } - - private static CommonsCliResidentMavenOptions interpolate( - CommonsCliResidentMavenOptions options, Collection> properties) { - try { - // now that we have properties, interpolate all arguments - BasicInterpolator interpolator = createInterpolator(properties); - CommandLine.Builder commandLineBuilder = new CommandLine.Builder(); - commandLineBuilder.setDeprecatedHandler(o -> {}); - for (Option option : options.commandLine.getOptions()) { - if (!CLIManager.USER_PROPERTY.equals(option.getOpt())) { - List values = option.getValuesList(); - for (ListIterator it = values.listIterator(); it.hasNext(); ) { - it.set(interpolator.interpolate(it.next())); - } - } - commandLineBuilder.addOption(option); - } - for (String arg : options.commandLine.getArgList()) { - commandLineBuilder.addArg(interpolator.interpolate(arg)); - } - return new CommonsCliResidentMavenOptions( - options.source, (CLIManager) options.cliManager, commandLineBuilder.build()); - } catch (InterpolationException e) { - throw new IllegalArgumentException("Could not interpolate CommonsCliOptions", e); - } - } - - @Override - public ResidentMavenOptions interpolate(Collection> properties) { - return interpolate(this, properties); - } - - protected static class CLIManager extends CommonsCliMavenOptions.CLIManager { - public static final String RAW_STREAMS = "ras"; - - @Override - protected void prepareOptions(Options options) { - super.prepareOptions(options); - options.addOption(Option.builder(RAW_STREAMS) - .longOpt("raw-streams") - .hasArg() - .desc("Use raw-streams for daemon communication") - .build()); - } - } -} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvoker.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvoker.java index 4063d0de833c..71973eb4391b 100644 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvoker.java +++ b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvoker.java @@ -22,9 +22,9 @@ import java.util.concurrent.ConcurrentHashMap; import org.apache.maven.api.cli.InvokerException; +import org.apache.maven.api.cli.mvn.MavenInvokerRequest; +import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.api.cli.mvn.resident.ResidentMavenInvoker; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenInvokerRequest; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions; import org.apache.maven.cling.invoker.ProtoLookup; import org.apache.maven.cling.invoker.mvn.DefaultMavenInvoker; @@ -34,14 +34,14 @@ */ public class DefaultResidentMavenInvoker extends DefaultMavenInvoker< - ResidentMavenOptions, ResidentMavenInvokerRequest, DefaultResidentMavenInvoker.LocalContext> + MavenOptions, MavenInvokerRequest, DefaultResidentMavenInvoker.LocalContext> implements ResidentMavenInvoker { - protected static class LocalContext + public static class LocalContext extends DefaultMavenInvoker.MavenContext< - ResidentMavenOptions, ResidentMavenInvokerRequest, DefaultResidentMavenInvoker.LocalContext> { + MavenOptions, MavenInvokerRequest, DefaultResidentMavenInvoker.LocalContext> { - protected LocalContext(DefaultResidentMavenInvoker invoker, ResidentMavenInvokerRequest invokerRequest) { + protected LocalContext(DefaultResidentMavenInvoker invoker, MavenInvokerRequest invokerRequest) { super(invoker, invokerRequest); } @@ -54,7 +54,7 @@ public void shutDown() throws InvokerException { super.close(); } - public LocalContext copy(ResidentMavenInvokerRequest invokerRequest) { + public LocalContext copy(MavenInvokerRequest invokerRequest) { LocalContext shadow = new LocalContext((DefaultResidentMavenInvoker) invoker, invokerRequest); shadow.logger = logger; @@ -107,7 +107,7 @@ public void close() throws InvokerException { } @Override - protected LocalContext createContext(ResidentMavenInvokerRequest invokerRequest) { + protected LocalContext createContext(MavenInvokerRequest invokerRequest) { return residentContext .computeIfAbsent(getContextId(invokerRequest), k -> { LocalContext master = new LocalContext(this, invokerRequest); @@ -125,7 +125,7 @@ protected LocalContext createContext(ResidentMavenInvokerRequest invokerRequest) .copy(invokerRequest); } - protected String getContextId(ResidentMavenInvokerRequest invokerRequest) { + protected String getContextId(MavenInvokerRequest invokerRequest) { // TODO: in a moment Maven stop pushing user properties to system properties (and maybe something more) // and allow multiple instances per JVM, this may become a pool? return "resident"; diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvokerRequest.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvokerRequest.java deleted file mode 100644 index 5d2dc60bbc13..000000000000 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvokerRequest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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.resident; - -import java.io.InputStream; -import java.io.OutputStream; -import java.nio.file.Path; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import org.apache.maven.api.cli.ParserRequest; -import org.apache.maven.api.cli.extensions.CoreExtension; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenInvokerRequest; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions; -import org.apache.maven.cling.invoker.mvn.DefaultMavenInvokerRequest; - -/** - * Maven execution request. - */ -public class DefaultResidentMavenInvokerRequest extends DefaultMavenInvokerRequest - implements ResidentMavenInvokerRequest { - private final List jvmArguments; - - @SuppressWarnings("ParameterNumber") - public DefaultResidentMavenInvokerRequest( - ParserRequest parserRequest, - Path cwd, - Path installationDirectory, - Path userHomeDirectory, - Map userProperties, - Map systemProperties, - Path topDirectory, - Path rootDirectory, - InputStream in, - OutputStream out, - OutputStream err, - List coreExtensions, - List jvmArguments, - ResidentMavenOptions options) { - super( - parserRequest, - cwd, - installationDirectory, - userHomeDirectory, - userProperties, - systemProperties, - topDirectory, - rootDirectory, - in, - out, - err, - coreExtensions, - options); - this.jvmArguments = jvmArguments; - } - - @Override - public Optional> jvmArguments() { - return Optional.of(jvmArguments); - } -} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenParser.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenParser.java deleted file mode 100644 index affe9c32c442..000000000000 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenParser.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.resident; - -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.apache.commons.cli.ParseException; -import org.apache.maven.api.cli.Options; -import org.apache.maven.api.cli.ParserException; -import org.apache.maven.api.cli.ParserRequest; -import org.apache.maven.api.cli.extensions.CoreExtension; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenInvokerRequest; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenParser; -import org.apache.maven.cling.invoker.mvn.DefaultMavenParser; - -public class DefaultResidentMavenParser extends DefaultMavenParser - implements ResidentMavenParser { - - @SuppressWarnings("ParameterNumber") - @Override - protected DefaultResidentMavenInvokerRequest getInvokerRequest( - ParserRequest parserRequest, - Path cwd, - Path installationDirectory, - Path userHomeDirectory, - Map userProperties, - Map systemProperties, - Path topDirectory, - Path rootDirectory, - ArrayList extensions, - Options options) { - return new DefaultResidentMavenInvokerRequest( - parserRequest, - cwd, - installationDirectory, - userHomeDirectory, - userProperties, - systemProperties, - topDirectory, - rootDirectory, - parserRequest.in(), - parserRequest.out(), - parserRequest.err(), - extensions, - getJvmArguments(rootDirectory), - (ResidentMavenOptions) options); - } - - protected List getJvmArguments(Path rootDirectory) { - if (rootDirectory != null) { - // TODO: do this - return Collections.emptyList(); - } - return null; - } - - @Override - protected ResidentMavenOptions parseArgs(String source, List args) throws ParserException { - try { - return CommonsCliResidentMavenOptions.parse(source, args.toArray(new String[0])); - } catch (ParseException e) { - throw new ParserException("Failed to parse source " + source, e.getCause()); - } - } - - @Override - protected ResidentMavenOptions assembleOptions(List parsedOptions) { - return LayeredResidentMavenOptions.layerResidentMavenOptions(parsedOptions); - } -} diff --git a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/LayeredResidentMavenOptions.java b/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/LayeredResidentMavenOptions.java deleted file mode 100644 index c84295240db8..000000000000 --- a/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/LayeredResidentMavenOptions.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.resident; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions; -import org.apache.maven.cling.invoker.mvn.LayeredMavenOptions; - -public class LayeredResidentMavenOptions extends LayeredMavenOptions - implements ResidentMavenOptions { - public static ResidentMavenOptions layerResidentMavenOptions(Collection options) { - List o = options.stream().filter(Objects::nonNull).toList(); - if (o.isEmpty()) { - throw new IllegalArgumentException("No options specified (or all were null)"); - } else if (o.size() == 1) { - return o.get(0); - } else { - return new LayeredResidentMavenOptions(o); - } - } - - private LayeredResidentMavenOptions(List options) { - super(options); - } - - @Override - public Optional rawStreams() { - return Optional.empty(); - } - - @Override - public ResidentMavenOptions interpolate(Collection> properties) { - ArrayList interpolatedOptions = new ArrayList<>(options.size()); - for (ResidentMavenOptions o : options) { - interpolatedOptions.add(o.interpolate(properties)); - } - return layerResidentMavenOptions(interpolatedOptions); - } -} diff --git a/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvokerTest.java b/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvokerTest.java index 96fed74d35fc..eb7e96aac2fc 100644 --- a/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvokerTest.java +++ b/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/local/DefaultLocalMavenInvokerTest.java @@ -29,6 +29,7 @@ import org.apache.maven.api.cli.mvn.MavenInvokerRequest; import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.cling.invoker.ProtoLookup; +import org.apache.maven.cling.invoker.mvn.DefaultMavenParser; import org.apache.maven.cling.invoker.mvn.MavenInvokerTestSupport; import org.codehaus.plexus.classworlds.ClassWorld; import org.junit.jupiter.api.Disabled; @@ -50,7 +51,7 @@ protected Invoker> createInvoker() { @Override protected Parser> createParser() { - return new DefaultLocalMavenParser(); + return new DefaultMavenParser(); } @Test diff --git a/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvokerTest.java b/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvokerTest.java index f90794a66ab0..5e9df0f26bb4 100644 --- a/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvokerTest.java +++ b/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/DefaultResidentMavenInvokerTest.java @@ -26,9 +26,10 @@ import com.google.common.jimfs.Jimfs; import org.apache.maven.api.cli.Invoker; import org.apache.maven.api.cli.Parser; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenInvokerRequest; -import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions; +import org.apache.maven.api.cli.mvn.MavenInvokerRequest; +import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.cling.invoker.ProtoLookup; +import org.apache.maven.cling.invoker.mvn.DefaultMavenParser; import org.apache.maven.cling.invoker.mvn.MavenInvokerTestSupport; import org.codehaus.plexus.classworlds.ClassWorld; import org.junit.jupiter.api.Disabled; @@ -40,18 +41,18 @@ * Resident UT. */ public class DefaultResidentMavenInvokerTest - extends MavenInvokerTestSupport { + extends MavenInvokerTestSupport> { @Override - protected Invoker createInvoker() { + protected Invoker> createInvoker() { return new DefaultResidentMavenInvoker(ProtoLookup.builder() .addMapping(ClassWorld.class, new ClassWorld("plexus.core", ClassLoader.getSystemClassLoader())) .build()); } @Override - protected Parser createParser() { - return new DefaultResidentMavenParser(); + protected Parser> createParser() { + return new DefaultMavenParser(); } @Test