diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java index 64003dc72339..e63a515bb9ff 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/InvokerRequest.java @@ -50,7 +50,7 @@ public interface InvokerRequest { /** * Flag representing parser processing result: if there were some fatal errors during * {@link Parser#parseInvocation(ParserRequest)} this method will return {@code true} and invoker should - * handle this request as "early failure". + * handle this request as "early failure". In these cases, {@link #options()} usually is absent. */ boolean parsingFailed(); @@ -195,16 +195,17 @@ default Optional stdErr() { /** * Returns the options associated with this invocation request. * - * @return the options object + * @return the options optional. It will be absent if {@link #parsingFailed()} return {@code true}. */ @Nonnull - Options options(); + Optional options(); /** * This method returns "verbose" option value derived from multiple places: CLI options, but also CI detection, * if applicable. */ default boolean effectiveVerbose() { - return options().verbose().orElse(ciInfo().isPresent() && ciInfo().get().isVerbose()); + return options().isPresent() && options().orElseThrow().verbose().orElse(false) + || ciInfo().isPresent() && ciInfo().orElseThrow().isVerbose(); } } diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/MavenOptions.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/MavenOptions.java index 4f692564ea3e..a77ea4ebb7e0 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/MavenOptions.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvn/MavenOptions.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Optional; -import java.util.function.UnaryOperator; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; @@ -221,14 +220,4 @@ public interface MavenOptions extends Options { */ @Nonnull Optional> goals(); - - /** - * Returns a new instance of {@link MavenOptions} with values interpolated using the given callback. - * - * @param callback a callback to use for interpolation - * @return a new MavenOptions instance with interpolated values - */ - @Nonnull - @Override - MavenOptions interpolate(@Nonnull UnaryOperator callback); } diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnenc/EncryptOptions.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnenc/EncryptOptions.java index 1c71f2ca027d..f2f38f3cb0c5 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnenc/EncryptOptions.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnenc/EncryptOptions.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Optional; -import java.util.function.UnaryOperator; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; @@ -56,14 +55,4 @@ public interface EncryptOptions extends Options { */ @Nonnull Optional> goals(); - - /** - * Returns a new instance of EncryptOptions with values interpolated using the given properties. - * - * @param callback a callback to use for interpolation - * @return a new EncryptOptions instance with interpolated values - */ - @Nonnull - @Override - EncryptOptions interpolate(UnaryOperator callback); } diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnsh/ShellOptions.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnsh/ShellOptions.java index 81aef61d7adf..05abbd804f34 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnsh/ShellOptions.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnsh/ShellOptions.java @@ -18,10 +18,7 @@ */ package org.apache.maven.api.cli.mvnsh; -import java.util.function.UnaryOperator; - import org.apache.maven.api.annotations.Experimental; -import org.apache.maven.api.annotations.Nonnull; import org.apache.maven.api.cli.Options; /** @@ -31,14 +28,4 @@ * @since 4.0.0 */ @Experimental -public interface ShellOptions extends Options { - /** - * Returns a new instance of ShellOptions with values interpolated using the given properties. - * - * @param callback a callback to use for interpolation - * @return a new EncryptOptions instance with interpolated values - */ - @Nonnull - @Override - ShellOptions interpolate(UnaryOperator callback); -} +public interface ShellOptions extends Options {} diff --git a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnup/UpgradeOptions.java b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnup/UpgradeOptions.java index 76bcd1ab2e75..47d8a67cbec1 100644 --- a/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnup/UpgradeOptions.java +++ b/api/maven-api-cli/src/main/java/org/apache/maven/api/cli/mvnup/UpgradeOptions.java @@ -20,7 +20,6 @@ import java.util.List; import java.util.Optional; -import java.util.function.UnaryOperator; import org.apache.maven.api.annotations.Experimental; import org.apache.maven.api.annotations.Nonnull; @@ -111,13 +110,4 @@ public interface UpgradeOptions extends Options { */ @Nonnull Optional all(); - - /** - * Returns a new instance of UpgradeOptions with values interpolated using the given properties. - * - * @param callback a callback to use for interpolation - * @return a new UpgradeOptions instance with interpolated values - */ - @Nonnull - UpgradeOptions interpolate(UnaryOperator callback); } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java index c07c853f393a..65fa91e78e84 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenCling.java @@ -75,7 +75,7 @@ public MavenCling(ClassWorld classWorld) { @Override protected Invoker createInvoker() { return new MavenInvoker( - ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build()); + ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build(), null); } @Override diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenEncCling.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenEncCling.java index 64393914830b..3fb3a765ab11 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenEncCling.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenEncCling.java @@ -75,7 +75,7 @@ public MavenEncCling(ClassWorld classWorld) { @Override protected Invoker createInvoker() { return new EncryptInvoker( - ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build()); + ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build(), null); } @Override diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenShellCling.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenShellCling.java index 1b50e2ba7f58..ce28bb636143 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenShellCling.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenShellCling.java @@ -75,7 +75,7 @@ public MavenShellCling(ClassWorld classWorld) { @Override protected Invoker createInvoker() { return new ShellInvoker( - ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build()); + ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build(), null); } @Override diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenUpCling.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenUpCling.java index 7c8aea15ed17..f5650f0525ec 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenUpCling.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/MavenUpCling.java @@ -75,7 +75,7 @@ public MavenUpCling(ClassWorld classWorld) { @Override protected Invoker createInvoker() { return new UpgradeInvoker( - ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build()); + ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build(), null); } @Override diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java index 02960ecd54e9..dcb6d2cacaf6 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseInvokerRequest.java @@ -27,12 +27,13 @@ import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.cli.CoreExtensions; import org.apache.maven.api.cli.InvokerRequest; +import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.ParserRequest; import org.apache.maven.api.cli.cisupport.CIInfo; import static java.util.Objects.requireNonNull; -public abstract class BaseInvokerRequest implements InvokerRequest { +public class BaseInvokerRequest implements InvokerRequest { private final ParserRequest parserRequest; private final boolean parsingFailed; private final Path cwd; @@ -44,6 +45,7 @@ public abstract class BaseInvokerRequest implements InvokerRequest { private final Path rootDirectory; private final List coreExtensions; private final CIInfo ciInfo; + private final Options options; @SuppressWarnings("ParameterNumber") public BaseInvokerRequest( @@ -57,7 +59,8 @@ public BaseInvokerRequest( @Nonnull Path topDirectory, @Nullable Path rootDirectory, @Nullable List coreExtensions, - @Nullable CIInfo ciInfo) { + @Nullable CIInfo ciInfo, + @Nullable Options options) { this.parserRequest = requireNonNull(parserRequest); this.parsingFailed = parsingFailed; this.cwd = requireNonNull(cwd); @@ -70,6 +73,7 @@ public BaseInvokerRequest( this.rootDirectory = rootDirectory; this.coreExtensions = coreExtensions; this.ciInfo = ciInfo; + this.options = options; } @Override @@ -126,4 +130,8 @@ public Optional> coreExtensions() { public Optional ciInfo() { return Optional.ofNullable(ciInfo); } + + public Optional options() { + return Optional.ofNullable(options); + } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java index e13f76476987..d4b99f2ec17a 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/BaseParser.java @@ -91,6 +91,7 @@ public LocalContext(ParserRequest parserRequest) { @Nullable public CIInfo ciInfo; + @Nullable public Options options; public Map extraInterpolationSource() { @@ -149,24 +150,14 @@ public InvokerRequest parseInvocation(ParserRequest parserRequest) { } // options - List parsedOptions; try { - parsedOptions = parseCliOptions(context); + context.options = parseCliOptions(context); } catch (Exception e) { context.parsingFailed = true; - parsedOptions = List.of(emptyOptions()); + context.options = null; parserRequest.logger().error("Error parsing program arguments", e); } - // assemble options if needed - try { - context.options = assembleOptions(parsedOptions); - } catch (Exception e) { - context.parsingFailed = true; - context.options = emptyOptions(); - parserRequest.logger().error("Error assembling program arguments", e); - } - // system and user properties try { context.systemProperties = populateSystemProperties(context); @@ -184,8 +175,12 @@ public InvokerRequest parseInvocation(ParserRequest parserRequest) { } // options: interpolate - context.options = context.options.interpolate(Interpolator.chain( - context.extraInterpolationSource()::get, context.userProperties::get, context.systemProperties::get)); + if (context.options != null) { + context.options = context.options.interpolate(Interpolator.chain( + context.extraInterpolationSource()::get, + context.userProperties::get, + context.systemProperties::get)); + } // core extensions try { @@ -255,9 +250,21 @@ protected void failIfFileNotExists(LocalContext context, String fileName, String } } - protected abstract Options emptyOptions(); - - protected abstract InvokerRequest getInvokerRequest(LocalContext context); + protected InvokerRequest getInvokerRequest(LocalContext context) { + return new BaseInvokerRequest( + context.parserRequest, + context.parsingFailed, + context.cwd, + context.installationDirectory, + context.userHomeDirectory, + context.userProperties, + context.systemProperties, + context.topDirectory, + context.rootDirectory, + context.extensions, + context.ciInfo, + context.options); + } protected Path getCwd(LocalContext context) { if (context.parserRequest.cwd() != null) { @@ -435,9 +442,7 @@ protected Map populateUserProperties(LocalContext context) { return toMap(userProperties); } - protected abstract List parseCliOptions(LocalContext context); - - protected abstract Options assembleOptions(List parsedOptions); + protected abstract Options parseCliOptions(LocalContext context); /** * Important: This method must return list of {@link CoreExtensions} in precedence order. diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CommonsCliOptions.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CommonsCliOptions.java index 10f8a06ec4f3..028e3b54cf4d 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CommonsCliOptions.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/CommonsCliOptions.java @@ -21,10 +21,13 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.util.LinkedHashSet; +import java.util.List; +import java.util.ListIterator; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; +import java.util.function.UnaryOperator; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.DefaultParser; @@ -34,12 +37,15 @@ import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.ParserRequest; +import org.apache.maven.api.services.Interpolator; +import org.apache.maven.api.services.InterpolatorException; import org.apache.maven.jline.MessageUtils; import static java.util.Objects.requireNonNull; +import static org.apache.maven.cling.invoker.CliUtils.createInterpolator; import static org.apache.maven.cling.invoker.CliUtils.toMap; -public abstract class CommonsCliOptions implements Options { +public class CommonsCliOptions implements Options { protected final String source; protected final CLIManager cliManager; @@ -250,6 +256,35 @@ public void warnAboutDeprecatedOptions(ParserRequest request, Consumer p } } + @Override + public final Options interpolate(UnaryOperator callback) { + try { + // now that we have properties, interpolate all arguments + Interpolator interpolator = createInterpolator(); + CommandLine.Builder commandLineBuilder = CommandLine.builder(); + commandLineBuilder.setDeprecatedHandler(o -> {}); + for (Option option : commandLine.getOptions()) { + if (!CommonsCliOptions.CLIManager.USER_PROPERTY.equals(option.getOpt())) { + List values = option.getValuesList(); + for (ListIterator it = values.listIterator(); it.hasNext(); ) { + it.set(interpolator.interpolate(it.next(), callback)); + } + } + commandLineBuilder.addOption(option); + } + for (String arg : commandLine.getArgList()) { + commandLineBuilder.addArg(interpolator.interpolate(arg, callback)); + } + return copy(source, cliManager, commandLineBuilder.build()); + } catch (InterpolatorException e) { + throw new IllegalArgumentException("Could not interpolate CommonsCliOptions", e); + } + } + + protected CommonsCliOptions copy(String source, CLIManager cliManager, CommandLine commandLine) { + return new CommonsCliOptions(source, cliManager, commandLine); + } + @Override public void displayHelp(ParserRequest request, Consumer printStream) { cliManager.displayHelp(request.command(), printStream); diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java index 36fcf92424e7..c3bbb9815852 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupContext.java @@ -31,6 +31,7 @@ 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.Lookup; import org.apache.maven.api.settings.Settings; import org.apache.maven.api.toolchain.PersistedToolchains; @@ -49,17 +50,15 @@ public class LookupContext implements AutoCloseable { public final Path installationDirectory; public final Path userDirectory; public final boolean containerCapsuleManaged; + private final Options options; - public LookupContext(InvokerRequest invokerRequest) { - this(invokerRequest, true); - } - - public LookupContext(InvokerRequest invokerRequest, boolean containerCapsuleManaged) { + public LookupContext(InvokerRequest invokerRequest, boolean containerCapsuleManaged, Options options) { this.invokerRequest = requireNonNull(invokerRequest); this.cwd = CWD.create(invokerRequest.cwd()); this.installationDirectory = CliUtils.getCanonicalPath(invokerRequest.installationDirectory()); this.userDirectory = CliUtils.getCanonicalPath(invokerRequest.userHomeDirectory()); this.containerCapsuleManaged = containerCapsuleManaged; + this.options = options; this.logger = invokerRequest.parserRequest().logger(); Map user = new HashMap<>(invokerRequest.userProperties()); @@ -149,4 +148,8 @@ public void doCloseContainer() throws Exception { } } } + + public Options options() { + return options; + } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java index c0b8c50b56f3..9abe2e8ceb3d 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/LookupInvoker.java @@ -45,7 +45,6 @@ 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.cli.cisupport.CIInfo; import org.apache.maven.api.cli.logging.AccumulatingLogger; import org.apache.maven.api.services.BuilderProblem; @@ -169,7 +168,7 @@ protected int doInvoke(C context) throws Exception { protected InvokerException.ExitException handleException(C context, Exception e) { printErrors( context, - context.invokerRequest.options().showErrors().orElse(false), + context.options().showErrors().orElse(false), List.of(new Logger.Entry(Logger.Level.ERROR, e.getMessage(), e.getCause())), context.logger); return new InvokerException.ExitException(2); @@ -217,9 +216,7 @@ protected void validate(C context) throws Exception { } // warn about deprecated options - context.invokerRequest - .options() - .warnAboutDeprecatedOptions(context.invokerRequest.parserRequest(), context.logger::warn); + context.options().warnAboutDeprecatedOptions(context.invokerRequest.parserRequest(), context.logger::warn); } protected void pushCoreProperties(C context) throws Exception { @@ -253,9 +250,8 @@ protected void pushUserProperties(C context) throws Exception { protected void configureLogging(C context) throws Exception { // LOG COLOR - Options mavenOptions = context.invokerRequest.options(); Map userProperties = context.protoSession.getUserProperties(); - String styleColor = mavenOptions + String styleColor = context.options() .color() .orElse(userProperties.getOrDefault( Constants.MAVEN_STYLE_COLOR_PROPERTY, userProperties.getOrDefault("style.color", "auto"))) @@ -268,9 +264,9 @@ protected void configureLogging(C context) throws Exception { throw new IllegalArgumentException( "Invalid color configuration value '" + styleColor + "'. Supported are 'auto', 'always', 'never'."); } else { - boolean isBatchMode = !mavenOptions.forceInteractive().orElse(false) - && mavenOptions.nonInteractive().orElse(false); - if (isBatchMode || mavenOptions.logFile().isPresent()) { + boolean isBatchMode = !context.options().forceInteractive().orElse(false) + && context.options().nonInteractive().orElse(false); + if (isBatchMode || context.options().logFile().isPresent()) { context.coloredOutput = false; } } @@ -281,7 +277,7 @@ protected void configureLogging(C context) throws Exception { context.loggerLevel = Slf4jConfiguration.Level.INFO; if (context.invokerRequest.effectiveVerbose()) { context.loggerLevel = Slf4jConfiguration.Level.DEBUG; - } else if (mavenOptions.quiet().orElse(false)) { + } else if (context.options().quiet().orElse(false)) { context.loggerLevel = Slf4jConfiguration.Level.ERROR; } context.slf4jConfiguration.setRootLoggerLevel(context.loggerLevel); @@ -346,7 +342,6 @@ protected void doCreateTerminal(C context, TerminalBuilder builder) { */ protected final void doConfigureWithTerminal(C context, Terminal terminal) { context.terminal = terminal; - Options options = context.invokerRequest.options(); // tricky thing: align what JLine3 detected and Maven thinks: // if embedded, we default to context.coloredOutput=false unless overridden (see above) // if not embedded, JLine3 may detect redirection and will create dumb terminal. @@ -357,7 +352,7 @@ protected final void doConfigureWithTerminal(C context, Terminal terminal) { context.coloredOutput != null ? context.coloredOutput : !Terminal.TYPE_DUMB.equals(terminal.getType())); // handle rawStreams: some would like to act on true, some on false - if (options.rawStreams().orElse(false)) { + if (context.options().rawStreams().orElse(false)) { doConfigureWithTerminalWithRawStreamsEnabled(context); } else { doConfigureWithTerminalWithRawStreamsDisabled(context); @@ -394,9 +389,8 @@ protected Consumer determineWriter(C context) { } protected Consumer doDetermineWriter(C context) { - Options options = context.invokerRequest.options(); - if (options.logFile().isPresent()) { - Path logFile = context.cwd.resolve(options.logFile().get()); + if (context.options().logFile().isPresent()) { + Path logFile = context.cwd.resolve(context.options().logFile().get()); try { PrintWriter printWriter = new PrintWriter(Files.newBufferedWriter(logFile), true); context.closeables.add(printWriter); @@ -416,12 +410,9 @@ protected Consumer doDetermineWriter(C context) { } protected void activateLogging(C context) throws Exception { - InvokerRequest invokerRequest = context.invokerRequest; - Options mavenOptions = invokerRequest.options(); - context.slf4jConfiguration.activate(); - if (mavenOptions.failOnSeverity().isPresent()) { - String logLevelThreshold = mavenOptions.failOnSeverity().get(); + if (context.options().failOnSeverity().isPresent()) { + String logLevelThreshold = context.options().failOnSeverity().get(); if (context.loggerFactory instanceof LogLevelRecorder recorder) { LogLevelRecorder.Level level = switch (logLevelThreshold.toLowerCase(Locale.ENGLISH)) { @@ -449,13 +440,12 @@ protected void activateLogging(C context) throws Exception { } protected void helpOrVersionAndMayExit(C context) throws Exception { - InvokerRequest invokerRequest = context.invokerRequest; - if (invokerRequest.options().help().isPresent()) { + if (context.options().help().isPresent()) { Consumer writer = determineWriter(context); - invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), writer); + context.options().displayHelp(context.invokerRequest.parserRequest(), writer); throw new InvokerException.ExitException(0); } - if (invokerRequest.options().showVersionAndExit().isPresent()) { + if (context.options().showVersionAndExit().isPresent()) { showVersion(context); throw new InvokerException.ExitException(0); } @@ -463,10 +453,9 @@ protected void helpOrVersionAndMayExit(C context) throws Exception { protected void showVersion(C context) { Consumer writer = determineWriter(context); - InvokerRequest invokerRequest = context.invokerRequest; - if (invokerRequest.options().quiet().orElse(false)) { + if (context.options().quiet().orElse(false)) { writer.accept(CLIReportingUtils.showVersionMinimal()); - } else if (invokerRequest.effectiveVerbose()) { + } else if (context.invokerRequest.effectiveVerbose()) { writer.accept(CLIReportingUtils.showVersion( ProcessHandle.current().info().commandLine().orElse(null), describe(context.terminal))); @@ -495,7 +484,7 @@ protected String describe(Terminal terminal) { protected void preCommands(C context) throws Exception { boolean verbose = context.invokerRequest.effectiveVerbose(); - boolean version = context.invokerRequest.options().showVersion().orElse(false); + boolean version = context.options().showVersion().orElse(false); if (verbose || version) { showVersion(context); } @@ -550,12 +539,11 @@ protected void init(C context) throws Exception { } protected void postCommands(C context) throws Exception { - InvokerRequest invokerRequest = context.invokerRequest; Logger logger = context.logger; - if (invokerRequest.options().showErrors().orElse(false)) { + if (context.options().showErrors().orElse(false)) { logger.info("Error stacktraces are turned on."); } - if (context.invokerRequest.options().verbose().orElse(false)) { + if (context.options().verbose().orElse(false)) { logger.debug("Message scheme: " + (MessageUtils.isColorEnabled() ? "color" : "plain")); if (MessageUtils.isColorEnabled()) { MessageBuilder buff = MessageUtils.builder(); @@ -594,12 +582,10 @@ protected void settings(C context) throws Exception { */ protected Runnable settings(C context, boolean emitSettingsWarnings, SettingsBuilder settingsBuilder) throws Exception { - Options mavenOptions = context.invokerRequest.options(); - Path userSettingsFile = null; - if (mavenOptions.altUserSettings().isPresent()) { + if (context.options().altUserSettings().isPresent()) { userSettingsFile = - context.cwd.resolve(mavenOptions.altUserSettings().get()); + context.cwd.resolve(context.options().altUserSettings().get()); if (!Files.isRegularFile(userSettingsFile)) { throw new FileNotFoundException("The specified user settings file does not exist: " + userSettingsFile); @@ -614,9 +600,9 @@ protected Runnable settings(C context, boolean emitSettingsWarnings, SettingsBui } Path projectSettingsFile = null; - if (mavenOptions.altProjectSettings().isPresent()) { + if (context.options().altProjectSettings().isPresent()) { projectSettingsFile = - context.cwd.resolve(mavenOptions.altProjectSettings().get()); + context.cwd.resolve(context.options().altProjectSettings().get()); if (!Files.isRegularFile(projectSettingsFile)) { throw new FileNotFoundException( @@ -631,9 +617,9 @@ protected Runnable settings(C context, boolean emitSettingsWarnings, SettingsBui } Path installationSettingsFile = null; - if (mavenOptions.altInstallationSettings().isPresent()) { - installationSettingsFile = - context.cwd.resolve(mavenOptions.altInstallationSettings().get()); + if (context.options().altInstallationSettings().isPresent()) { + installationSettingsFile = context.cwd.resolve( + context.options().altInstallationSettings().get()); if (!Files.isRegularFile(installationSettingsFile)) { throw new FileNotFoundException( @@ -698,7 +684,7 @@ protected Runnable settings(C context, boolean emitSettingsWarnings, SettingsBui "%s %s encountered while building the effective settings (use -e to see details)", totalProblems, (totalProblems == 1) ? "problem was" : "problems were")); - if (context.invokerRequest.options().showErrors().orElse(false)) { + if (context.options().showErrors().orElse(false)) { for (BuilderProblem problem : settingsResult.getProblems().problems().toList()) { context.logger.warn(problem.getMessage() + " @ " + problem.getLocation()); @@ -722,8 +708,8 @@ protected void customizeSettingsRequest(C context, SettingsBuilderRequest settin protected void customizeSettingsResult(C context, SettingsBuilderResult settingsBuilderResult) throws Exception {} protected boolean mayDisableInteractiveMode(C context, boolean proposedInteractive) { - if (!context.invokerRequest.options().forceInteractive().orElse(false)) { - if (context.invokerRequest.options().nonInteractive().orElse(false)) { + if (!context.options().forceInteractive().orElse(false)) { + if (context.options().nonInteractive().orElse(false)) { return false; } else { if (context.invokerRequest.ciInfo().isPresent()) { @@ -768,13 +754,12 @@ protected Path localRepositoryPath(C context) { protected void populateRequest(C context, Lookup lookup, MavenExecutionRequest request) throws Exception { populateRequestFromSettings(request, context.effectiveSettings); - Options options = context.invokerRequest.options(); request.setLoggingLevel(toMavenExecutionRequestLoggingLevel(context.loggerLevel)); request.setLocalRepositoryPath(context.localRepositoryPath.toFile()); request.setLocalRepository(createLocalArtifactRepository(context.localRepositoryPath)); request.setInteractiveMode(context.interactive); - request.setShowErrors(options.showErrors().orElse(false)); + request.setShowErrors(context.options().showErrors().orElse(false)); request.setBaseDirectory(context.invokerRequest.topDirectory().toFile()); request.setSystemProperties(toProperties(context.protoSession.getSystemProperties())); request.setUserProperties(toProperties(context.protoSession.getUserProperties())); diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/CommonsCliMavenOptions.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/CommonsCliMavenOptions.java index 2632d71e48c2..1101965ad75b 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/CommonsCliMavenOptions.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/CommonsCliMavenOptions.java @@ -20,20 +20,14 @@ import java.util.Arrays; import java.util.List; -import java.util.ListIterator; import java.util.Optional; -import java.util.function.UnaryOperator; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.mvn.MavenOptions; -import org.apache.maven.api.services.Interpolator; -import org.apache.maven.api.services.InterpolatorException; import org.apache.maven.cling.invoker.CommonsCliOptions; -import static org.apache.maven.cling.invoker.CliUtils.createInterpolator; - public class CommonsCliMavenOptions extends CommonsCliOptions implements MavenOptions { public static CommonsCliMavenOptions parse(String source, String[] args) throws ParseException { CLIManager cliManager = new CLIManager(); @@ -44,31 +38,6 @@ protected CommonsCliMavenOptions(String source, CLIManager cliManager, CommandLi super(source, cliManager, commandLine); } - private static CommonsCliMavenOptions interpolate(CommonsCliMavenOptions options, UnaryOperator callback) { - try { - // now that we have properties, interpolate all arguments - Interpolator interpolator = createInterpolator(); - 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(), callback)); - } - } - commandLineBuilder.addOption(option); - } - for (String arg : options.commandLine.getArgList()) { - commandLineBuilder.addArg(interpolator.interpolate(arg, callback)); - } - return new CommonsCliMavenOptions( - options.source, (CLIManager) options.cliManager, commandLineBuilder.build()); - } catch (InterpolatorException e) { - throw new IllegalArgumentException("Could not interpolate CommonsCliOptions", e); - } - } - @Override public Optional alternatePomFile() { if (commandLine.hasOption(CLIManager.ALTERNATE_POM_FILE)) { @@ -255,8 +224,9 @@ public Optional> goals() { } @Override - public MavenOptions interpolate(UnaryOperator callback) { - return interpolate(this, callback); + protected CommonsCliMavenOptions copy( + String source, CommonsCliOptions.CLIManager cliManager, CommandLine commandLine) { + return new CommonsCliMavenOptions(source, (CLIManager) cliManager, commandLine); } protected static class CLIManager extends CommonsCliOptions.CLIManager { diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/LayeredMavenOptions.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/LayeredMavenOptions.java index d88e08b04721..a4ad7f5e41d1 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/LayeredMavenOptions.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/LayeredMavenOptions.java @@ -168,7 +168,7 @@ public Optional> goals() { public MavenOptions interpolate(UnaryOperator callback) { ArrayList interpolatedOptions = new ArrayList<>(options.size()); for (MavenOptions o : options) { - interpolatedOptions.add(o.interpolate(callback)); + interpolatedOptions.add((MavenOptions) o.interpolate(callback)); } return layerMavenOptions(interpolatedOptions); } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenContext.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenContext.java index 7f84ff96141c..05e824b53f5c 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenContext.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenContext.java @@ -20,16 +20,13 @@ import org.apache.maven.Maven; import org.apache.maven.api.cli.InvokerRequest; +import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.cling.invoker.LookupContext; @SuppressWarnings("VisibilityModifier") public class MavenContext extends LookupContext { - public MavenContext(InvokerRequest invokerRequest) { - this(invokerRequest, true); - } - - public MavenContext(InvokerRequest invokerRequest, boolean containerCapsuleManaged) { - super(invokerRequest, containerCapsuleManaged); + public MavenContext(InvokerRequest invokerRequest, boolean containerCapsuleManaged, MavenOptions mavenOptions) { + super(invokerRequest, containerCapsuleManaged, mavenOptions); } public Maven maven; @@ -42,4 +39,9 @@ public void doCloseContainer() throws Exception { maven = null; } } + + @Override + public MavenOptions options() { + return (MavenOptions) super.options(); + } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java index 44b435712eaf..23d90d9caff7 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvoker.java @@ -79,17 +79,14 @@ * The Maven invoker, that expects whole Maven on classpath and invokes it. */ public class MavenInvoker extends LookupInvoker { - public MavenInvoker(Lookup protoLookup) { - this(protoLookup, null); - } - public MavenInvoker(Lookup protoLookup, @Nullable Consumer contextConsumer) { super(protoLookup, contextConsumer); } @Override protected MavenContext createContext(InvokerRequest invokerRequest) { - return new MavenContext(invokerRequest); + return new MavenContext( + invokerRequest, true, (MavenOptions) invokerRequest.options().orElse(null)); } @Override @@ -129,21 +126,19 @@ protected void lookup(MavenContext context) throws Exception { protected void postCommands(MavenContext context) throws Exception { super.postCommands(context); - InvokerRequest invokerRequest = context.invokerRequest; - MavenOptions options = (MavenOptions) invokerRequest.options(); Logger logger = context.logger; - if (options.relaxedChecksums().orElse(false)) { + if (context.options().relaxedChecksums().orElse(false)) { logger.info("Disabling strict checksum verification on all artifact downloads."); - } else if (options.strictChecksums().orElse(false)) { + } else if (context.options().strictChecksums().orElse(false)) { logger.info("Enabling strict checksum verification on all artifact downloads."); } } protected void toolchains(MavenContext context, MavenExecutionRequest request) throws Exception { Path userToolchainsFile = null; - if (context.invokerRequest.options().altUserToolchains().isPresent()) { - userToolchainsFile = context.cwd.resolve( - context.invokerRequest.options().altUserToolchains().get()); + if (context.options().altUserToolchains().isPresent()) { + userToolchainsFile = + context.cwd.resolve(context.options().altUserToolchains().get()); if (!Files.isRegularFile(userToolchainsFile)) { throw new FileNotFoundException( @@ -158,9 +153,9 @@ protected void toolchains(MavenContext context, MavenExecutionRequest request) t } Path installationToolchainsFile = null; - if (context.invokerRequest.options().altInstallationToolchains().isPresent()) { + if (context.options().altInstallationToolchains().isPresent()) { installationToolchainsFile = context.cwd.resolve( - context.invokerRequest.options().altInstallationToolchains().get()); + context.options().altInstallationToolchains().get()); if (!Files.isRegularFile(installationToolchainsFile)) { throw new FileNotFoundException( @@ -211,7 +206,7 @@ protected void toolchains(MavenContext context, MavenExecutionRequest request) t "%s %s encountered while building the effective toolchains (use -e to see details)", totalProblems, (totalProblems == 1) ? "problem was" : "problems were")); - if (context.invokerRequest.options().showErrors().orElse(false)) { + if (context.options().showErrors().orElse(false)) { for (BuilderProblem problem : toolchainsResult.getProblems().problems().toList()) { context.logger.warn(problem.getMessage() + " @ " + problem.getLocation()); @@ -239,13 +234,12 @@ protected void populateRequest(MavenContext context, Lookup lookup, MavenExecuti .map(ToolchainModel::new) .collect(Collectors.groupingBy(ToolchainModel::getType))); - MavenOptions options = (MavenOptions) context.invokerRequest.options(); - request.setNoSnapshotUpdates(options.suppressSnapshotUpdates().orElse(false)); - request.setGoals(options.goals().orElse(List.of())); + request.setNoSnapshotUpdates(context.options().suppressSnapshotUpdates().orElse(false)); + request.setGoals(context.options().goals().orElse(List.of())); request.setReactorFailureBehavior(determineReactorFailureBehaviour(context)); - request.setRecursive(!options.nonRecursive().orElse(!request.isRecursive())); - request.setOffline(options.offline().orElse(request.isOffline())); - request.setUpdateSnapshots(options.updateSnapshots().orElse(false)); + request.setRecursive(!context.options().nonRecursive().orElse(!request.isRecursive())); + request.setOffline(context.options().offline().orElse(request.isOffline())); + request.setUpdateSnapshots(context.options().updateSnapshots().orElse(false)); request.setGlobalChecksumPolicy(determineGlobalChecksumPolicy(context)); Path pom = determinePom(context, lookup); @@ -263,17 +257,17 @@ protected void populateRequest(MavenContext context, Lookup lookup, MavenExecuti } } - request.setTransferListener( - determineTransferListener(context, options.noTransferProgress().orElse(false))); + request.setTransferListener(determineTransferListener( + context, context.options().noTransferProgress().orElse(false))); request.setExecutionListener(determineExecutionListener(context)); - request.setResumeFrom(options.resumeFrom().orElse(null)); - request.setResume(options.resume().orElse(false)); + request.setResumeFrom(context.options().resumeFrom().orElse(null)); + request.setResume(context.options().resume().orElse(false)); request.setMakeBehavior(determineMakeBehavior(context)); - request.setCacheNotFound(options.cacheArtifactNotFound().orElse(true)); + request.setCacheNotFound(context.options().cacheArtifactNotFound().orElse(true)); request.setCacheTransferError(false); - if (options.strictArtifactDescriptorPolicy().orElse(false)) { + if (context.options().strictArtifactDescriptorPolicy().orElse(false)) { request.setIgnoreMissingArtifactDescriptor(false); request.setIgnoreInvalidArtifactDescriptor(false); } else { @@ -282,7 +276,7 @@ protected void populateRequest(MavenContext context, Lookup lookup, MavenExecuti } request.setIgnoreTransitiveRepositories( - options.ignoreTransitiveRepositories().orElse(false)); + context.options().ignoreTransitiveRepositories().orElse(false)); performProjectActivation(context, request.getProjectActivation()); performProfileActivation(context, request.getProfileActivation()); @@ -295,9 +289,9 @@ protected void populateRequest(MavenContext context, Lookup lookup, MavenExecuti // parameters but this is sufficient for now. Ultimately we want components like Builders to provide a way to // extend the command line to accept its own configuration parameters. // - if (options.threads().isPresent()) { + if (context.options().threads().isPresent()) { int degreeOfConcurrency = - calculateDegreeOfConcurrency(options.threads().get()); + calculateDegreeOfConcurrency(context.options().threads().get()); if (degreeOfConcurrency > 1) { request.setBuilderId("multithreaded"); request.setDegreeOfConcurrency(degreeOfConcurrency); @@ -307,16 +301,15 @@ protected void populateRequest(MavenContext context, Lookup lookup, MavenExecuti // // Allow the builder to be overridden by the user if requested. The builders are now pluggable. // - if (options.builder().isPresent()) { - request.setBuilderId(options.builder().get()); + if (context.options().builder().isPresent()) { + request.setBuilderId(context.options().builder().get()); } } protected Path determinePom(MavenContext context, Lookup lookup) { Path current = context.cwd.get(); - MavenOptions options = (MavenOptions) context.invokerRequest.options(); - if (options.alternatePomFile().isPresent()) { - current = context.cwd.resolve(options.alternatePomFile().get()); + if (context.options().alternatePomFile().isPresent()) { + current = context.cwd.resolve(context.options().alternatePomFile().get()); } ModelProcessor modelProcessor = lookup.lookupOptional(ModelProcessor.class).orElse(null); @@ -328,12 +321,11 @@ protected Path determinePom(MavenContext context, Lookup lookup) { } protected String determineReactorFailureBehaviour(MavenContext context) { - MavenOptions mavenOptions = (MavenOptions) context.invokerRequest.options(); - if (mavenOptions.failFast().isPresent()) { + if (context.options().failFast().isPresent()) { return MavenExecutionRequest.REACTOR_FAIL_FAST; - } else if (mavenOptions.failAtEnd().isPresent()) { + } else if (context.options().failAtEnd().isPresent()) { return MavenExecutionRequest.REACTOR_FAIL_AT_END; - } else if (mavenOptions.failNever().isPresent()) { + } else if (context.options().failNever().isPresent()) { return MavenExecutionRequest.REACTOR_FAIL_NEVER; } else { return MavenExecutionRequest.REACTOR_FAIL_FAST; @@ -341,10 +333,9 @@ protected String determineReactorFailureBehaviour(MavenContext context) { } protected String determineGlobalChecksumPolicy(MavenContext context) { - MavenOptions mavenOptions = (MavenOptions) context.invokerRequest.options(); - if (mavenOptions.strictChecksums().orElse(false)) { + if (context.options().strictChecksums().orElse(false)) { return MavenExecutionRequest.CHECKSUM_POLICY_FAIL; - } else if (mavenOptions.relaxedChecksums().orElse(false)) { + } else if (context.options().relaxedChecksums().orElse(false)) { return MavenExecutionRequest.CHECKSUM_POLICY_WARN; } else { return null; @@ -360,10 +351,10 @@ protected ExecutionListener determineExecutionListener(MavenContext context) { } protected TransferListener determineTransferListener(MavenContext context, boolean noTransferProgress) { - boolean quiet = context.invokerRequest.options().quiet().orElse(false); - boolean logFile = context.invokerRequest.options().logFile().isPresent(); + boolean quiet = context.options().quiet().orElse(false); + boolean logFile = context.options().logFile().isPresent(); boolean quietCI = context.invokerRequest.ciInfo().isPresent() - && !context.invokerRequest.options().forceInteractive().orElse(false); + && !context.options().forceInteractive().orElse(false); TransferListener delegate; if (quiet || noTransferProgress || quietCI) { @@ -382,15 +373,14 @@ protected TransferListener determineTransferListener(MavenContext context, boole } protected String determineMakeBehavior(MavenContext context) { - MavenOptions mavenOptions = (MavenOptions) context.invokerRequest.options(); - if (mavenOptions.alsoMake().isPresent() - && mavenOptions.alsoMakeDependents().isEmpty()) { + if (context.options().alsoMake().isPresent() + && context.options().alsoMakeDependents().isEmpty()) { return MavenExecutionRequest.REACTOR_MAKE_UPSTREAM; - } else if (mavenOptions.alsoMake().isEmpty() - && mavenOptions.alsoMakeDependents().isPresent()) { + } else if (context.options().alsoMake().isEmpty() + && context.options().alsoMakeDependents().isPresent()) { return MavenExecutionRequest.REACTOR_MAKE_DOWNSTREAM; - } else if (mavenOptions.alsoMake().isPresent() - && mavenOptions.alsoMakeDependents().isPresent()) { + } else if (context.options().alsoMake().isPresent() + && context.options().alsoMakeDependents().isPresent()) { return MavenExecutionRequest.REACTOR_MAKE_BOTH; } else { return null; @@ -398,10 +388,9 @@ protected String determineMakeBehavior(MavenContext context) { } protected void performProjectActivation(MavenContext context, ProjectActivation projectActivation) { - MavenOptions mavenOptions = (MavenOptions) context.invokerRequest.options(); - if (mavenOptions.projects().isPresent() - && !mavenOptions.projects().get().isEmpty()) { - List optionValues = mavenOptions.projects().get(); + if (context.options().projects().isPresent() + && !context.options().projects().get().isEmpty()) { + List optionValues = context.options().projects().get(); for (final String optionValue : optionValues) { for (String token : optionValue.split(",")) { String selector = token.trim(); @@ -426,10 +415,9 @@ protected void performProjectActivation(MavenContext context, ProjectActivation } protected void performProfileActivation(MavenContext context, ProfileActivation profileActivation) { - MavenOptions mavenOptions = (MavenOptions) context.invokerRequest.options(); - if (mavenOptions.activatedProfiles().isPresent() - && !mavenOptions.activatedProfiles().get().isEmpty()) { - List optionValues = mavenOptions.activatedProfiles().get(); + if (context.options().activatedProfiles().isPresent() + && !context.options().activatedProfiles().get().isEmpty()) { + List optionValues = context.options().activatedProfiles().get(); for (final String optionValue : optionValues) { for (String token : optionValue.split(",")) { String profileId = token.trim(); @@ -480,7 +468,7 @@ protected int doExecute(MavenContext context, MavenExecutionRequest request) thr context.logger.error(""); - if (!context.invokerRequest.options().showErrors().orElse(false)) { + if (!context.options().showErrors().orElse(false)) { context.logger.error("To see the full stack trace of the errors, re-run Maven with the '" + MessageUtils.builder().strong("-e") + "' switch"); } @@ -514,7 +502,7 @@ protected int doExecute(MavenContext context, MavenExecutionRequest request) thr } } - if (((MavenOptions) context.invokerRequest.options()).failNever().orElse(false)) { + if (context.options().failNever().orElse(false)) { context.logger.info("Build failures were ignored."); return 0; } else { @@ -609,7 +597,7 @@ protected void logSummary( line = indent + line + ("".equals(nextColor) ? "" : ANSI_RESET); if ((i == lines.length - 1) - && (context.invokerRequest.options().showErrors().orElse(false) + && (context.options().showErrors().orElse(false) || (summary.getException() instanceof InternalErrorException))) { context.logger.error(line, summary.getException()); } else { diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvokerRequest.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvokerRequest.java deleted file mode 100644 index d390b88ce645..000000000000 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenInvokerRequest.java +++ /dev/null @@ -1,77 +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; - -import java.nio.file.Path; -import java.util.List; -import java.util.Map; - -import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.cli.CoreExtensions; -import org.apache.maven.api.cli.ParserRequest; -import org.apache.maven.api.cli.cisupport.CIInfo; -import org.apache.maven.api.cli.mvn.MavenOptions; -import org.apache.maven.cling.invoker.BaseInvokerRequest; - -import static java.util.Objects.requireNonNull; - -/** - * Maven execution request. - */ -public class MavenInvokerRequest extends BaseInvokerRequest { - private final MavenOptions options; - - @SuppressWarnings("ParameterNumber") - public MavenInvokerRequest( - ParserRequest parserRequest, - boolean parseFailed, - Path cwd, - Path installationDirectory, - Path userHomeDirectory, - Map userProperties, - Map systemProperties, - Path topDirectory, - Path rootDirectory, - List coreExtensions, - CIInfo ciInfo, - MavenOptions options) { - super( - parserRequest, - parseFailed, - cwd, - installationDirectory, - userHomeDirectory, - userProperties, - systemProperties, - topDirectory, - rootDirectory, - coreExtensions, - ciInfo); - this.options = requireNonNull(options); - } - - /** - * The mandatory Maven options. - */ - @Nonnull - @Override - public MavenOptions options() { - return options; - } -} diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java index a8238d90ee4a..2b9b9bf53fc0 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/MavenParser.java @@ -32,10 +32,9 @@ import org.apache.maven.cling.invoker.BaseParser; public class MavenParser extends BaseParser { - @Override - protected List parseCliOptions(LocalContext context) { - ArrayList result = new ArrayList<>(); + protected Options parseCliOptions(LocalContext context) { + ArrayList result = new ArrayList<>(); // CLI args MavenOptions cliOptions = parseMavenCliOptions(context.parserRequest.args()); result.add(cliOptions); @@ -53,7 +52,7 @@ protected List parseCliOptions(LocalContext context) { if (mavenConfig != null && Files.isRegularFile(mavenConfig)) { result.add(parseMavenConfigOptions(mavenConfig)); } - return result; + return LayeredMavenOptions.layerMavenOptions(result); } protected MavenOptions parseMavenCliOptions(List args) { @@ -100,36 +99,4 @@ protected MavenOptions parseMavenConfigOptions(Path configFile) { protected MavenOptions parseArgs(String source, List args) throws ParseException { return CommonsCliMavenOptions.parse(source, args.toArray(new String[0])); } - - @Override - protected MavenOptions emptyOptions() { - try { - return CommonsCliMavenOptions.parse(Options.SOURCE_CLI, new String[0]); - } catch (ParseException e) { - throw new IllegalArgumentException(e); - } - } - - @Override - protected MavenInvokerRequest getInvokerRequest(LocalContext context) { - return new MavenInvokerRequest( - context.parserRequest, - context.parsingFailed, - context.cwd, - context.installationDirectory, - context.userHomeDirectory, - context.userProperties, - context.systemProperties, - context.topDirectory, - context.rootDirectory, - context.extensions, - context.ciInfo, - (MavenOptions) context.options); - } - - @Override - @SuppressWarnings({"unchecked", "rawtypes"}) - protected MavenOptions assembleOptions(List parsedOptions) { - return LayeredMavenOptions.layerMavenOptions((List) parsedOptions); - } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvoker.java index 84b49ebdec92..34d2a6932356 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvoker.java @@ -20,10 +20,14 @@ import java.util.ArrayList; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.cli.InvokerException; import org.apache.maven.api.cli.InvokerRequest; +import org.apache.maven.api.cli.mvn.MavenOptions; import org.apache.maven.api.services.Lookup; +import org.apache.maven.cling.invoker.LookupContext; import org.apache.maven.cling.invoker.mvn.MavenContext; import org.apache.maven.cling.invoker.mvn.MavenInvoker; @@ -38,8 +42,8 @@ public class ResidentMavenInvoker extends MavenInvoker { private final ConcurrentHashMap residentContext; - public ResidentMavenInvoker(Lookup protoLookup) { - super(protoLookup, null); + public ResidentMavenInvoker(Lookup protoLookup, @Nullable Consumer contextConsumer) { + super(protoLookup, contextConsumer); this.residentContext = new ConcurrentHashMap<>(); } @@ -64,7 +68,10 @@ public void close() throws InvokerException { protected MavenContext createContext(InvokerRequest 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? derive key based in invokerRequest? - MavenContext result = residentContext.computeIfAbsent("resident", k -> new MavenContext(invokerRequest, false)); + MavenContext result = residentContext.computeIfAbsent( + "resident", + k -> new MavenContext(invokerRequest, false, (MavenOptions) + invokerRequest.options().orElse(null))); return copyIfDifferent(result, invokerRequest); } @@ -72,7 +79,8 @@ protected MavenContext copyIfDifferent(MavenContext mavenContext, InvokerRequest if (invokerRequest == mavenContext.invokerRequest) { return mavenContext; } - MavenContext shadow = new MavenContext(invokerRequest, false); + MavenContext shadow = new MavenContext( + invokerRequest, false, (MavenOptions) invokerRequest.options().orElse(null)); // we carry over only "resident" things shadow.containerCapsule = mavenContext.containerCapsule; diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/CommonsCliEncryptOptions.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/CommonsCliEncryptOptions.java index 65d12d93ae89..495d6373dee0 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/CommonsCliEncryptOptions.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/CommonsCliEncryptOptions.java @@ -19,10 +19,8 @@ package org.apache.maven.cling.invoker.mvnenc; import java.util.List; -import java.util.ListIterator; import java.util.Optional; import java.util.function.Consumer; -import java.util.function.UnaryOperator; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; @@ -30,12 +28,8 @@ import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.ParserRequest; import org.apache.maven.api.cli.mvnenc.EncryptOptions; -import org.apache.maven.api.services.Interpolator; -import org.apache.maven.api.services.InterpolatorException; import org.apache.maven.cling.invoker.CommonsCliOptions; -import static org.apache.maven.cling.invoker.CliUtils.createInterpolator; - /** * Implementation of {@link EncryptOptions} (base + mvnenc). */ @@ -49,32 +43,6 @@ protected CommonsCliEncryptOptions(String source, CLIManager cliManager, Command super(source, cliManager, commandLine); } - private static CommonsCliEncryptOptions interpolate( - CommonsCliEncryptOptions options, UnaryOperator callback) { - try { - // now that we have properties, interpolate all arguments - Interpolator interpolator = createInterpolator(); - 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(), callback)); - } - } - commandLineBuilder.addOption(option); - } - for (String arg : options.commandLine.getArgList()) { - commandLineBuilder.addArg(interpolator.interpolate(arg, callback)); - } - return new CommonsCliEncryptOptions( - options.source, (CLIManager) options.cliManager, commandLineBuilder.build()); - } catch (InterpolatorException e) { - throw new IllegalArgumentException("Could not interpolate CommonsCliOptions", e); - } - } - @Override public Optional force() { if (commandLine.hasOption(CLIManager.FORCE)) { @@ -99,11 +67,6 @@ public Optional> goals() { return Optional.empty(); } - @Override - public EncryptOptions interpolate(UnaryOperator callback) { - return interpolate(this, callback); - } - @Override public void displayHelp(ParserRequest request, Consumer printStream) { super.displayHelp(request, printStream); @@ -117,6 +80,12 @@ public void displayHelp(ParserRequest request, Consumer printStream) { printStream.accept(""); } + @Override + protected CommonsCliEncryptOptions copy( + String source, CommonsCliOptions.CLIManager cliManager, CommandLine commandLine) { + return new CommonsCliEncryptOptions(source, (CLIManager) cliManager, commandLine); + } + protected static class CLIManager extends CommonsCliOptions.CLIManager { public static final String FORCE = "f"; public static final String YES = "y"; diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptContext.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptContext.java index 1e3f22514823..82ad430e2843 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptContext.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptContext.java @@ -22,6 +22,7 @@ import java.util.Map; import org.apache.maven.api.cli.InvokerRequest; +import org.apache.maven.api.cli.mvnenc.EncryptOptions; import org.apache.maven.cling.invoker.LookupContext; import org.jline.reader.LineReader; import org.jline.utils.AttributedString; @@ -30,12 +31,8 @@ @SuppressWarnings("VisibilityModifier") public class EncryptContext extends LookupContext { - public EncryptContext(InvokerRequest invokerRequest) { - this(invokerRequest, true); - } - - public EncryptContext(InvokerRequest invokerRequest, boolean containerCapsuleManaged) { - super(invokerRequest, containerCapsuleManaged); + public EncryptContext(InvokerRequest invokerRequest, EncryptOptions encryptOptions) { + super(invokerRequest, true, encryptOptions); } public Map goals; @@ -53,4 +50,9 @@ public void addInHeader(AttributedStyle style, String text) { asb.style(style).append(text); header.add(asb.toAttributedString()); } + + @Override + public EncryptOptions options() { + return (EncryptOptions) super.options(); + } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvoker.java index 6ae551a6a4cf..f0d74efd2125 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvoker.java @@ -45,17 +45,14 @@ public class EncryptInvoker extends LookupInvoker { public static final int BAD_OPERATION = 2; // bad user input or alike public static final int CANCELED = 3; // user canceled - public EncryptInvoker(Lookup protoLookup) { - this(protoLookup, null); - } - public EncryptInvoker(Lookup protoLookup, @Nullable Consumer contextConsumer) { super(protoLookup, contextConsumer); } @Override protected EncryptContext createContext(InvokerRequest invokerRequest) { - return new EncryptContext(invokerRequest); + return new EncryptContext( + invokerRequest, (EncryptOptions) invokerRequest.options().orElse(null)); } @Override @@ -84,12 +81,12 @@ protected int execute(EncryptContext context) throws Exception { context.reader = LineReaderBuilder.builder().terminal(context.terminal).build(); - EncryptOptions options = (EncryptOptions) context.invokerRequest.options(); - if (options.goals().isEmpty() || options.goals().get().size() != 1) { + if (context.options().goals().isEmpty() + || context.options().goals().get().size() != 1) { return badGoalsErrorMessage("No goal or multiple goals specified, specify only one goal.", context); } - String goalName = options.goals().get().get(0); + String goalName = context.options().goals().get().get(0); Goal goal = context.goals.get(goalName); if (goal == null) { @@ -101,7 +98,7 @@ protected int execute(EncryptContext context) throws Exception { context.logger.error("Goal canceled by user."); return CANCELED; } catch (Exception e) { - if (context.invokerRequest.options().showErrors().orElse(false)) { + if (context.options().showErrors().orElse(false)) { context.logger.error(e.getMessage(), e); } else { context.logger.error(e.getMessage()); diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvokerRequest.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvokerRequest.java deleted file mode 100644 index 60f596def746..000000000000 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptInvokerRequest.java +++ /dev/null @@ -1,74 +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.mvnenc; - -import java.nio.file.Path; -import java.util.List; -import java.util.Map; - -import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.cli.CoreExtensions; -import org.apache.maven.api.cli.ParserRequest; -import org.apache.maven.api.cli.cisupport.CIInfo; -import org.apache.maven.api.cli.mvnenc.EncryptOptions; -import org.apache.maven.cling.invoker.BaseInvokerRequest; - -import static java.util.Objects.requireNonNull; - -public class EncryptInvokerRequest extends BaseInvokerRequest { - private final EncryptOptions options; - - @SuppressWarnings("ParameterNumber") - public EncryptInvokerRequest( - ParserRequest parserRequest, - boolean parsingFailed, - Path cwd, - Path installationDirectory, - Path userHomeDirectory, - Map userProperties, - Map systemProperties, - Path topDirectory, - Path rootDirectory, - List coreExtensions, - CIInfo ciInfo, - EncryptOptions options) { - super( - parserRequest, - parsingFailed, - cwd, - installationDirectory, - userHomeDirectory, - userProperties, - systemProperties, - topDirectory, - rootDirectory, - coreExtensions, - ciInfo); - this.options = requireNonNull(options); - } - - /** - * The mandatory Encrypt options. - */ - @Nonnull - @Override - public EncryptOptions options() { - return options; - } -} diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java index 378f81f38326..e01a50e0b662 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/EncryptParser.java @@ -18,58 +18,17 @@ */ package org.apache.maven.cling.invoker.mvnenc; -import java.util.Collections; -import java.util.List; - import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.Options; -import org.apache.maven.api.cli.mvnenc.EncryptOptions; import org.apache.maven.cling.invoker.BaseParser; public class EncryptParser extends BaseParser { - - @Override - protected EncryptOptions emptyOptions() { - try { - return CommonsCliEncryptOptions.parse(new String[0]); - } catch (ParseException e) { - throw new IllegalArgumentException(e); - } - } - @Override - protected EncryptInvokerRequest getInvokerRequest(LocalContext context) { - return new EncryptInvokerRequest( - context.parserRequest, - context.parsingFailed, - context.cwd, - context.installationDirectory, - context.userHomeDirectory, - context.userProperties, - context.systemProperties, - context.topDirectory, - context.rootDirectory, - context.extensions, - context.ciInfo, - (EncryptOptions) context.options); - } - - @Override - protected List parseCliOptions(LocalContext context) { - return Collections.singletonList(parseEncryptCliOptions(context.parserRequest.args())); - } - - protected CommonsCliEncryptOptions parseEncryptCliOptions(List args) { + protected Options parseCliOptions(LocalContext context) { try { - return CommonsCliEncryptOptions.parse(args.toArray(new String[0])); + return CommonsCliEncryptOptions.parse(context.parserRequest.args().toArray(new String[0])); } catch (ParseException e) { throw new IllegalArgumentException("Failed to parse command line options: " + e.getMessage(), e); } } - - @Override - protected Options assembleOptions(List parsedOptions) { - // nothing to assemble, we deal with CLI only - return parsedOptions.get(0); - } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/ConfiguredGoalSupport.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/ConfiguredGoalSupport.java index a3647a1f6b80..bf4423f300ac 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/ConfiguredGoalSupport.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/ConfiguredGoalSupport.java @@ -50,7 +50,7 @@ public int execute(EncryptContext context) throws Exception { protected boolean validateConfiguration(EncryptContext context) { SecDispatcher.ValidationResponse response = secDispatcher.validateConfiguration(); - if (!response.isValid() || context.invokerRequest.options().verbose().orElse(false)) { + if (!response.isValid() || context.options().verbose().orElse(false)) { dumpResponse(context, "", response); } return response.isValid(); diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/Init.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/Init.java index a4e13bb78132..cb17a674df8e 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/Init.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnenc/goals/Init.java @@ -22,7 +22,6 @@ import java.util.Map; import java.util.Objects; -import org.apache.maven.api.cli.mvnenc.EncryptOptions; import org.apache.maven.api.di.Inject; import org.apache.maven.api.di.Named; import org.apache.maven.api.di.Singleton; @@ -62,9 +61,8 @@ public Init(MessageBuilderFactory messageBuilderFactory, SecDispatcher secDispat @SuppressWarnings("MethodLength") @Override public int doExecute(EncryptContext context) throws Exception { - EncryptOptions options = (EncryptOptions) context.invokerRequest.options(); - boolean force = options.force().orElse(false); - boolean yes = options.yes().orElse(false); + boolean force = context.options().force().orElse(false); + boolean yes = context.options().yes().orElse(false); if (configExists() && !force) { context.logger.error(messageBuilderFactory diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/CommonsCliShellOptions.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/CommonsCliShellOptions.java index 8b7957cb3203..768c2c1dc4ae 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/CommonsCliShellOptions.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/CommonsCliShellOptions.java @@ -18,21 +18,12 @@ */ package org.apache.maven.cling.invoker.mvnsh; -import java.util.List; -import java.util.ListIterator; -import java.util.function.UnaryOperator; - import org.apache.commons.cli.CommandLine; -import org.apache.commons.cli.Option; import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.mvnsh.ShellOptions; -import org.apache.maven.api.services.Interpolator; -import org.apache.maven.api.services.InterpolatorException; import org.apache.maven.cling.invoker.CommonsCliOptions; -import static org.apache.maven.cling.invoker.CliUtils.createInterpolator; - /** * Implementation of {@link ShellOptions} (base + shell). */ @@ -46,34 +37,10 @@ protected CommonsCliShellOptions(String source, CLIManager cliManager, CommandLi super(source, cliManager, commandLine); } - private static CommonsCliShellOptions interpolate(CommonsCliShellOptions options, UnaryOperator callback) { - try { - // now that we have properties, interpolate all arguments - Interpolator interpolator = createInterpolator(); - 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(), callback)); - } - } - commandLineBuilder.addOption(option); - } - for (String arg : options.commandLine.getArgList()) { - commandLineBuilder.addArg(interpolator.interpolate(arg, callback)); - } - return new CommonsCliShellOptions( - options.source, (CLIManager) options.cliManager, commandLineBuilder.build()); - } catch (InterpolatorException e) { - throw new IllegalArgumentException("Could not interpolate CommonsCliOptions", e); - } - } - @Override - public ShellOptions interpolate(UnaryOperator callback) { - return interpolate(this, callback); + protected CommonsCliShellOptions copy( + String source, CommonsCliOptions.CLIManager cliManager, CommandLine commandLine) { + return new CommonsCliShellOptions(source, (CLIManager) cliManager, commandLine); } protected static class CLIManager extends CommonsCliOptions.CLIManager { diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvoker.java index 608eeb98b66b..01c22ed1eb75 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvoker.java @@ -21,7 +21,9 @@ import java.nio.file.Path; import java.util.Map; import java.util.concurrent.atomic.AtomicReference; +import java.util.function.Consumer; +import org.apache.maven.api.annotations.Nullable; import org.apache.maven.api.cli.InvokerRequest; import org.apache.maven.api.services.Lookup; import org.apache.maven.cling.invoker.LookupContext; @@ -53,13 +55,13 @@ */ public class ShellInvoker extends LookupInvoker { - public ShellInvoker(Lookup protoLookup) { - super(protoLookup, null); + public ShellInvoker(Lookup protoLookup, @Nullable Consumer contextConsumer) { + super(protoLookup, contextConsumer); } @Override protected LookupContext createContext(InvokerRequest invokerRequest) { - return new LookupContext(invokerRequest); + return new LookupContext(invokerRequest, true, invokerRequest.options().orElse(null)); } public static final int OK = 0; // OK @@ -98,7 +100,7 @@ protected int execute(LookupContext context) throws Exception { ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░\s ░▒▓█▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓██▓▒░ ░▒▓█▓▒░░▒▓█▓▒░░▒▓███████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░"""; context.writer.accept(banner); - if (!context.invokerRequest.options().showVersion().orElse(false)) { + if (!context.options().showVersion().orElse(false)) { context.writer.accept(CLIReportingUtils.showVersionMinimal()); } context.writer.accept(""); @@ -174,7 +176,7 @@ public boolean isCommandOrScript(String command) { .builder() .error("Error: " + e.getMessage()) .build()); - if (context.invokerRequest.options().showErrors().orElse(false)) { + if (context.options().showErrors().orElse(false)) { e.printStackTrace(context.terminal.writer()); } return ERROR; diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvokerRequest.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvokerRequest.java deleted file mode 100644 index a5c328b82dee..000000000000 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellInvokerRequest.java +++ /dev/null @@ -1,74 +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.mvnsh; - -import java.nio.file.Path; -import java.util.List; -import java.util.Map; - -import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.cli.CoreExtensions; -import org.apache.maven.api.cli.ParserRequest; -import org.apache.maven.api.cli.cisupport.CIInfo; -import org.apache.maven.api.cli.mvnsh.ShellOptions; -import org.apache.maven.cling.invoker.BaseInvokerRequest; - -import static java.util.Objects.requireNonNull; - -public class ShellInvokerRequest extends BaseInvokerRequest { - private final ShellOptions options; - - @SuppressWarnings("ParameterNumber") - public ShellInvokerRequest( - ParserRequest parserRequest, - boolean parsingFailed, - Path cwd, - Path installationDirectory, - Path userHomeDirectory, - Map userProperties, - Map systemProperties, - Path topDirectory, - Path rootDirectory, - List coreExtensions, - CIInfo ciInfo, - ShellOptions options) { - super( - parserRequest, - parsingFailed, - cwd, - installationDirectory, - userHomeDirectory, - userProperties, - systemProperties, - topDirectory, - rootDirectory, - coreExtensions, - ciInfo); - this.options = requireNonNull(options); - } - - /** - * The mandatory Shell options. - */ - @Nonnull - @Override - public ShellOptions options() { - return options; - } -} diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java index 31c87e2f9056..07a5a1653e48 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnsh/ShellParser.java @@ -18,57 +18,17 @@ */ package org.apache.maven.cling.invoker.mvnsh; -import java.util.Collections; -import java.util.List; - import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.Options; -import org.apache.maven.api.cli.mvnsh.ShellOptions; import org.apache.maven.cling.invoker.BaseParser; public class ShellParser extends BaseParser { @Override - protected ShellOptions emptyOptions() { + protected Options parseCliOptions(LocalContext context) { try { - return CommonsCliShellOptions.parse(new String[0]); - } catch (ParseException e) { - throw new IllegalArgumentException(e); - } - } - - @Override - protected ShellInvokerRequest getInvokerRequest(LocalContext context) { - return new ShellInvokerRequest( - context.parserRequest, - context.parsingFailed, - context.cwd, - context.installationDirectory, - context.userHomeDirectory, - context.userProperties, - context.systemProperties, - context.topDirectory, - context.rootDirectory, - context.extensions, - context.ciInfo, - (ShellOptions) context.options); - } - - @Override - protected List parseCliOptions(LocalContext context) { - return Collections.singletonList(parseShellCliOptions(context.parserRequest.args())); - } - - protected CommonsCliShellOptions parseShellCliOptions(List args) { - try { - return CommonsCliShellOptions.parse(args.toArray(new String[0])); + return CommonsCliShellOptions.parse(context.parserRequest.args().toArray(new String[0])); } catch (ParseException e) { throw new IllegalArgumentException("Failed to parse command line options: " + e.getMessage(), e); } } - - @Override - protected Options assembleOptions(List parsedOptions) { - // nothing to assemble, we deal with CLI only - return parsedOptions.get(0); - } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/CommonsCliUpgradeOptions.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/CommonsCliUpgradeOptions.java index e1fcd283e96a..0e5621c2889a 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/CommonsCliUpgradeOptions.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/CommonsCliUpgradeOptions.java @@ -19,10 +19,8 @@ package org.apache.maven.cling.invoker.mvnup; import java.util.List; -import java.util.ListIterator; import java.util.Optional; import java.util.function.Consumer; -import java.util.function.UnaryOperator; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; @@ -31,12 +29,8 @@ import org.apache.maven.api.cli.Options; import org.apache.maven.api.cli.ParserRequest; import org.apache.maven.api.cli.mvnup.UpgradeOptions; -import org.apache.maven.api.services.Interpolator; -import org.apache.maven.api.services.InterpolatorException; import org.apache.maven.cling.invoker.CommonsCliOptions; -import static org.apache.maven.cling.invoker.CliUtils.createInterpolator; - /** * Implementation of {@link UpgradeOptions} (base + mvnup). */ @@ -50,32 +44,6 @@ protected CommonsCliUpgradeOptions(String source, CLIManager cliManager, Command super(source, cliManager, commandLine); } - private static CommonsCliUpgradeOptions interpolate( - CommonsCliUpgradeOptions options, UnaryOperator callback) { - try { - // now that we have properties, interpolate all arguments - Interpolator interpolator = createInterpolator(); - 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(), callback)); - } - } - commandLineBuilder.addOption(option); - } - for (String arg : options.commandLine.getArgList()) { - commandLineBuilder.addArg(interpolator.interpolate(arg, callback)); - } - return new CommonsCliUpgradeOptions( - options.source, (CLIManager) options.cliManager, commandLineBuilder.build()); - } catch (InterpolatorException e) { - throw new IllegalArgumentException("Could not interpolate CommonsCliOptions", e); - } - } - @Override @Nonnull public Optional force() { @@ -157,12 +125,6 @@ public Optional all() { return Optional.empty(); } - @Override - @Nonnull - public UpgradeOptions interpolate(UnaryOperator callback) { - return interpolate(this, callback); - } - @Override public void displayHelp(ParserRequest request, Consumer printStream) { super.displayHelp(request, printStream); @@ -188,6 +150,12 @@ public void displayHelp(ParserRequest request, Consumer printStream) { printStream.accept(""); } + @Override + protected CommonsCliUpgradeOptions copy( + String source, CommonsCliOptions.CLIManager cliManager, CommandLine commandLine) { + return new CommonsCliUpgradeOptions(source, (CLIManager) cliManager, commandLine); + } + protected static class CLIManager extends CommonsCliOptions.CLIManager { public static final String FORCE = "f"; public static final String YES = "y"; diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeContext.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeContext.java index 8361e593530a..bef4e344fd2c 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeContext.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeContext.java @@ -34,12 +34,8 @@ @SuppressWarnings("VisibilityModifier") public class UpgradeContext extends LookupContext { - public UpgradeContext(InvokerRequest invokerRequest) { - this(invokerRequest, true); - } - - public UpgradeContext(InvokerRequest invokerRequest, boolean containerCapsuleManaged) { - super(invokerRequest, containerCapsuleManaged); + public UpgradeContext(InvokerRequest invokerRequest, UpgradeOptions upgradeOptions) { + super(invokerRequest, true, upgradeOptions); } public Map goals; @@ -161,20 +157,6 @@ public void action(String message) { */ @Nonnull public UpgradeOptions options() { - return invokerRequest().options(); - } - - /** - * Gets the upgrade-specific invoker request with proper type casting. - * This method provides type-safe access to the UpgradeInvokerRequest, - * which contains upgrade-specific options and configuration. - * - * @return the UpgradeInvokerRequest instance, never null - * @throws ClassCastException if the invokerRequest is not an UpgradeInvokerRequest - * @see #options() () for convenient access to upgrade options without casting - */ - @Nonnull - public UpgradeInvokerRequest invokerRequest() { - return (UpgradeInvokerRequest) invokerRequest; + return (UpgradeOptions) super.options(); } } diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeInvoker.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeInvoker.java index 5c584594268f..7d807a5e4f87 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeInvoker.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeInvoker.java @@ -45,17 +45,14 @@ public class UpgradeInvoker extends LookupInvoker { public static final int BAD_OPERATION = 2; // bad user input or alike public static final int CANCELED = 3; // user canceled - public UpgradeInvoker(Lookup protoLookup) { - this(protoLookup, null); - } - public UpgradeInvoker(Lookup protoLookup, @Nullable Consumer contextConsumer) { super(protoLookup, contextConsumer); } @Override protected UpgradeContext createContext(InvokerRequest invokerRequest) { - return new UpgradeContext(invokerRequest); + return new UpgradeContext( + invokerRequest, (UpgradeOptions) invokerRequest.options().orElse(null)); } @Override @@ -84,12 +81,11 @@ protected int execute(UpgradeContext context) throws Exception { context.reader = LineReaderBuilder.builder().terminal(context.terminal).build(); - UpgradeOptions upgradeOptions = ((UpgradeInvokerRequest) context.invokerRequest).options(); - if (upgradeOptions.goals().isEmpty()) { + if (context.options().goals().isEmpty()) { return badGoalsErrorMessage("No goals specified.", context); } - String goalName = upgradeOptions.goals().get().get(0); + String goalName = context.options().goals().get().get(0); Goal goal = context.goals.get(goalName); if (goal == null) { return badGoalsErrorMessage("Unknown goal: " + goalName, context); @@ -100,7 +96,7 @@ protected int execute(UpgradeContext context) throws Exception { context.logger.error("Goal canceled by user."); return CANCELED; } catch (Exception e) { - if (context.invokerRequest.options().showErrors().orElse(false)) { + if (context.options().showErrors().orElse(false)) { context.logger.error(e.getMessage(), e); } else { context.logger.error(e.getMessage()); diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeInvokerRequest.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeInvokerRequest.java deleted file mode 100644 index add706e2e88b..000000000000 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeInvokerRequest.java +++ /dev/null @@ -1,73 +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.mvnup; - -import java.nio.file.Path; -import java.util.List; -import java.util.Map; - -import org.apache.maven.api.annotations.Nonnull; -import org.apache.maven.api.cli.CoreExtensions; -import org.apache.maven.api.cli.ParserRequest; -import org.apache.maven.api.cli.cisupport.CIInfo; -import org.apache.maven.api.cli.mvnup.UpgradeOptions; -import org.apache.maven.cling.invoker.BaseInvokerRequest; - -import static java.util.Objects.requireNonNull; - -public class UpgradeInvokerRequest extends BaseInvokerRequest { - private final UpgradeOptions options; - - @SuppressWarnings("ParameterNumber") - public UpgradeInvokerRequest( - ParserRequest parserRequest, - boolean parsingFailed, - Path cwd, - Path installationDirectory, - Path userHomeDirectory, - Map userProperties, - Map systemProperties, - Path topDirectory, - Path rootDirectory, - List coreExtensions, - CIInfo ciInfo, - UpgradeOptions options) { - super( - parserRequest, - parsingFailed, - cwd, - installationDirectory, - userHomeDirectory, - userProperties, - systemProperties, - topDirectory, - rootDirectory, - coreExtensions, - ciInfo); - this.options = requireNonNull(options); - } - - /** - * The mandatory Upgrade options. - */ - @Nonnull - public UpgradeOptions options() { - return options; - } -} diff --git a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeParser.java b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeParser.java index 6c902062666c..c87384e5a29b 100644 --- a/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeParser.java +++ b/impl/maven-cli/src/main/java/org/apache/maven/cling/invoker/mvnup/UpgradeParser.java @@ -18,58 +18,17 @@ */ package org.apache.maven.cling.invoker.mvnup; -import java.util.Collections; -import java.util.List; - import org.apache.commons.cli.ParseException; import org.apache.maven.api.cli.Options; -import org.apache.maven.api.cli.mvnup.UpgradeOptions; import org.apache.maven.cling.invoker.BaseParser; public class UpgradeParser extends BaseParser { - - @Override - protected UpgradeOptions emptyOptions() { - try { - return CommonsCliUpgradeOptions.parse(new String[0]); - } catch (ParseException e) { - throw new IllegalArgumentException(e); - } - } - @Override - protected UpgradeInvokerRequest getInvokerRequest(LocalContext context) { - return new UpgradeInvokerRequest( - context.parserRequest, - context.parsingFailed, - context.cwd, - context.installationDirectory, - context.userHomeDirectory, - context.userProperties, - context.systemProperties, - context.topDirectory, - context.rootDirectory, - context.extensions, - context.ciInfo, - (UpgradeOptions) context.options); - } - - @Override - protected List parseCliOptions(LocalContext context) { - return Collections.singletonList(parseUpgradeCliOptions(context.parserRequest.args())); - } - - protected CommonsCliUpgradeOptions parseUpgradeCliOptions(List args) { + protected Options parseCliOptions(LocalContext context) { try { - return CommonsCliUpgradeOptions.parse(args.toArray(new String[0])); + return CommonsCliUpgradeOptions.parse(context.parserRequest.args().toArray(new String[0])); } catch (ParseException e) { throw new IllegalArgumentException("Failed to parse command line options: " + e.getMessage(), e); } } - - @Override - protected Options assembleOptions(List parsedOptions) { - // nothing to assemble, we deal with CLI only - return parsedOptions.get(0); - } } diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/MavenInvokerTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/MavenInvokerTest.java index 698d1c853254..eae08feb2d05 100644 --- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/MavenInvokerTest.java +++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/MavenInvokerTest.java @@ -50,7 +50,7 @@ public class MavenInvokerTest extends MavenInvokerTestSupport { @Override protected Invoker createInvoker(ClassWorld classWorld) { return new MavenInvoker( - ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build()); + ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build(), null); } @Override diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvokerTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvokerTest.java index 86363162805e..56b9a105583c 100644 --- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvokerTest.java +++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvn/resident/ResidentMavenInvokerTest.java @@ -45,7 +45,7 @@ public class ResidentMavenInvokerTest extends MavenInvokerTestSupport { @Override protected Invoker createInvoker(ClassWorld classWorld) { return new ResidentMavenInvoker( - ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build()); + ProtoLookup.builder().addMapping(ClassWorld.class, classWorld).build(), null); } @Override diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/PluginUpgradeCliTest.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/PluginUpgradeCliTest.java index 77302f460821..32ad1473b90a 100644 --- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/PluginUpgradeCliTest.java +++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/PluginUpgradeCliTest.java @@ -185,7 +185,7 @@ void testInterpolationWithPluginsOption() throws ParseException { CommonsCliUpgradeOptions options = CommonsCliUpgradeOptions.parse(args); // Test that interpolation works (even though there's nothing to interpolate here) - UpgradeOptions interpolated = options.interpolate(s -> s); + UpgradeOptions interpolated = (CommonsCliUpgradeOptions) options.interpolate(s -> s); assertTrue(interpolated.plugins().isPresent(), "Interpolated options should preserve --plugins"); assertTrue(interpolated.plugins().get(), "Interpolated --plugins should be true"); diff --git a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/TestUtils.java b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/TestUtils.java index 41bb73d19829..40dff68c44ab 100644 --- a/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/TestUtils.java +++ b/impl/maven-cli/src/test/java/org/apache/maven/cling/invoker/mvnup/goals/TestUtils.java @@ -23,11 +23,11 @@ import java.util.Map; import java.util.Optional; +import org.apache.maven.api.cli.InvokerRequest; import org.apache.maven.api.cli.Logger; import org.apache.maven.api.cli.ParserRequest; import org.apache.maven.api.cli.mvnup.UpgradeOptions; import org.apache.maven.cling.invoker.mvnup.UpgradeContext; -import org.apache.maven.cling.invoker.mvnup.UpgradeInvokerRequest; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -78,7 +78,7 @@ public static UpgradeContext createMockContext(UpgradeOptions options) { * @return a mock UpgradeContext */ public static UpgradeContext createMockContext(Path workingDirectory, UpgradeOptions options) { - UpgradeInvokerRequest request = mock(UpgradeInvokerRequest.class); + InvokerRequest request = mock(InvokerRequest.class); // Mock all required properties for LookupContext constructor when(request.cwd()).thenReturn(workingDirectory); @@ -88,7 +88,7 @@ public static UpgradeContext createMockContext(Path workingDirectory, UpgradeOpt when(request.rootDirectory()).thenReturn(Optional.empty()); when(request.userProperties()).thenReturn(Map.of()); when(request.systemProperties()).thenReturn(Map.of()); - when(request.options()).thenReturn(options); + when(request.options()).thenReturn(Optional.ofNullable(options)); // Mock parserRequest and logger ParserRequest parserRequest = mock(ParserRequest.class); @@ -96,7 +96,7 @@ public static UpgradeContext createMockContext(Path workingDirectory, UpgradeOpt when(request.parserRequest()).thenReturn(parserRequest); when(parserRequest.logger()).thenReturn(logger); - return new UpgradeContext(request); + return new UpgradeContext(request, options); } /**