Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

CLIng diet #1897

Merged
merged 17 commits into from
Nov 13, 2024
1 change: 1 addition & 0 deletions .mvn/maven.config
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-Daether.transport.jdk.httpVersion=HTTP_1_1
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cli;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;

/**
* Defines the contract for a component responsible for executing a Maven tool
* using the information provided in an {@link ExecutorRequest}. This interface is central
* to the execution of Maven commands and builds, but it does not construct nor fully parses arguments.
*
* @since 4.0.0
*/
@Experimental
public interface Executor extends AutoCloseable {
/**
* Invokes the tool application using the provided {@link ExecutorRequest}.
* This method is responsible for executing the command or build
* process based on the information contained in the request.
*
* @param executorRequest the request containing all necessary information for the execution
* @return an integer representing the exit code of the execution (0 typically indicates success)
* @throws ExecutorException if an error occurs during the execution process
*/
int execute(@Nonnull ExecutorRequest executorRequest) throws ExecutorException;

/**
* Closes and disposes of this {@link Executor} instance, releasing any resources it may hold.
* This method is called automatically when using try-with-resources statements.
*
* <p>The default implementation does nothing. Subclasses should override this method
* if they need to perform cleanup operations.</p>
*
* @throws ExecutorException if an error occurs while closing the {@link Executor}
*/
@Override
default void close() throws ExecutorException {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cli;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nullable;
import org.apache.maven.api.services.MavenException;

/**
* Represents an exception that occurs during the execution of a Maven build or command.
* This exception is typically thrown when there are errors during the execution of a Maven
* process, such as wrong cwd, non-existent installation directory, or other runtime issues.
*
* @since 4.0.0
*/
@Experimental
public class ExecutorException extends MavenException {
/**
* Constructs a new {@code InvokerException} with the specified detail message.
*
* @param message the detail message explaining the cause of the exception
*/
public ExecutorException(@Nullable String message) {
super(message);
}

/**
* Constructs a new {@code InvokerException} with the specified detail message and cause.
*
* @param message the detail message explaining the cause of the exception
* @param cause the underlying cause of the exception
*/
public ExecutorException(@Nullable String message, @Nullable Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.api.cli;

import java.nio.file.Path;
import java.util.List;
import java.util.Optional;

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Immutable;
import org.apache.maven.api.annotations.Nonnull;

/**
* Represents a request to execute Maven with command-line arguments.
* This interface encapsulates all the necessary information needed to execute
* Maven command with arguments. The arguments were not parsed, they are just passed over
* to executed tool.
*
* @since 4.0.0
*/
@Immutable
@Experimental
public interface ExecutorRequest {
/**
* The parser request this instance was created from.
*/
@Nonnull
ParserRequest parserRequest();

/**
* Returns the current working directory for the Maven execution.
* This is typically the directory from which Maven was invoked.
*
* @return the current working directory path
*/
@Nonnull
Path cwd();

/**
* Returns the Maven installation directory.
* This is usually set by the Maven launcher script using the "maven.home" system property.
*
* @return the Maven installation directory path
*/
@Nonnull
Path installationDirectory();

/**
* Returns the user's home directory.
* This is typically obtained from the "user.home" system property.
*
* @return the user's home directory path
*/
@Nonnull
Path userHomeDirectory();

/**
* Returns the list of extra JVM arguments to be passed to the forked process.
* These arguments allow for customization of the JVM environment in which tool will run.
* This property is used ONLY by executors and invokers that spawn a new JVM.
*
* @return an Optional containing the list of extra JVM arguments, or empty if not specified
*/
@Nonnull
Optional<List<String>> jvmArguments();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,16 @@
/**
* Defines the contract for a component responsible for invoking a Maven application
* using the information provided in an {@link InvokerRequest}. This interface is central
* to the execution of Maven commands and builds.
* to the construction and invocation of Maven commands and builds, and it fully parses arguments.
*
* <p>The Invoker is designed to be flexible, allowing for different implementations
* that can handle various types of {@link InvokerRequest InvokerRequests}. It also implements
* {@link AutoCloseable} to ensure proper resource management.</p>
*
* @param <R> The specific type of {@link InvokerRequest} this {@code Invoker} can handle, extending {@link InvokerRequest}
*
* @since 4.0.0
*/
@Experimental
public interface Invoker<R extends InvokerRequest<? extends Options>> extends AutoCloseable {
public interface Invoker extends AutoCloseable {
/**
* Invokes the Maven application using the provided {@link InvokerRequest}.
* This method is responsible for executing the Maven command or build
Expand All @@ -45,7 +43,7 @@ public interface Invoker<R extends InvokerRequest<? extends Options>> extends Au
* @return an integer representing the exit code of the invocation (0 typically indicates success)
* @throws InvokerException if an error occurs during the invocation process
*/
int invoke(@Nonnull R invokerRequest) throws InvokerException;
int invoke(@Nonnull InvokerRequest invokerRequest) throws InvokerException;

/**
* Closes and disposes of this {@link Invoker} instance, releasing any resources it may hold.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,21 @@ public InvokerException(@Nullable String message) {
public InvokerException(@Nullable String message, @Nullable Throwable cause) {
super(message, cause);
}

/**
* Exception for intentional exit: No message or anything will be displayed, just the
* carried exit code will be returned from invoker {@link Invoker#invoke(InvokerRequest)} method.
*/
public static final class ExitException extends InvokerException {
private final int exitCode;

public ExitException(int exitCode) {
super("EXIT");
this.exitCode = exitCode;
}

public int getExitCode() {
return exitCode;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,22 +33,14 @@
import org.apache.maven.api.services.MessageBuilderFactory;

/**
* Represents a Maven execution request, encapsulating all necessary information
* for invoking a Maven build or command.
*
* @param <O> the type of {@link Options} used for this request, extending the base {@link Options} interface
* Represents a Maven invocation request, encapsulating all necessary information
* for invoking a Maven build or command. Arguments are parsed and exposed via methods.
*
* @since 4.0.0
*/
@Immutable
@Experimental
public interface InvokerRequest<O extends Options> {
/**
* The parser request this instance was created from.
*/
@Nonnull
ParserRequest parserRequest();

public interface InvokerRequest extends ExecutorRequest {
/**
* Shorthand for {@link Logger} to use.
*/
Expand All @@ -70,33 +62,6 @@ default Lookup lookup() {
return parserRequest().lookup();
}

/**
* Returns the current working directory for the Maven execution.
* This is typically the directory from which Maven was invoked.
*
* @return the current working directory path
*/
@Nonnull
Path cwd();

/**
* Returns the Maven installation directory.
* This is usually set by the Maven launcher script using the "maven.home" system property.
*
* @return the Maven installation directory path
*/
@Nonnull
Path installationDirectory();

/**
* Returns the user's home directory.
* This is typically obtained from the "user.home" system property.
*
* @return the user's home directory path
*/
@Nonnull
Path userHomeDirectory();

/**
* Returns a map of user-defined properties for the Maven execution.
* These properties can be set using the -D command-line option.
Expand Down Expand Up @@ -172,5 +137,5 @@ default Lookup lookup() {
* @return the options object
*/
@Nonnull
O options();
Options options();
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,47 +22,35 @@

import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.services.MessageBuilderFactory;

/**
* Defines the contract for parsing Maven command-line arguments and creating an InvokerRequest.
* This interface is responsible for interpreting the command-line input and constructing
* the appropriate {@link InvokerRequest} object.
*
* @param <R> the type of {@link InvokerRequest} produced by this parser, extending {@link InvokerRequest}
* Defines the contract for parsing Maven command-line arguments and creating an execution or invoker requests.
*
* @since 4.0.0
*/
@Experimental
public interface Parser<R extends InvokerRequest<? extends Options>> {
public interface Parser {
/**
* Parses the given Maven arguments to create an InvokerRequest.
* This is a convenience method that internally creates a ParserRequest using
* {@link ParserRequest#mvn(String[], Logger, MessageBuilderFactory)}.
* Parses the given ParserRequest to create an {@link ExecutorRequest}.
* This method does not interpret tool arguments.
*
* @param args the command-line arguments
* @param logger the logger to use during parsing
* @param messageBuilderFactory the factory for creating message builders
* @return the parsed InvokerRequest
* @throws ParserException if there's an error during parsing of the command or arguments
* @param parserRequest the request containing all necessary information for parsing
* @return the parsed executor request
* @throws ParserException if there's an error during parsing of the request
* @throws IOException if there's an I/O error during the parsing process
*/
@Nonnull
default R mvn(@Nonnull String[] args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory)
throws ParserException, IOException {
return parse(ParserRequest.mvn(args, logger, messageBuilderFactory).build());
}
ExecutorRequest parseExecution(@Nonnull ParserRequest parserRequest) throws ParserException, IOException;

/**
* Parses the given ParserRequest to create an InvokerRequest.
* This method is responsible for interpreting the contents of the ParserRequest
* and constructing the appropriate InvokerRequest object.
* Parses the given ParserRequest to create an {@link InvokerRequest}.
* This method does interpret tool arguments.
*
* @param parserRequest the request containing all necessary information for parsing
* @return the parsed InvokerRequest
* @return the parsed invoker request
* @throws ParserException if there's an error during parsing of the request
* @throws IOException if there's an I/O error during the parsing process
*/
@Nonnull
R parse(@Nonnull ParserRequest parserRequest) throws ParserException, IOException;
InvokerRequest parseInvocation(@Nonnull ParserRequest parserRequest) throws ParserException, IOException;
}
Loading