mirror of https://github.com/apache/maven.git
[MNG-8283] Maven CLIng smaller bugfixes and improvements (#1772)
This PR adopts CLIng for use in mvnd, and adds several improvements to CLIng overall. Major topics: * ability to pass in per-request Lookup for customization * makes parser request creation a bit friendlier * removes a log of redundancy (same stuff copied over) * ability to alter rootDirectory detection in parsers * resident invoker bugfix * adds UTs for 3 invoker implementations --- https://issues.apache.org/jira/browse/MNG-8283
This commit is contained in:
parent
1f1a0f9a72
commit
533790bb4a
|
@ -26,8 +26,10 @@ import java.util.Map;
|
|||
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;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.services.Lookup;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
|
||||
/**
|
||||
|
@ -38,15 +40,35 @@ import org.apache.maven.api.services.MessageBuilderFactory;
|
|||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Immutable
|
||||
@Experimental
|
||||
public interface InvokerRequest<O extends Options> {
|
||||
/**
|
||||
* Returns the command to be executed.
|
||||
*
|
||||
* @return the command string
|
||||
* The parser request this instance was created from.
|
||||
*/
|
||||
@Nonnull
|
||||
String command();
|
||||
ParserRequest parserRequest();
|
||||
|
||||
/**
|
||||
* Shorthand for {@link Logger} to use.
|
||||
*/
|
||||
default Logger logger() {
|
||||
return parserRequest().logger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand for {@link MessageBuilderFactory}.
|
||||
*/
|
||||
default MessageBuilderFactory messageBuilderFactory() {
|
||||
return parserRequest().messageBuilderFactory();
|
||||
}
|
||||
|
||||
/**
|
||||
* Shorthand for {@link Lookup}.
|
||||
*/
|
||||
default Lookup lookup() {
|
||||
return parserRequest().lookup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current working directory for the Maven execution.
|
||||
|
@ -93,24 +115,6 @@ public interface InvokerRequest<O extends Options> {
|
|||
@Nonnull
|
||||
Map<String, String> systemProperties();
|
||||
|
||||
/**
|
||||
* Returns the logger to be used during the early phases of Maven execution,
|
||||
* before the main Maven logger is initialized.
|
||||
*
|
||||
* @return the early-phase logger
|
||||
*/
|
||||
@Nonnull
|
||||
Logger logger();
|
||||
|
||||
/**
|
||||
* Returns the factory for creating message builders.
|
||||
* Message builders are used for constructing formatted log messages.
|
||||
*
|
||||
* @return the message builder factory
|
||||
*/
|
||||
@Nonnull
|
||||
MessageBuilderFactory messageBuilderFactory();
|
||||
|
||||
/**
|
||||
* Returns the top-level directory of the Maven invocation.
|
||||
* This is typically the directory containing the POM file being executed.
|
||||
|
|
|
@ -196,12 +196,12 @@ public interface Options {
|
|||
*
|
||||
* @param printWriter the PrintWriter to use for output
|
||||
*/
|
||||
default void warnAboutDeprecatedOptions(@Nonnull PrintWriter printWriter) {}
|
||||
default void warnAboutDeprecatedOptions(@Nonnull ParserRequest request, @Nonnull PrintWriter printWriter) {}
|
||||
|
||||
/**
|
||||
* Displays help information for these options.
|
||||
*
|
||||
* @param printWriter the PrintWriter to use for output
|
||||
*/
|
||||
void displayHelp(@Nonnull String command, @Nonnull PrintWriter printWriter);
|
||||
void displayHelp(@Nonnull ParserRequest request, @Nonnull PrintWriter printWriter);
|
||||
}
|
||||
|
|
|
@ -36,10 +36,10 @@ import org.apache.maven.api.services.MessageBuilderFactory;
|
|||
@Experimental
|
||||
public interface Parser<R extends InvokerRequest<? extends Options>> {
|
||||
/**
|
||||
* Parses the given command and arguments to create an InvokerRequest.
|
||||
* This is a convenience method that internally creates a ParserRequest.
|
||||
* 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)}.
|
||||
*
|
||||
* @param command the Maven command to execute
|
||||
* @param args the command-line arguments
|
||||
* @param logger the logger to use during parsing
|
||||
* @param messageBuilderFactory the factory for creating message builders
|
||||
|
@ -48,14 +48,9 @@ public interface Parser<R extends InvokerRequest<? extends Options>> {
|
|||
* @throws IOException if there's an I/O error during the parsing process
|
||||
*/
|
||||
@Nonnull
|
||||
default R parse(
|
||||
@Nonnull String command,
|
||||
@Nonnull String[] args,
|
||||
@Nonnull Logger logger,
|
||||
@Nonnull MessageBuilderFactory messageBuilderFactory)
|
||||
default R mvn(@Nonnull String[] args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory)
|
||||
throws ParserException, IOException {
|
||||
return parse(ParserRequest.builder(command, args, logger, messageBuilderFactory)
|
||||
.build());
|
||||
return parse(ParserRequest.mvn(args, logger, messageBuilderFactory).build());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -21,10 +21,17 @@ package org.apache.maven.api.cli;
|
|||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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;
|
||||
import org.apache.maven.api.annotations.Nullable;
|
||||
import org.apache.maven.api.services.Lookup;
|
||||
import org.apache.maven.api.services.LookupException;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
@ -36,16 +43,31 @@ import static java.util.Objects.requireNonNull;
|
|||
*
|
||||
* @since 4.0.0
|
||||
*/
|
||||
@Immutable
|
||||
@Experimental
|
||||
public interface ParserRequest {
|
||||
String MVN_CMD = "mvn";
|
||||
String MVN_NAME = "Maven";
|
||||
|
||||
String MVNENC_CMD = "mvnenc";
|
||||
String MVNENC_NAME = "Maven Password Encrypting Tool";
|
||||
|
||||
/**
|
||||
* Returns the Maven command to be executed.
|
||||
* Returns the Maven command to be executed. This command is used in some invokers (ie forked) but also to
|
||||
* present help to user.
|
||||
*
|
||||
* @return the command string
|
||||
*/
|
||||
@Nonnull
|
||||
String command();
|
||||
|
||||
/**
|
||||
* Returns the Maven command name (ie "Maven"). This string is used in some invokers to complete error messages.
|
||||
*
|
||||
* @return the command (human) name
|
||||
*/
|
||||
String commandName();
|
||||
|
||||
/**
|
||||
* Returns the logger to be used during the parsing process.
|
||||
*
|
||||
|
@ -65,10 +87,18 @@ public interface ParserRequest {
|
|||
/**
|
||||
* Returns the command-line arguments to be parsed.
|
||||
*
|
||||
* @return an array of argument strings
|
||||
* @return a list of argument strings
|
||||
*/
|
||||
@Nonnull
|
||||
String[] args();
|
||||
List<String> args();
|
||||
|
||||
/**
|
||||
* Per-request {@link Lookup} for customization.
|
||||
*
|
||||
* @return a lookup possibly with custom components
|
||||
*/
|
||||
@Nonnull
|
||||
Lookup lookup();
|
||||
|
||||
/**
|
||||
* Returns the current working directory for the Maven execution.
|
||||
|
@ -124,10 +154,67 @@ public interface ParserRequest {
|
|||
@Nullable
|
||||
OutputStream err();
|
||||
|
||||
/**
|
||||
* Creates a new Builder instance for constructing a Maven ParserRequest.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
* @param logger the logger to be used during parsing
|
||||
* @param messageBuilderFactory the factory for creating message builders
|
||||
* @return a new Builder instance
|
||||
*/
|
||||
@Nonnull
|
||||
static Builder mvn(
|
||||
@Nonnull String[] args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory) {
|
||||
return mvn(Arrays.asList(args), logger, messageBuilderFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Builder instance for constructing a Maven ParserRequest.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
* @param logger the logger to be used during parsing
|
||||
* @param messageBuilderFactory the factory for creating message builders
|
||||
* @return a new Builder instance
|
||||
*/
|
||||
@Nonnull
|
||||
static Builder mvn(
|
||||
@Nonnull List<String> args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory) {
|
||||
return builder(MVN_CMD, MVN_NAME, args, logger, messageBuilderFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Builder instance for constructing a Maven Encrypting Tool ParserRequest.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
* @param logger the logger to be used during parsing
|
||||
* @param messageBuilderFactory the factory for creating message builders
|
||||
* @return a new Builder instance
|
||||
*/
|
||||
@Nonnull
|
||||
static Builder mvnenc(
|
||||
@Nonnull String[] args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory) {
|
||||
return mvnenc(Arrays.asList(args), logger, messageBuilderFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Builder instance for constructing a Maven Encrypting Tool ParserRequest.
|
||||
*
|
||||
* @param args the command-line arguments
|
||||
* @param logger the logger to be used during parsing
|
||||
* @param messageBuilderFactory the factory for creating message builders
|
||||
* @return a new Builder instance
|
||||
*/
|
||||
@Nonnull
|
||||
static Builder mvnenc(
|
||||
@Nonnull List<String> args, @Nonnull Logger logger, @Nonnull MessageBuilderFactory messageBuilderFactory) {
|
||||
return builder(MVNENC_CMD, MVNENC_NAME, args, logger, messageBuilderFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new Builder instance for constructing a ParserRequest.
|
||||
*
|
||||
* @param command the Maven command to be executed
|
||||
* @param commandName the Maven command Name to be executed
|
||||
* @param args the command-line arguments
|
||||
* @param logger the logger to be used during parsing
|
||||
* @param messageBuilderFactory the factory for creating message builders
|
||||
|
@ -136,17 +223,20 @@ public interface ParserRequest {
|
|||
@Nonnull
|
||||
static Builder builder(
|
||||
@Nonnull String command,
|
||||
@Nonnull String[] args,
|
||||
@Nonnull String commandName,
|
||||
@Nonnull List<String> args,
|
||||
@Nonnull Logger logger,
|
||||
@Nonnull MessageBuilderFactory messageBuilderFactory) {
|
||||
return new Builder(command, args, logger, messageBuilderFactory);
|
||||
return new Builder(command, commandName, args, logger, messageBuilderFactory);
|
||||
}
|
||||
|
||||
class Builder {
|
||||
private final String command;
|
||||
private final String[] args;
|
||||
private final String commandName;
|
||||
private final List<String> args;
|
||||
private final Logger logger;
|
||||
private final MessageBuilderFactory messageBuilderFactory;
|
||||
private Lookup lookup = EMPTY_LOOKUP;
|
||||
private Path cwd;
|
||||
private Path mavenHome;
|
||||
private Path userHome;
|
||||
|
@ -154,13 +244,24 @@ public interface ParserRequest {
|
|||
private OutputStream out;
|
||||
private OutputStream err;
|
||||
|
||||
private Builder(String command, String[] args, Logger logger, MessageBuilderFactory messageBuilderFactory) {
|
||||
this.command = requireNonNull(command, "appName");
|
||||
private Builder(
|
||||
String command,
|
||||
String commandName,
|
||||
List<String> args,
|
||||
Logger logger,
|
||||
MessageBuilderFactory messageBuilderFactory) {
|
||||
this.command = requireNonNull(command, "command");
|
||||
this.commandName = requireNonNull(commandName, "commandName");
|
||||
this.args = requireNonNull(args, "args");
|
||||
this.logger = requireNonNull(logger, "logger");
|
||||
this.messageBuilderFactory = requireNonNull(messageBuilderFactory, "messageBuilderFactory");
|
||||
}
|
||||
|
||||
public Builder lookup(@Nonnull Lookup lookup) {
|
||||
this.lookup = requireNonNull(lookup);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder cwd(Path cwd) {
|
||||
this.cwd = cwd;
|
||||
return this;
|
||||
|
@ -193,15 +294,28 @@ public interface ParserRequest {
|
|||
|
||||
public ParserRequest build() {
|
||||
return new ParserRequestImpl(
|
||||
command, args, logger, messageBuilderFactory, cwd, mavenHome, userHome, in, out, err);
|
||||
command,
|
||||
commandName,
|
||||
args,
|
||||
logger,
|
||||
messageBuilderFactory,
|
||||
lookup,
|
||||
cwd,
|
||||
mavenHome,
|
||||
userHome,
|
||||
in,
|
||||
out,
|
||||
err);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
private static class ParserRequestImpl implements ParserRequest {
|
||||
private final String command;
|
||||
private final String commandName;
|
||||
private final Logger logger;
|
||||
private final MessageBuilderFactory messageBuilderFactory;
|
||||
private final String[] args;
|
||||
private final List<String> args;
|
||||
private final Lookup lookup;
|
||||
private final Path cwd;
|
||||
private final Path mavenHome;
|
||||
private final Path userHome;
|
||||
|
@ -211,19 +325,23 @@ public interface ParserRequest {
|
|||
|
||||
private ParserRequestImpl(
|
||||
String command,
|
||||
String[] args,
|
||||
String commandName,
|
||||
List<String> args,
|
||||
Logger logger,
|
||||
MessageBuilderFactory messageBuilderFactory,
|
||||
Lookup lookup,
|
||||
Path cwd,
|
||||
Path mavenHome,
|
||||
Path userHome,
|
||||
InputStream in,
|
||||
OutputStream out,
|
||||
OutputStream err) {
|
||||
this.command = requireNonNull(command, "appName");
|
||||
this.args = requireNonNull(args, "args");
|
||||
this.command = requireNonNull(command, "command");
|
||||
this.commandName = requireNonNull(commandName, "commandName");
|
||||
this.args = List.copyOf(requireNonNull(args, "args"));
|
||||
this.logger = requireNonNull(logger, "logger");
|
||||
this.messageBuilderFactory = requireNonNull(messageBuilderFactory, "messageBuilderFactory");
|
||||
this.lookup = requireNonNull(lookup, "lookup");
|
||||
this.cwd = cwd;
|
||||
this.mavenHome = mavenHome;
|
||||
this.userHome = userHome;
|
||||
|
@ -237,6 +355,11 @@ public interface ParserRequest {
|
|||
return command;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String commandName() {
|
||||
return commandName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger logger() {
|
||||
return logger;
|
||||
|
@ -248,10 +371,15 @@ public interface ParserRequest {
|
|||
}
|
||||
|
||||
@Override
|
||||
public String[] args() {
|
||||
public List<String> args() {
|
||||
return args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Lookup lookup() {
|
||||
return lookup;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path cwd() {
|
||||
return cwd;
|
||||
|
@ -282,5 +410,37 @@ public interface ParserRequest {
|
|||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
private static final Lookup EMPTY_LOOKUP = new Lookup() {
|
||||
@Override
|
||||
public <T> T lookup(Class<T> type) {
|
||||
throw new LookupException("empty lookup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T lookup(Class<T> type, String name) {
|
||||
throw new LookupException("empty lookup");
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> lookupOptional(Class<T> type) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Optional<T> lookupOptional(Class<T> type, String name) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> List<T> lookupList(Class<T> type) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Map<String, T> lookupMap(Class<T> type) {
|
||||
return Map.of();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,8 @@ import java.io.IOException;
|
|||
import org.apache.maven.api.cli.Invoker;
|
||||
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.Parser;
|
||||
import org.apache.maven.api.cli.ParserException;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
import org.apache.maven.cling.invoker.ProtoLogger;
|
||||
import org.apache.maven.jline.JLineMessageBuilderFactory;
|
||||
import org.apache.maven.jline.MessageUtils;
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
|
||||
|
@ -44,26 +39,24 @@ import static java.util.Objects.requireNonNull;
|
|||
public abstract class ClingSupport<O extends Options, R extends InvokerRequest<O>> {
|
||||
static final String CORE_CLASS_REALM_ID = "plexus.core";
|
||||
|
||||
protected final String command;
|
||||
protected final ClassWorld classWorld;
|
||||
protected final boolean classWorldManaged;
|
||||
|
||||
/**
|
||||
* Ctor that creates "managed" ClassWorld. This constructor is not used in "normal" circumstances.
|
||||
*/
|
||||
public ClingSupport(String command) {
|
||||
this(command, new ClassWorld(CORE_CLASS_REALM_ID, Thread.currentThread().getContextClassLoader()), true);
|
||||
public ClingSupport() {
|
||||
this(new ClassWorld(CORE_CLASS_REALM_ID, Thread.currentThread().getContextClassLoader()), true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ctor to be used when running in ClassWorlds Launcher.
|
||||
*/
|
||||
public ClingSupport(String command, ClassWorld classWorld) {
|
||||
this(command, classWorld, false);
|
||||
public ClingSupport(ClassWorld classWorld) {
|
||||
this(classWorld, false);
|
||||
}
|
||||
|
||||
protected ClingSupport(String command, ClassWorld classWorld, boolean classWorldManaged) {
|
||||
this.command = requireNonNull(command, "command");
|
||||
private ClingSupport(ClassWorld classWorld, boolean classWorldManaged) {
|
||||
this.classWorld = requireNonNull(classWorld);
|
||||
this.classWorldManaged = classWorldManaged;
|
||||
}
|
||||
|
@ -75,7 +68,7 @@ public abstract class ClingSupport<O extends Options, R extends InvokerRequest<O
|
|||
MessageUtils.systemInstall();
|
||||
MessageUtils.registerShutdownHook();
|
||||
try (Invoker<R> invoker = createInvoker()) {
|
||||
return invoker.invoke(createParser().parse(command, args, createLogger(), createMessageBuilderFactory()));
|
||||
return invoker.invoke(parseArguments(args));
|
||||
} catch (ParserException e) {
|
||||
System.err.println(e.getMessage());
|
||||
return 1;
|
||||
|
@ -94,13 +87,5 @@ public abstract class ClingSupport<O extends Options, R extends InvokerRequest<O
|
|||
|
||||
protected abstract Invoker<R> createInvoker();
|
||||
|
||||
protected abstract Parser<R> createParser();
|
||||
|
||||
protected Logger createLogger() {
|
||||
return new ProtoLogger();
|
||||
}
|
||||
|
||||
protected MessageBuilderFactory createMessageBuilderFactory() {
|
||||
return new JLineMessageBuilderFactory();
|
||||
}
|
||||
protected abstract R parseArguments(String[] args) throws ParserException, IOException;
|
||||
}
|
||||
|
|
|
@ -21,26 +21,26 @@ package org.apache.maven.cling;
|
|||
import java.io.IOException;
|
||||
|
||||
import org.apache.maven.api.cli.Invoker;
|
||||
import org.apache.maven.api.cli.Parser;
|
||||
import org.apache.maven.api.cli.ParserException;
|
||||
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.cling.invoker.ProtoLogger;
|
||||
import org.apache.maven.cling.invoker.ProtoLookup;
|
||||
import org.apache.maven.cling.invoker.mvn.local.DefaultLocalMavenInvoker;
|
||||
import org.apache.maven.cling.invoker.mvn.local.DefaultLocalMavenParser;
|
||||
import org.apache.maven.jline.JLineMessageBuilderFactory;
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
|
||||
/**
|
||||
* Maven CLI "new-gen".
|
||||
*/
|
||||
public class MavenCling extends ClingSupport<MavenOptions, MavenInvokerRequest<MavenOptions>> {
|
||||
public static final String NAME = "mvn";
|
||||
|
||||
/**
|
||||
* "Normal" Java entry point. Note: Maven uses ClassWorld Launcher and this entry point is NOT used under normal
|
||||
* circumstances.
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
int exitCode = new MavenCling(NAME).run(args);
|
||||
int exitCode = new MavenCling().run(args);
|
||||
System.exit(exitCode);
|
||||
}
|
||||
|
||||
|
@ -48,15 +48,15 @@ public class MavenCling extends ClingSupport<MavenOptions, MavenInvokerRequest<M
|
|||
* ClassWorld Launcher "enhanced" entry point: returning exitCode and accepts Class World.
|
||||
*/
|
||||
public static int main(String[] args, ClassWorld world) throws IOException {
|
||||
return new MavenCling(NAME, world).run(args);
|
||||
return new MavenCling(world).run(args);
|
||||
}
|
||||
|
||||
public MavenCling(String command) {
|
||||
super(command);
|
||||
public MavenCling() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MavenCling(String command, ClassWorld classWorld) {
|
||||
super(command, classWorld);
|
||||
public MavenCling(ClassWorld classWorld) {
|
||||
super(classWorld);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +66,7 @@ public class MavenCling extends ClingSupport<MavenOptions, MavenInvokerRequest<M
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Parser<MavenInvokerRequest<MavenOptions>> createParser() {
|
||||
return new DefaultLocalMavenParser();
|
||||
protected MavenInvokerRequest<MavenOptions> parseArguments(String[] args) throws ParserException, IOException {
|
||||
return new DefaultLocalMavenParser().mvn(args, new ProtoLogger(), new JLineMessageBuilderFactory());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,26 +21,27 @@ package org.apache.maven.cling;
|
|||
import java.io.IOException;
|
||||
|
||||
import org.apache.maven.api.cli.Invoker;
|
||||
import org.apache.maven.api.cli.Parser;
|
||||
import org.apache.maven.api.cli.ParserException;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.mvnenc.EncryptInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvnenc.EncryptOptions;
|
||||
import org.apache.maven.cling.invoker.ProtoLogger;
|
||||
import org.apache.maven.cling.invoker.ProtoLookup;
|
||||
import org.apache.maven.cling.invoker.mvnenc.DefaultEncryptInvoker;
|
||||
import org.apache.maven.cling.invoker.mvnenc.DefaultEncryptParser;
|
||||
import org.apache.maven.jline.JLineMessageBuilderFactory;
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
|
||||
/**
|
||||
* Maven encrypt CLI "new-gen".
|
||||
*/
|
||||
public class MavenEncCling extends ClingSupport<EncryptOptions, EncryptInvokerRequest> {
|
||||
public static final String NAME = "mvnenc";
|
||||
|
||||
/**
|
||||
* "Normal" Java entry point. Note: Maven uses ClassWorld Launcher and this entry point is NOT used under normal
|
||||
* circumstances.
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
int exitCode = new MavenEncCling(NAME).run(args);
|
||||
int exitCode = new MavenEncCling().run(args);
|
||||
System.exit(exitCode);
|
||||
}
|
||||
|
||||
|
@ -48,15 +49,15 @@ public class MavenEncCling extends ClingSupport<EncryptOptions, EncryptInvokerRe
|
|||
* ClassWorld Launcher "enhanced" entry point: returning exitCode and accepts Class World.
|
||||
*/
|
||||
public static int main(String[] args, ClassWorld world) throws IOException {
|
||||
return new MavenEncCling(NAME, world).run(args);
|
||||
return new MavenEncCling(world).run(args);
|
||||
}
|
||||
|
||||
public MavenEncCling(String command) {
|
||||
super(command);
|
||||
public MavenEncCling() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MavenEncCling(String command, ClassWorld classWorld) {
|
||||
super(command, classWorld);
|
||||
public MavenEncCling(ClassWorld classWorld) {
|
||||
super(classWorld);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,7 +67,9 @@ public class MavenEncCling extends ClingSupport<EncryptOptions, EncryptInvokerRe
|
|||
}
|
||||
|
||||
@Override
|
||||
protected Parser<EncryptInvokerRequest> createParser() {
|
||||
return new DefaultEncryptParser();
|
||||
protected EncryptInvokerRequest parseArguments(String[] args) throws ParserException, IOException {
|
||||
return new DefaultEncryptParser()
|
||||
.parse(ParserRequest.mvnenc(args, new ProtoLogger(), new JLineMessageBuilderFactory())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,22 +28,19 @@ import java.util.Optional;
|
|||
import org.apache.maven.api.annotations.Nonnull;
|
||||
import org.apache.maven.api.annotations.Nullable;
|
||||
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.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
public abstract class BaseInvokerRequest<T extends Options> implements InvokerRequest<T> {
|
||||
private final String command;
|
||||
private final ParserRequest parserRequest;
|
||||
private final Path cwd;
|
||||
private final Path installationDirectory;
|
||||
private final Path userHomeDirectory;
|
||||
private final Map<String, String> userProperties;
|
||||
private final Map<String, String> systemProperties;
|
||||
private final Logger logger;
|
||||
private final MessageBuilderFactory messageBuilderFactory;
|
||||
private final Path topDirectory;
|
||||
private final Path rootDirectory;
|
||||
|
||||
|
@ -54,28 +51,24 @@ public abstract class BaseInvokerRequest<T extends Options> implements InvokerRe
|
|||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
public BaseInvokerRequest(
|
||||
@Nonnull String command,
|
||||
@Nonnull ParserRequest parserRequest,
|
||||
@Nonnull Path cwd,
|
||||
@Nonnull Path installationDirectory,
|
||||
@Nonnull Path userHomeDirectory,
|
||||
@Nonnull Map<String, String> userProperties,
|
||||
@Nonnull Map<String, String> systemProperties,
|
||||
@Nonnull Logger logger,
|
||||
@Nonnull MessageBuilderFactory messageBuilderFactory,
|
||||
@Nonnull Path topDirectory,
|
||||
@Nullable Path rootDirectory,
|
||||
@Nullable InputStream in,
|
||||
@Nullable OutputStream out,
|
||||
@Nullable OutputStream err,
|
||||
@Nullable List<CoreExtension> coreExtensions) {
|
||||
this.command = requireNonNull(command);
|
||||
this.parserRequest = requireNonNull(parserRequest);
|
||||
this.cwd = requireNonNull(cwd);
|
||||
this.installationDirectory = requireNonNull(installationDirectory);
|
||||
this.userHomeDirectory = requireNonNull(userHomeDirectory);
|
||||
this.userProperties = requireNonNull(userProperties);
|
||||
this.systemProperties = requireNonNull(systemProperties);
|
||||
this.logger = requireNonNull(logger);
|
||||
this.messageBuilderFactory = requireNonNull(messageBuilderFactory);
|
||||
this.topDirectory = requireNonNull(topDirectory);
|
||||
this.rootDirectory = rootDirectory;
|
||||
|
||||
|
@ -86,8 +79,8 @@ public abstract class BaseInvokerRequest<T extends Options> implements InvokerRe
|
|||
}
|
||||
|
||||
@Override
|
||||
public String command() {
|
||||
return command;
|
||||
public ParserRequest parserRequest() {
|
||||
return parserRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -115,16 +108,6 @@ public abstract class BaseInvokerRequest<T extends Options> implements InvokerRe
|
|||
return systemProperties;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Logger logger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MessageBuilderFactory messageBuilderFactory() {
|
||||
return messageBuilderFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path topDirectory() {
|
||||
return topDirectory;
|
||||
|
|
|
@ -23,10 +23,9 @@ import javax.xml.stream.XMLStreamException;
|
|||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.FileSystems;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
@ -39,7 +38,6 @@ import java.util.Set;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.apache.maven.api.Constants;
|
||||
import org.apache.maven.api.annotations.Nullable;
|
||||
import org.apache.maven.api.cli.InvokerRequest;
|
||||
import org.apache.maven.api.cli.Options;
|
||||
import org.apache.maven.api.cli.Parser;
|
||||
|
@ -69,41 +67,20 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
|
||||
// the basics
|
||||
HashMap<String, String> overrides = new HashMap<>();
|
||||
FileSystem fileSystem = requireNonNull(getFileSystem(parserRequest));
|
||||
Path cwd = requireNonNull(getCwd(parserRequest, fileSystem, overrides));
|
||||
Path installationDirectory = requireNonNull(getInstallationDirectory(parserRequest, fileSystem, overrides));
|
||||
Path userHomeDirectory = requireNonNull(getUserHomeDirectory(parserRequest, fileSystem, overrides));
|
||||
Path cwd = requireNonNull(getCwd(parserRequest, overrides));
|
||||
Path installationDirectory = requireNonNull(getInstallationDirectory(parserRequest, overrides));
|
||||
Path userHomeDirectory = requireNonNull(getUserHomeDirectory(parserRequest, overrides));
|
||||
|
||||
// top/root
|
||||
Path topDirectory = getCanonicalPath(requireNonNull(getTopDirectory(parserRequest, cwd)));
|
||||
RootLocator rootLocator =
|
||||
ServiceLoader.load(RootLocator.class).iterator().next();
|
||||
@Nullable Path rootDirectory = rootLocator.findRoot(topDirectory);
|
||||
|
||||
// TODO: multiModuleProjectDirectory vs rootDirectory?
|
||||
// fallback if no root? otherwise make sure they are same?
|
||||
Path mmpd = System.getProperty("maven.multiModuleProjectDirectory") == null
|
||||
? null
|
||||
: getCanonicalPath(cwd.resolve(requireNonNull(
|
||||
System.getProperty("maven.multiModuleProjectDirectory"),
|
||||
"maven.multiModuleProjectDirectory is not set")));
|
||||
if (rootDirectory == null) {
|
||||
parserRequest.logger().warn(rootLocator.getNoRootMessage());
|
||||
rootDirectory = requireNonNull(
|
||||
mmpd, "maven.multiModuleProjectDirectory is not set and rootDirectory was not discovered");
|
||||
} else {
|
||||
rootDirectory = getCanonicalPath(rootDirectory);
|
||||
if (mmpd != null && !Objects.equals(rootDirectory, mmpd)) {
|
||||
parserRequest.logger().warn("Project root directory and multiModuleProjectDirectory are not aligned");
|
||||
}
|
||||
}
|
||||
Path topDirectory = requireNonNull(getTopDirectory(parserRequest, cwd));
|
||||
Path rootDirectory = requireNonNull(getRootDirectory(parserRequest, cwd, topDirectory));
|
||||
|
||||
// options
|
||||
List<O> parsedOptions = parseCliOptions(rootDirectory, parserRequest.args());
|
||||
|
||||
// warn about deprecated options
|
||||
parsedOptions.forEach(o -> o.warnAboutDeprecatedOptions(
|
||||
new PrintWriter(parserRequest.out() != null ? parserRequest.out() : System.out, true)));
|
||||
parserRequest, new PrintWriter(parserRequest.out() != null ? parserRequest.out() : System.out, true)));
|
||||
|
||||
// assemble options if needed
|
||||
O options = assembleOptions(parsedOptions);
|
||||
|
@ -113,7 +90,8 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
Map<String, String> paths = new HashMap<>();
|
||||
paths.put("session.topDirectory", topDirectory.toString());
|
||||
paths.put("session.rootDirectory", rootDirectory.toString());
|
||||
Map<String, String> userProperties = populateUserProperties(systemProperties, fileSystem, paths, options);
|
||||
Map<String, String> userProperties =
|
||||
populateUserProperties(systemProperties, installationDirectory, paths, options);
|
||||
|
||||
// options: interpolate
|
||||
Options interpolatedOptions = options.interpolate(Arrays.asList(paths, systemProperties, userProperties));
|
||||
|
@ -121,13 +99,13 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
// core extensions
|
||||
ArrayList<CoreExtension> extensions = new ArrayList<>();
|
||||
String installationExtensionsFile = userProperties.get(Constants.MAVEN_INSTALLATION_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptor(installationExtensionsFile, fileSystem));
|
||||
extensions.addAll(readCoreExtensionsDescriptor(installationExtensionsFile, installationDirectory));
|
||||
|
||||
String projectExtensionsFile = userProperties.get(Constants.MAVEN_PROJECT_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptor(projectExtensionsFile, fileSystem));
|
||||
extensions.addAll(readCoreExtensionsDescriptor(projectExtensionsFile, cwd));
|
||||
|
||||
String userExtensionsFile = userProperties.get(Constants.MAVEN_USER_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptor(userExtensionsFile, fileSystem));
|
||||
extensions.addAll(readCoreExtensionsDescriptor(userExtensionsFile, userHomeDirectory));
|
||||
|
||||
return getInvokerRequest(
|
||||
parserRequest,
|
||||
|
@ -155,23 +133,18 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
ArrayList<CoreExtension> extensions,
|
||||
Options options);
|
||||
|
||||
protected FileSystem getFileSystem(ParserRequest parserRequest) throws ParserException, IOException {
|
||||
return parserRequest.cwd() != null ? parserRequest.cwd().getFileSystem() : FileSystems.getDefault();
|
||||
}
|
||||
|
||||
protected Path getCwd(ParserRequest parserRequest, FileSystem fileSystem, Map<String, String> overrides)
|
||||
throws ParserException {
|
||||
protected Path getCwd(ParserRequest parserRequest, Map<String, String> overrides) throws ParserException {
|
||||
if (parserRequest.cwd() != null) {
|
||||
Path result = getCanonicalPath(parserRequest.cwd());
|
||||
overrides.put("user.dir", result.toString());
|
||||
return result;
|
||||
} else {
|
||||
return getCanonicalPath(fileSystem.getPath(System.getProperty("user.dir")));
|
||||
return getCanonicalPath(Paths.get(System.getProperty("user.dir")));
|
||||
}
|
||||
}
|
||||
|
||||
protected Path getInstallationDirectory(
|
||||
ParserRequest parserRequest, FileSystem fileSystem, Map<String, String> overrides) throws ParserException {
|
||||
protected Path getInstallationDirectory(ParserRequest parserRequest, Map<String, String> overrides)
|
||||
throws ParserException {
|
||||
Path result;
|
||||
if (parserRequest.mavenHome() != null) {
|
||||
result = getCanonicalPath(parserRequest.mavenHome());
|
||||
|
@ -181,21 +154,21 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
if (mavenHome == null) {
|
||||
throw new ParserException("local mode requires " + Constants.MAVEN_HOME + " Java System Property set");
|
||||
}
|
||||
result = getCanonicalPath(fileSystem.getPath(mavenHome));
|
||||
result = getCanonicalPath(Paths.get(mavenHome));
|
||||
}
|
||||
// TODO: we still do this but would be cool if this becomes unneeded
|
||||
System.setProperty(Constants.MAVEN_HOME, result.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Path getUserHomeDirectory(
|
||||
ParserRequest parserRequest, FileSystem fileSystem, Map<String, String> overrides) throws ParserException {
|
||||
protected Path getUserHomeDirectory(ParserRequest parserRequest, Map<String, String> overrides)
|
||||
throws ParserException {
|
||||
if (parserRequest.userHome() != null) {
|
||||
Path result = getCanonicalPath(parserRequest.userHome());
|
||||
overrides.put("user.home", result.toString());
|
||||
return result;
|
||||
} else {
|
||||
return getCanonicalPath(fileSystem.getPath(System.getProperty("user.home")));
|
||||
return getCanonicalPath(Paths.get(System.getProperty("user.home")));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -226,7 +199,32 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
isAltFile = arg.equals("-f") || arg.equals("--file");
|
||||
}
|
||||
}
|
||||
return topDirectory;
|
||||
return getCanonicalPath(topDirectory);
|
||||
}
|
||||
|
||||
protected Path getRootDirectory(ParserRequest parserRequest, Path cwd, Path topDirectory) throws ParserException {
|
||||
RootLocator rootLocator =
|
||||
ServiceLoader.load(RootLocator.class).iterator().next();
|
||||
Path rootDirectory = rootLocator.findRoot(topDirectory);
|
||||
|
||||
// TODO: multiModuleProjectDirectory vs rootDirectory?
|
||||
// fallback if no root? otherwise make sure they are same?
|
||||
Path mmpd = System.getProperty("maven.multiModuleProjectDirectory") == null
|
||||
? null
|
||||
: getCanonicalPath(cwd.resolve(requireNonNull(
|
||||
System.getProperty("maven.multiModuleProjectDirectory"),
|
||||
"maven.multiModuleProjectDirectory is not set")));
|
||||
if (rootDirectory == null) {
|
||||
parserRequest.logger().warn(rootLocator.getNoRootMessage());
|
||||
rootDirectory = requireNonNull(
|
||||
mmpd, "maven.multiModuleProjectDirectory is not set and rootDirectory was not discovered");
|
||||
} else {
|
||||
rootDirectory = getCanonicalPath(rootDirectory);
|
||||
if (mmpd != null && !Objects.equals(rootDirectory, mmpd)) {
|
||||
parserRequest.logger().warn("Project root directory and multiModuleProjectDirectory are not aligned");
|
||||
}
|
||||
}
|
||||
return getCanonicalPath(rootDirectory);
|
||||
}
|
||||
|
||||
protected Map<String, String> populateSystemProperties(Map<String, String> overrides) throws ParserException {
|
||||
|
@ -260,7 +258,10 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
}
|
||||
|
||||
protected Map<String, String> populateUserProperties(
|
||||
Map<String, String> systemProperties, FileSystem fileSystem, Map<String, String> paths, Options options)
|
||||
Map<String, String> systemProperties,
|
||||
Path installationDirectory,
|
||||
Map<String, String> paths,
|
||||
Options options)
|
||||
throws ParserException, IOException {
|
||||
Properties userProperties = new Properties();
|
||||
|
||||
|
@ -281,13 +282,15 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
|
||||
Path mavenConf;
|
||||
if (systemProperties.get(MAVEN_INSTALLATION_CONF) != null) {
|
||||
mavenConf = fileSystem.getPath(systemProperties.get(MAVEN_INSTALLATION_CONF));
|
||||
mavenConf = installationDirectory.resolve(systemProperties.get(MAVEN_INSTALLATION_CONF));
|
||||
} else if (systemProperties.get("maven.conf") != null) {
|
||||
mavenConf = fileSystem.getPath(systemProperties.get("maven.conf"));
|
||||
mavenConf = installationDirectory.resolve(systemProperties.get("maven.conf"));
|
||||
} else if (systemProperties.get(MAVEN_HOME) != null) {
|
||||
mavenConf = fileSystem.getPath(systemProperties.get(MAVEN_HOME), "conf");
|
||||
mavenConf = installationDirectory
|
||||
.resolve(systemProperties.get(MAVEN_HOME))
|
||||
.resolve("conf");
|
||||
} else {
|
||||
mavenConf = fileSystem.getPath("");
|
||||
mavenConf = installationDirectory.resolve("");
|
||||
}
|
||||
Path propertiesFile = mavenConf.resolve("maven.properties");
|
||||
MavenPropertiesLoader.loadProperties(userProperties, propertiesFile, callback, false);
|
||||
|
@ -304,15 +307,16 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
return toMap(userProperties);
|
||||
}
|
||||
|
||||
protected abstract List<O> parseCliOptions(Path rootDirectory, String[] args) throws ParserException, IOException;
|
||||
protected abstract List<O> parseCliOptions(Path rootDirectory, List<String> args)
|
||||
throws ParserException, IOException;
|
||||
|
||||
protected abstract O assembleOptions(List<O> parsedOptions);
|
||||
|
||||
protected List<CoreExtension> readCoreExtensionsDescriptor(String extensionsFile, FileSystem fileSystem)
|
||||
protected List<CoreExtension> readCoreExtensionsDescriptor(String extensionsFile, Path cwd)
|
||||
throws ParserException, IOException {
|
||||
try {
|
||||
if (extensionsFile != null) {
|
||||
Path extensionsPath = fileSystem.getPath(extensionsFile);
|
||||
Path extensionsPath = cwd.resolve(extensionsFile);
|
||||
if (Files.exists(extensionsPath)) {
|
||||
try (InputStream is = Files.newInputStream(extensionsPath)) {
|
||||
return new CoreExtensionsStaxReader().read(is, true).getExtensions();
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.apache.commons.cli.HelpFormatter;
|
|||
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.ParserRequest;
|
||||
import org.apache.maven.cli.CleanArgument;
|
||||
import org.apache.maven.jline.MessageUtils;
|
||||
|
||||
|
@ -201,7 +202,7 @@ public abstract class CommonsCliOptions implements Options {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void warnAboutDeprecatedOptions(PrintWriter printWriter) {
|
||||
public void warnAboutDeprecatedOptions(ParserRequest request, PrintWriter printWriter) {
|
||||
if (cliManager.getUsedDeprecatedOptions().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
@ -217,15 +218,18 @@ public abstract class CommonsCliOptions implements Options {
|
|||
sb.append("and will be removed in a future version");
|
||||
}
|
||||
if (option.getDeprecated().getSince() != null) {
|
||||
sb.append("since Maven ").append(option.getDeprecated().getSince());
|
||||
sb.append("since ")
|
||||
.append(request.commandName())
|
||||
.append(" ")
|
||||
.append(option.getDeprecated().getSince());
|
||||
}
|
||||
printWriter.println(sb);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void displayHelp(String command, PrintWriter printStream) {
|
||||
cliManager.displayHelp(command, printStream);
|
||||
public void displayHelp(ParserRequest request, PrintWriter printStream) {
|
||||
cliManager.displayHelp(request.command(), printStream);
|
||||
}
|
||||
|
||||
protected static class CLIManager {
|
||||
|
|
|
@ -27,6 +27,7 @@ import java.util.Optional;
|
|||
import java.util.function.Function;
|
||||
|
||||
import org.apache.maven.api.cli.Options;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
|
||||
/**
|
||||
* Options that are "layered" by precedence order.
|
||||
|
@ -132,11 +133,11 @@ public abstract class LayeredOptions<O extends Options> implements Options {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void warnAboutDeprecatedOptions(PrintWriter printWriter) {}
|
||||
public void warnAboutDeprecatedOptions(ParserRequest request, PrintWriter printWriter) {}
|
||||
|
||||
@Override
|
||||
public void displayHelp(String command, PrintWriter printWriter) {
|
||||
options.get(0).displayHelp(command, printWriter);
|
||||
public void displayHelp(ParserRequest request, PrintWriter printWriter) {
|
||||
options.get(0).displayHelp(request, printWriter);
|
||||
}
|
||||
|
||||
protected <T> Optional<T> returnFirstPresentOrEmpty(Function<O, Optional<T>> getter) {
|
||||
|
|
|
@ -95,6 +95,8 @@ public abstract class LookupInvoker<
|
|||
public final ProtoLookup protoLookup;
|
||||
public final R invokerRequest;
|
||||
public final Function<String, Path> cwdResolver;
|
||||
public final Function<String, Path> installationResolver;
|
||||
public final Function<String, Path> userResolver;
|
||||
public final InputStream stdIn;
|
||||
public final PrintWriter stdOut;
|
||||
public final PrintWriter stdErr;
|
||||
|
@ -104,10 +106,17 @@ public abstract class LookupInvoker<
|
|||
this.protoLookup = invoker.protoLookup;
|
||||
this.invokerRequest = requireNonNull(invokerRequest);
|
||||
this.cwdResolver = s -> invokerRequest.cwd().resolve(s).normalize().toAbsolutePath();
|
||||
this.installationResolver = s -> invokerRequest
|
||||
.installationDirectory()
|
||||
.resolve(s)
|
||||
.normalize()
|
||||
.toAbsolutePath();
|
||||
this.userResolver = s ->
|
||||
invokerRequest.userHomeDirectory().resolve(s).normalize().toAbsolutePath();
|
||||
this.stdIn = invokerRequest.in().orElse(System.in);
|
||||
this.stdOut = new PrintWriter(invokerRequest.out().orElse(System.out), true);
|
||||
this.stdErr = new PrintWriter(invokerRequest.err().orElse(System.err), true);
|
||||
this.logger = invokerRequest.logger();
|
||||
this.logger = invokerRequest.parserRequest().logger();
|
||||
}
|
||||
|
||||
public Logger logger;
|
||||
|
@ -149,7 +158,7 @@ public abstract class LookupInvoker<
|
|||
logging(context);
|
||||
|
||||
if (invokerRequest.options().help().isPresent()) {
|
||||
invokerRequest.options().displayHelp(context.invokerRequest.command(), context.stdOut);
|
||||
invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), context.stdOut);
|
||||
return 0;
|
||||
}
|
||||
if (invokerRequest.options().showVersionAndExit().isPresent()) {
|
||||
|
@ -178,9 +187,11 @@ public abstract class LookupInvoker<
|
|||
throws InvokerException {
|
||||
boolean showStackTrace = context.invokerRequest.options().showErrors().orElse(false);
|
||||
if (showStackTrace) {
|
||||
context.logger.error("Error executing Maven.", e);
|
||||
context.logger.error(
|
||||
"Error executing " + context.invokerRequest.parserRequest().commandName() + ".", e);
|
||||
} else {
|
||||
context.logger.error("Error executing Maven.");
|
||||
context.logger.error(
|
||||
"Error executing " + context.invokerRequest.parserRequest().commandName() + ".");
|
||||
context.logger.error(e.getMessage());
|
||||
for (Throwable cause = e.getCause(); cause != null && cause != cause.getCause(); cause = cause.getCause()) {
|
||||
context.logger.error("Caused by: " + cause.getMessage());
|
||||
|
@ -338,7 +349,7 @@ public abstract class LookupInvoker<
|
|||
} else {
|
||||
String userSettingsFileStr = context.invokerRequest.userProperties().get(Constants.MAVEN_USER_SETTINGS);
|
||||
if (userSettingsFileStr != null) {
|
||||
userSettingsFile = context.cwdResolver.apply(userSettingsFileStr);
|
||||
userSettingsFile = context.userResolver.apply(userSettingsFileStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -374,7 +385,7 @@ public abstract class LookupInvoker<
|
|||
String installationSettingsFileStr =
|
||||
context.invokerRequest.userProperties().get(Constants.MAVEN_INSTALLATION_SETTINGS);
|
||||
if (installationSettingsFileStr != null) {
|
||||
installationSettingsFile = context.cwdResolver.apply(installationSettingsFileStr);
|
||||
installationSettingsFile = context.installationResolver.apply(installationSettingsFileStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -463,18 +474,18 @@ public abstract class LookupInvoker<
|
|||
+ "usually located at ${session.rootDirectory}/.mvn/maven.properties.");
|
||||
}
|
||||
}
|
||||
if (userDefinedLocalRepo != null) {
|
||||
return context.cwdResolver.apply(userDefinedLocalRepo);
|
||||
}
|
||||
// settings
|
||||
if (userDefinedLocalRepo == null) {
|
||||
userDefinedLocalRepo = context.effectiveSettings.getLocalRepository();
|
||||
userDefinedLocalRepo = context.effectiveSettings.getLocalRepository();
|
||||
if (userDefinedLocalRepo != null) {
|
||||
return context.userResolver.apply(userDefinedLocalRepo);
|
||||
}
|
||||
// defaults
|
||||
if (userDefinedLocalRepo == null) {
|
||||
userDefinedLocalRepo = context.cwdResolver
|
||||
.apply(context.invokerRequest.userProperties().get(Constants.MAVEN_USER_CONF))
|
||||
.resolve("repository")
|
||||
.toString();
|
||||
}
|
||||
return context.cwdResolver.apply(userDefinedLocalRepo);
|
||||
return context.userResolver
|
||||
.apply(context.invokerRequest.userProperties().get(Constants.MAVEN_USER_CONF))
|
||||
.resolve("repository");
|
||||
}
|
||||
|
||||
protected void populateRequest(C context, MavenExecutionRequest request) throws Exception {
|
||||
|
|
|
@ -105,7 +105,7 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void prepare(C localContext) throws Exception {
|
||||
protected void prepare(C context) throws Exception {
|
||||
// explicitly fill in "defaults"?
|
||||
DefaultMavenExecutionRequest mavenExecutionRequest = new DefaultMavenExecutionRequest();
|
||||
mavenExecutionRequest.setRepositoryCache(new DefaultRepositoryCache());
|
||||
|
@ -120,7 +120,7 @@ public abstract class DefaultMavenInvoker<
|
|||
mavenExecutionRequest.setDegreeOfConcurrency(1);
|
||||
mavenExecutionRequest.setBuilderId("singlethreaded");
|
||||
|
||||
localContext.mavenExecutionRequest = mavenExecutionRequest;
|
||||
context.mavenExecutionRequest = mavenExecutionRequest;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -146,11 +146,11 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
|
||||
@Override
|
||||
protected void postCommands(C localContext) throws Exception {
|
||||
super.postCommands(localContext);
|
||||
protected void postCommands(C context) throws Exception {
|
||||
super.postCommands(context);
|
||||
|
||||
R invokerRequest = localContext.invokerRequest;
|
||||
Logger logger = localContext.logger;
|
||||
R invokerRequest = context.invokerRequest;
|
||||
Logger logger = context.logger;
|
||||
if (invokerRequest.options().relaxedChecksums().orElse(false)) {
|
||||
logger.info("Disabling strict checksum verification on all artifact downloads.");
|
||||
} else if (invokerRequest.options().strictChecksums().orElse(false)) {
|
||||
|
@ -172,12 +172,12 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected void toolchains(C localContext) throws Exception {
|
||||
protected void toolchains(C context) throws Exception {
|
||||
Path userToolchainsFile = null;
|
||||
|
||||
if (localContext.invokerRequest.options().altUserToolchains().isPresent()) {
|
||||
userToolchainsFile = localContext.cwdResolver.apply(
|
||||
localContext.invokerRequest.options().altUserToolchains().get());
|
||||
if (context.invokerRequest.options().altUserToolchains().isPresent()) {
|
||||
userToolchainsFile = context.cwdResolver.apply(
|
||||
context.invokerRequest.options().altUserToolchains().get());
|
||||
|
||||
if (!Files.isRegularFile(userToolchainsFile)) {
|
||||
throw new FileNotFoundException(
|
||||
|
@ -185,20 +185,17 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
} else {
|
||||
String userToolchainsFileStr =
|
||||
localContext.invokerRequest.userProperties().get(Constants.MAVEN_USER_TOOLCHAINS);
|
||||
context.invokerRequest.userProperties().get(Constants.MAVEN_USER_TOOLCHAINS);
|
||||
if (userToolchainsFileStr != null) {
|
||||
userToolchainsFile = localContext.cwdResolver.apply(userToolchainsFileStr);
|
||||
userToolchainsFile = context.cwdResolver.apply(userToolchainsFileStr);
|
||||
}
|
||||
}
|
||||
|
||||
Path installationToolchainsFile = null;
|
||||
|
||||
if (localContext.invokerRequest.options().altInstallationToolchains().isPresent()) {
|
||||
installationToolchainsFile = localContext.cwdResolver.apply(localContext
|
||||
.invokerRequest
|
||||
.options()
|
||||
.altInstallationToolchains()
|
||||
.get());
|
||||
if (context.invokerRequest.options().altInstallationToolchains().isPresent()) {
|
||||
installationToolchainsFile = context.cwdResolver.apply(
|
||||
context.invokerRequest.options().altInstallationToolchains().get());
|
||||
|
||||
if (!Files.isRegularFile(installationToolchainsFile)) {
|
||||
throw new FileNotFoundException(
|
||||
|
@ -206,15 +203,15 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
} else {
|
||||
String installationToolchainsFileStr =
|
||||
localContext.invokerRequest.userProperties().get(Constants.MAVEN_INSTALLATION_TOOLCHAINS);
|
||||
context.invokerRequest.userProperties().get(Constants.MAVEN_INSTALLATION_TOOLCHAINS);
|
||||
if (installationToolchainsFileStr != null) {
|
||||
installationToolchainsFile = localContext.cwdResolver.apply(installationToolchainsFileStr);
|
||||
installationToolchainsFile = context.cwdResolver.apply(installationToolchainsFileStr);
|
||||
}
|
||||
}
|
||||
|
||||
localContext.mavenExecutionRequest.setInstallationToolchainsFile(
|
||||
context.mavenExecutionRequest.setInstallationToolchainsFile(
|
||||
installationToolchainsFile != null ? installationToolchainsFile.toFile() : null);
|
||||
localContext.mavenExecutionRequest.setUserToolchainsFile(
|
||||
context.mavenExecutionRequest.setUserToolchainsFile(
|
||||
userToolchainsFile != null ? userToolchainsFile.toFile() : null);
|
||||
|
||||
DefaultToolchainsBuildingRequest toolchainsRequest = new DefaultToolchainsBuildingRequest();
|
||||
|
@ -225,35 +222,35 @@ public abstract class DefaultMavenInvoker<
|
|||
toolchainsRequest.setUserToolchainsSource(new FileSource(userToolchainsFile));
|
||||
}
|
||||
|
||||
localContext.eventSpyDispatcher.onEvent(toolchainsRequest);
|
||||
context.eventSpyDispatcher.onEvent(toolchainsRequest);
|
||||
|
||||
localContext.logger.debug("Reading installation toolchains from '"
|
||||
context.logger.debug("Reading installation toolchains from '"
|
||||
+ (toolchainsRequest.getGlobalToolchainsSource() != null
|
||||
? toolchainsRequest.getGlobalToolchainsSource().getLocation()
|
||||
: installationToolchainsFile)
|
||||
+ "'");
|
||||
localContext.logger.debug("Reading user toolchains from '"
|
||||
context.logger.debug("Reading user toolchains from '"
|
||||
+ (toolchainsRequest.getUserToolchainsSource() != null
|
||||
? toolchainsRequest.getUserToolchainsSource().getLocation()
|
||||
: userToolchainsFile)
|
||||
+ "'");
|
||||
|
||||
ToolchainsBuildingResult toolchainsResult = localContext.toolchainsBuilder.build(toolchainsRequest);
|
||||
ToolchainsBuildingResult toolchainsResult = context.toolchainsBuilder.build(toolchainsRequest);
|
||||
|
||||
localContext.eventSpyDispatcher.onEvent(toolchainsResult);
|
||||
context.eventSpyDispatcher.onEvent(toolchainsResult);
|
||||
|
||||
localContext.mavenExecutionRequestPopulator.populateFromToolchains(
|
||||
localContext.mavenExecutionRequest, toolchainsResult.getEffectiveToolchains());
|
||||
context.mavenExecutionRequestPopulator.populateFromToolchains(
|
||||
context.mavenExecutionRequest, toolchainsResult.getEffectiveToolchains());
|
||||
|
||||
if (!toolchainsResult.getProblems().isEmpty()) {
|
||||
localContext.logger.warn("");
|
||||
localContext.logger.warn("Some problems were encountered while building the effective toolchains");
|
||||
context.logger.warn("");
|
||||
context.logger.warn("Some problems were encountered while building the effective toolchains");
|
||||
|
||||
for (Problem problem : toolchainsResult.getProblems()) {
|
||||
localContext.logger.warn(problem.getMessage() + " @ " + problem.getLocation());
|
||||
context.logger.warn(problem.getMessage() + " @ " + problem.getLocation());
|
||||
}
|
||||
|
||||
localContext.logger.warn("");
|
||||
context.logger.warn("");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -325,21 +322,21 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected Path determinePom(C localContext) {
|
||||
Path current = localContext.invokerRequest.cwd();
|
||||
if (localContext.invokerRequest.options().alternatePomFile().isPresent()) {
|
||||
current = localContext.cwdResolver.apply(
|
||||
localContext.invokerRequest.options().alternatePomFile().get());
|
||||
protected Path determinePom(C context) {
|
||||
Path current = context.invokerRequest.cwd();
|
||||
if (context.invokerRequest.options().alternatePomFile().isPresent()) {
|
||||
current = context.cwdResolver.apply(
|
||||
context.invokerRequest.options().alternatePomFile().get());
|
||||
}
|
||||
if (localContext.modelProcessor != null) {
|
||||
return localContext.modelProcessor.locateExistingPom(current);
|
||||
if (context.modelProcessor != null) {
|
||||
return context.modelProcessor.locateExistingPom(current);
|
||||
} else {
|
||||
return Files.isRegularFile(current) ? current : null;
|
||||
}
|
||||
}
|
||||
|
||||
protected String determineReactorFailureBehaviour(C localContext) {
|
||||
MavenOptions mavenOptions = localContext.invokerRequest.options();
|
||||
protected String determineReactorFailureBehaviour(C context) {
|
||||
MavenOptions mavenOptions = context.invokerRequest.options();
|
||||
if (mavenOptions.failFast().isPresent()) {
|
||||
return MavenExecutionRequest.REACTOR_FAIL_FAST;
|
||||
} else if (mavenOptions.failAtEnd().isPresent()) {
|
||||
|
@ -351,8 +348,8 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected String determineGlobalChecksumPolicy(C localContext) {
|
||||
MavenOptions mavenOptions = localContext.invokerRequest.options();
|
||||
protected String determineGlobalChecksumPolicy(C context) {
|
||||
MavenOptions mavenOptions = context.invokerRequest.options();
|
||||
if (mavenOptions.strictChecksums().orElse(false)) {
|
||||
return MavenExecutionRequest.CHECKSUM_POLICY_FAIL;
|
||||
} else if (mavenOptions.relaxedChecksums().orElse(false)) {
|
||||
|
@ -362,18 +359,17 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected ExecutionListener determineExecutionListener(C localContext) {
|
||||
ExecutionListener executionListener =
|
||||
new ExecutionEventLogger(localContext.invokerRequest.messageBuilderFactory());
|
||||
if (localContext.eventSpyDispatcher != null) {
|
||||
return localContext.eventSpyDispatcher.chainListener(executionListener);
|
||||
protected ExecutionListener determineExecutionListener(C context) {
|
||||
ExecutionListener executionListener = new ExecutionEventLogger(context.invokerRequest.messageBuilderFactory());
|
||||
if (context.eventSpyDispatcher != null) {
|
||||
return context.eventSpyDispatcher.chainListener(executionListener);
|
||||
} else {
|
||||
return executionListener;
|
||||
}
|
||||
}
|
||||
|
||||
protected String determineMakeBehavior(C localContext) {
|
||||
MavenOptions mavenOptions = localContext.invokerRequest.options();
|
||||
protected String determineMakeBehavior(C context) {
|
||||
MavenOptions mavenOptions = context.invokerRequest.options();
|
||||
if (mavenOptions.alsoMake().isPresent()
|
||||
&& mavenOptions.alsoMakeDependents().isEmpty()) {
|
||||
return MavenExecutionRequest.REACTOR_MAKE_UPSTREAM;
|
||||
|
@ -388,8 +384,8 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected void performProjectActivation(C localContext, ProjectActivation projectActivation) {
|
||||
MavenOptions mavenOptions = localContext.invokerRequest.options();
|
||||
protected void performProjectActivation(C context, ProjectActivation projectActivation) {
|
||||
MavenOptions mavenOptions = context.invokerRequest.options();
|
||||
if (mavenOptions.projects().isPresent()
|
||||
&& !mavenOptions.projects().get().isEmpty()) {
|
||||
List<String> optionValues = mavenOptions.projects().get();
|
||||
|
@ -416,8 +412,8 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected void performProfileActivation(C localContext, ProfileActivation profileActivation) {
|
||||
MavenOptions mavenOptions = localContext.invokerRequest.options();
|
||||
protected void performProfileActivation(C context, ProfileActivation profileActivation) {
|
||||
MavenOptions mavenOptions = context.invokerRequest.options();
|
||||
if (mavenOptions.activatedProfiles().isPresent()
|
||||
&& !mavenOptions.activatedProfiles().get().isEmpty()) {
|
||||
List<String> optionValues = mavenOptions.activatedProfiles().get();
|
||||
|
@ -444,62 +440,61 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected int doExecute(C localContext) throws Exception {
|
||||
MavenExecutionRequest request = localContext.mavenExecutionRequest;
|
||||
protected int doExecute(C context) throws Exception {
|
||||
MavenExecutionRequest request = context.mavenExecutionRequest;
|
||||
|
||||
// why? No way to disable caching?
|
||||
if (localContext.mavenExecutionRequest.getRepositoryCache() == null) {
|
||||
localContext.mavenExecutionRequest.setRepositoryCache(new DefaultRepositoryCache());
|
||||
if (context.mavenExecutionRequest.getRepositoryCache() == null) {
|
||||
context.mavenExecutionRequest.setRepositoryCache(new DefaultRepositoryCache());
|
||||
}
|
||||
|
||||
localContext.eventSpyDispatcher.onEvent(request);
|
||||
context.eventSpyDispatcher.onEvent(request);
|
||||
|
||||
MavenExecutionResult result = localContext.maven.execute(request);
|
||||
|
||||
localContext.eventSpyDispatcher.onEvent(result);
|
||||
|
||||
localContext.eventSpyDispatcher.close();
|
||||
MavenExecutionResult result;
|
||||
try {
|
||||
result = context.maven.execute(request);
|
||||
context.eventSpyDispatcher.onEvent(result);
|
||||
} finally {
|
||||
context.eventSpyDispatcher.close();
|
||||
}
|
||||
|
||||
if (result.hasExceptions()) {
|
||||
ExceptionHandler handler = new DefaultExceptionHandler();
|
||||
|
||||
Map<String, String> references = new LinkedHashMap<>();
|
||||
|
||||
List<MavenProject> failedProjects = new ArrayList<>();
|
||||
|
||||
for (Throwable exception : result.getExceptions()) {
|
||||
ExceptionSummary summary = handler.handleException(exception);
|
||||
|
||||
logSummary(localContext, summary, references, "");
|
||||
logSummary(context, summary, references, "");
|
||||
|
||||
if (exception instanceof LifecycleExecutionException) {
|
||||
failedProjects.add(((LifecycleExecutionException) exception).getProject());
|
||||
}
|
||||
}
|
||||
|
||||
localContext.logger.error("");
|
||||
context.logger.error("");
|
||||
|
||||
if (!localContext.invokerRequest.options().showErrors().orElse(false)) {
|
||||
localContext.logger.error("To see the full stack trace of the errors, re-run Maven with the '"
|
||||
if (!context.invokerRequest.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");
|
||||
}
|
||||
if (!localContext.invokerRequest.options().verbose().orElse(false)) {
|
||||
localContext.logger.error("Re-run Maven using the '"
|
||||
if (!context.invokerRequest.options().verbose().orElse(false)) {
|
||||
context.logger.error("Re-run Maven using the '"
|
||||
+ MessageUtils.builder().strong("-X") + "' switch to enable verbose output");
|
||||
}
|
||||
|
||||
if (!references.isEmpty()) {
|
||||
localContext.logger.error("");
|
||||
localContext.logger.error("For more information about the errors and possible solutions"
|
||||
context.logger.error("");
|
||||
context.logger.error("For more information about the errors and possible solutions"
|
||||
+ ", please read the following articles:");
|
||||
|
||||
for (Map.Entry<String, String> entry : references.entrySet()) {
|
||||
localContext.logger.error(MessageUtils.builder().strong(entry.getValue()) + " " + entry.getKey());
|
||||
context.logger.error(MessageUtils.builder().strong(entry.getValue()) + " " + entry.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
if (result.canResume()) {
|
||||
logBuildResumeHint(localContext, "mvn [args] -r");
|
||||
logBuildResumeHint(context, "mvn [args] -r");
|
||||
} else if (!failedProjects.isEmpty()) {
|
||||
List<MavenProject> sortedProjects = result.getTopologicallySortedProjects();
|
||||
|
||||
|
@ -509,12 +504,12 @@ public abstract class DefaultMavenInvoker<
|
|||
MavenProject firstFailedProject = failedProjects.get(0);
|
||||
if (!firstFailedProject.equals(sortedProjects.get(0))) {
|
||||
String resumeFromSelector = getResumeFromSelector(sortedProjects, firstFailedProject);
|
||||
logBuildResumeHint(localContext, "mvn [args] -rf " + resumeFromSelector);
|
||||
logBuildResumeHint(context, "mvn [args] -rf " + resumeFromSelector);
|
||||
}
|
||||
}
|
||||
|
||||
if (localContext.invokerRequest.options().failNever().orElse(false)) {
|
||||
localContext.logger.info("Build failures were ignored.");
|
||||
if (context.invokerRequest.options().failNever().orElse(false)) {
|
||||
context.logger.info("Build failures were ignored.");
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
|
@ -524,10 +519,10 @@ public abstract class DefaultMavenInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected void logBuildResumeHint(C localContext, String resumeBuildHint) {
|
||||
localContext.logger.error("");
|
||||
localContext.logger.error("After correcting the problems, you can resume the build with the command");
|
||||
localContext.logger.error(
|
||||
protected void logBuildResumeHint(C context, String resumeBuildHint) {
|
||||
context.logger.error("");
|
||||
context.logger.error("After correcting the problems, you can resume the build with the command");
|
||||
context.logger.error(
|
||||
MessageUtils.builder().a(" ").strong(resumeBuildHint).toString());
|
||||
}
|
||||
|
||||
|
@ -567,7 +562,7 @@ public abstract class DefaultMavenInvoker<
|
|||
|
||||
protected static final String ANSI_RESET = "\u001B\u005Bm";
|
||||
|
||||
protected void logSummary(C localContext, ExceptionSummary summary, Map<String, String> references, String indent) {
|
||||
protected void logSummary(C context, ExceptionSummary summary, Map<String, String> references, String indent) {
|
||||
String referenceKey = "";
|
||||
|
||||
if (summary.getReference() != null && !summary.getReference().isEmpty()) {
|
||||
|
@ -607,11 +602,11 @@ public abstract class DefaultMavenInvoker<
|
|||
line = indent + line + ("".equals(nextColor) ? "" : ANSI_RESET);
|
||||
|
||||
if ((i == lines.length - 1)
|
||||
&& (localContext.invokerRequest.options().showErrors().orElse(false)
|
||||
&& (context.invokerRequest.options().showErrors().orElse(false)
|
||||
|| (summary.getException() instanceof InternalErrorException))) {
|
||||
localContext.logger.error(line, summary.getException());
|
||||
context.logger.error(line, summary.getException());
|
||||
} else {
|
||||
localContext.logger.error(line);
|
||||
context.logger.error(line);
|
||||
}
|
||||
|
||||
currentColor = nextColor;
|
||||
|
@ -620,7 +615,7 @@ public abstract class DefaultMavenInvoker<
|
|||
indent += " ";
|
||||
|
||||
for (ExceptionSummary child : summary.getChildren()) {
|
||||
logSummary(localContext, child, references, indent);
|
||||
logSummary(context, child, references, indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.apache.maven.api.annotations.Nonnull;
|
||||
import org.apache.maven.api.cli.Logger;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
import org.apache.maven.cling.invoker.BaseInvokerRequest;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
@ -45,14 +44,12 @@ public class DefaultMavenInvokerRequest<O extends MavenOptions> extends BaseInvo
|
|||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
public DefaultMavenInvokerRequest(
|
||||
String command,
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Logger logger,
|
||||
MessageBuilderFactory messageBuilderFactory,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
InputStream in,
|
||||
|
@ -61,14 +58,12 @@ public class DefaultMavenInvokerRequest<O extends MavenOptions> extends BaseInvo
|
|||
List<CoreExtension> coreExtensions,
|
||||
O options) {
|
||||
super(
|
||||
command,
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
logger,
|
||||
messageBuilderFactory,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
in,
|
||||
|
|
|
@ -53,7 +53,7 @@ public abstract class DefaultMavenParser<O extends MavenOptions, R extends Maven
|
|||
Options options);
|
||||
|
||||
@Override
|
||||
protected List<O> parseCliOptions(Path rootDirectory, String[] args) throws ParserException, IOException {
|
||||
protected List<O> parseCliOptions(Path rootDirectory, List<String> args) throws ParserException, IOException {
|
||||
ArrayList<O> result = new ArrayList<>();
|
||||
// CLI args
|
||||
result.add(parseMavenCliOptions(args));
|
||||
|
@ -65,14 +65,14 @@ public abstract class DefaultMavenParser<O extends MavenOptions, R extends Maven
|
|||
return result;
|
||||
}
|
||||
|
||||
protected O parseMavenCliOptions(String[] args) throws ParserException {
|
||||
protected O parseMavenCliOptions(List<String> args) throws ParserException {
|
||||
return parseArgs(Options.SOURCE_CLI, args);
|
||||
}
|
||||
|
||||
protected O parseMavenConfigOptions(Path configFile) throws ParserException, IOException {
|
||||
try (Stream<String> lines = Files.lines(configFile, Charset.defaultCharset())) {
|
||||
String[] args =
|
||||
lines.filter(arg -> !arg.isEmpty() && !arg.startsWith("#")).toArray(String[]::new);
|
||||
List<String> args =
|
||||
lines.filter(arg -> !arg.isEmpty() && !arg.startsWith("#")).toList();
|
||||
O options = parseArgs("maven.config", args);
|
||||
if (options.goals().isPresent()) {
|
||||
// This file can only contain options, not args (goals or phases)
|
||||
|
@ -83,5 +83,5 @@ public abstract class DefaultMavenParser<O extends MavenOptions, R extends Maven
|
|||
}
|
||||
}
|
||||
|
||||
protected abstract O parseArgs(String source, String[] args) throws ParserException;
|
||||
protected abstract O parseArgs(String source, List<String> args) throws ParserException;
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import static java.util.Objects.requireNonNull;
|
|||
* Forked invoker implementation, it spawns a subprocess with Maven.
|
||||
*/
|
||||
public class DefaultForkedMavenInvoker implements ForkedMavenInvoker {
|
||||
@SuppressWarnings("MethodLength")
|
||||
@Override
|
||||
public int invoke(ForkedMavenInvokerRequest invokerRequest) throws InvokerException {
|
||||
requireNonNull(invokerRequest);
|
||||
|
@ -44,7 +45,10 @@ public class DefaultForkedMavenInvoker implements ForkedMavenInvoker {
|
|||
cmdAndArguments.add(invokerRequest
|
||||
.installationDirectory()
|
||||
.resolve("bin")
|
||||
.resolve(Os.IS_WINDOWS ? invokerRequest.command() + ".cmd" : invokerRequest.command())
|
||||
.resolve(
|
||||
Os.IS_WINDOWS
|
||||
? invokerRequest.parserRequest().command() + ".cmd"
|
||||
: invokerRequest.parserRequest().command())
|
||||
.toString());
|
||||
|
||||
MavenOptions mavenOptions = invokerRequest.options();
|
||||
|
@ -54,42 +58,138 @@ public class DefaultForkedMavenInvoker implements ForkedMavenInvoker {
|
|||
cmdAndArguments.add("-D" + entry.getKey() + "=" + entry.getValue());
|
||||
}
|
||||
}
|
||||
if (mavenOptions.showVersionAndExit().orElse(false)) {
|
||||
cmdAndArguments.add("--version");
|
||||
}
|
||||
if (mavenOptions.showVersion().orElse(false)) {
|
||||
cmdAndArguments.add("--show-version");
|
||||
}
|
||||
if (mavenOptions.quiet().orElse(false)) {
|
||||
cmdAndArguments.add("--quiet");
|
||||
}
|
||||
if (mavenOptions.verbose().orElse(false)) {
|
||||
cmdAndArguments.add("--verbose");
|
||||
}
|
||||
if (mavenOptions.showErrors().orElse(false)) {
|
||||
cmdAndArguments.add("--errors");
|
||||
}
|
||||
if (mavenOptions.failOnSeverity().isPresent()) {
|
||||
cmdAndArguments.add("--fail-on-severity");
|
||||
cmdAndArguments.add(mavenOptions.failOnSeverity().get());
|
||||
}
|
||||
if (mavenOptions.nonInteractive().orElse(false)) {
|
||||
cmdAndArguments.add("--non-interactive");
|
||||
}
|
||||
if (mavenOptions.forceInteractive().orElse(false)) {
|
||||
cmdAndArguments.add("--force-interactive");
|
||||
}
|
||||
if (mavenOptions.altUserSettings().isPresent()) {
|
||||
cmdAndArguments.add("--settings");
|
||||
cmdAndArguments.add(mavenOptions.altUserSettings().get());
|
||||
}
|
||||
if (mavenOptions.altProjectSettings().isPresent()) {
|
||||
cmdAndArguments.add("--project-settings");
|
||||
cmdAndArguments.add(mavenOptions.altProjectSettings().get());
|
||||
}
|
||||
if (mavenOptions.altInstallationSettings().isPresent()) {
|
||||
cmdAndArguments.add("--install-settings");
|
||||
cmdAndArguments.add(mavenOptions.altInstallationSettings().get());
|
||||
}
|
||||
if (mavenOptions.altUserToolchains().isPresent()) {
|
||||
cmdAndArguments.add("--toolchains");
|
||||
cmdAndArguments.add(mavenOptions.altUserToolchains().get());
|
||||
}
|
||||
if (mavenOptions.altInstallationToolchains().isPresent()) {
|
||||
cmdAndArguments.add("--install-toolchains");
|
||||
cmdAndArguments.add(mavenOptions.altInstallationToolchains().get());
|
||||
}
|
||||
if (mavenOptions.logFile().isPresent()) {
|
||||
cmdAndArguments.add("--log-file");
|
||||
cmdAndArguments.add(mavenOptions.logFile().get());
|
||||
}
|
||||
if (mavenOptions.color().isPresent()) {
|
||||
cmdAndArguments.add("--color");
|
||||
cmdAndArguments.add(mavenOptions.color().get());
|
||||
}
|
||||
if (mavenOptions.help().orElse(false)) {
|
||||
cmdAndArguments.add("--help");
|
||||
}
|
||||
if (mavenOptions.alternatePomFile().isPresent()) {
|
||||
cmdAndArguments.add("-f");
|
||||
cmdAndArguments.add("--file");
|
||||
cmdAndArguments.add(mavenOptions.alternatePomFile().get());
|
||||
}
|
||||
if (mavenOptions.offline().orElse(false)) {
|
||||
cmdAndArguments.add("-o");
|
||||
}
|
||||
if (mavenOptions.showVersionAndExit().orElse(false)) {
|
||||
cmdAndArguments.add("-v");
|
||||
}
|
||||
if (mavenOptions.showVersion().orElse(false)) {
|
||||
cmdAndArguments.add("-V");
|
||||
}
|
||||
if (mavenOptions.quiet().orElse(false)) {
|
||||
cmdAndArguments.add("-q");
|
||||
}
|
||||
if (mavenOptions.verbose().orElse(false)) {
|
||||
cmdAndArguments.add("-X");
|
||||
}
|
||||
if (mavenOptions.showErrors().orElse(false)) {
|
||||
cmdAndArguments.add("-e");
|
||||
cmdAndArguments.add("--offline");
|
||||
}
|
||||
if (mavenOptions.nonRecursive().orElse(false)) {
|
||||
cmdAndArguments.add("-N");
|
||||
cmdAndArguments.add("--non-recursive");
|
||||
}
|
||||
if (mavenOptions.updateSnapshots().orElse(false)) {
|
||||
cmdAndArguments.add("-U");
|
||||
cmdAndArguments.add("--update-snapshots");
|
||||
}
|
||||
if (mavenOptions.nonInteractive().orElse(false)) {
|
||||
cmdAndArguments.add("-B");
|
||||
if (mavenOptions.activatedProfiles().isPresent()) {
|
||||
cmdAndArguments.add("--activate-profiles");
|
||||
cmdAndArguments.add(
|
||||
String.join(",", mavenOptions.activatedProfiles().get()));
|
||||
}
|
||||
if (mavenOptions.logFile().isPresent()) {
|
||||
cmdAndArguments.add("-l");
|
||||
cmdAndArguments.add(mavenOptions.logFile().get());
|
||||
if (mavenOptions.suppressSnapshotUpdates().orElse(false)) {
|
||||
cmdAndArguments.add("--no-snapshot-updates");
|
||||
}
|
||||
if (mavenOptions.strictChecksums().orElse(false)) {
|
||||
cmdAndArguments.add("--strict-checksums");
|
||||
}
|
||||
if (mavenOptions.relaxedChecksums().orElse(false)) {
|
||||
cmdAndArguments.add("--lax-checksums");
|
||||
}
|
||||
if (mavenOptions.failFast().orElse(false)) {
|
||||
cmdAndArguments.add("--fail-fast");
|
||||
}
|
||||
if (mavenOptions.failAtEnd().orElse(false)) {
|
||||
cmdAndArguments.add("--fail-at-end");
|
||||
}
|
||||
if (mavenOptions.failNever().orElse(false)) {
|
||||
cmdAndArguments.add("--fail-never");
|
||||
}
|
||||
if (mavenOptions.resume().orElse(false)) {
|
||||
cmdAndArguments.add("--resume");
|
||||
}
|
||||
if (mavenOptions.resumeFrom().isPresent()) {
|
||||
cmdAndArguments.add("--resume-from");
|
||||
cmdAndArguments.add(mavenOptions.resumeFrom().get());
|
||||
}
|
||||
if (mavenOptions.projects().isPresent()) {
|
||||
cmdAndArguments.add("--projects");
|
||||
cmdAndArguments.add(String.join(",", mavenOptions.projects().get()));
|
||||
}
|
||||
if (mavenOptions.alsoMake().orElse(false)) {
|
||||
cmdAndArguments.add("--also-make");
|
||||
}
|
||||
if (mavenOptions.alsoMakeDependents().orElse(false)) {
|
||||
cmdAndArguments.add("--also-make-dependents");
|
||||
}
|
||||
if (mavenOptions.threads().isPresent()) {
|
||||
cmdAndArguments.add("--threads");
|
||||
cmdAndArguments.add(mavenOptions.threads().get());
|
||||
}
|
||||
if (mavenOptions.builder().isPresent()) {
|
||||
cmdAndArguments.add("--builder");
|
||||
cmdAndArguments.add(mavenOptions.builder().get());
|
||||
}
|
||||
if (mavenOptions.noTransferProgress().orElse(false)) {
|
||||
cmdAndArguments.add("--no-transfer-progress");
|
||||
}
|
||||
if (mavenOptions.cacheArtifactNotFound().isPresent()) {
|
||||
cmdAndArguments.add("--cache-artifact-not-found");
|
||||
cmdAndArguments.add(mavenOptions.cacheArtifactNotFound().get().toString());
|
||||
}
|
||||
if (mavenOptions.strictArtifactDescriptorPolicy().isPresent()) {
|
||||
cmdAndArguments.add("--strict-artifact-descriptor-policy");
|
||||
cmdAndArguments.add(
|
||||
mavenOptions.strictArtifactDescriptorPolicy().get().toString());
|
||||
}
|
||||
if (mavenOptions.ignoreTransitiveRepositories().isPresent()) {
|
||||
cmdAndArguments.add("--ignore-transitive-repositories");
|
||||
}
|
||||
// TODO: etc
|
||||
|
||||
// last the goals
|
||||
cmdAndArguments.addAll(mavenOptions.goals().orElse(Collections.emptyList()));
|
||||
|
|
|
@ -25,11 +25,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.maven.api.cli.Logger;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvokerRequest;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
import org.apache.maven.cling.invoker.mvn.DefaultMavenInvokerRequest;
|
||||
|
||||
/**
|
||||
|
@ -41,14 +40,12 @@ public class DefaultForkedMavenInvokerRequest extends DefaultMavenInvokerRequest
|
|||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
public DefaultForkedMavenInvokerRequest(
|
||||
String command,
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Logger logger,
|
||||
MessageBuilderFactory messageBuilderFactory,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
InputStream in,
|
||||
|
@ -58,14 +55,12 @@ public class DefaultForkedMavenInvokerRequest extends DefaultMavenInvokerRequest
|
|||
List<String> jvmArguments,
|
||||
MavenOptions options) {
|
||||
super(
|
||||
command,
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
logger,
|
||||
messageBuilderFactory,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
in,
|
||||
|
@ -78,6 +73,6 @@ public class DefaultForkedMavenInvokerRequest extends DefaultMavenInvokerRequest
|
|||
|
||||
@Override
|
||||
public Optional<List<String>> jvmArguments() {
|
||||
return Optional.of(jvmArguments);
|
||||
return Optional.ofNullable(jvmArguments);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ package org.apache.maven.cling.invoker.mvn.forked;
|
|||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -53,14 +52,12 @@ public class DefaultForkedMavenParser extends DefaultMavenParser<MavenOptions, F
|
|||
ArrayList<CoreExtension> extensions,
|
||||
Options options) {
|
||||
return new DefaultForkedMavenInvokerRequest(
|
||||
parserRequest.command(),
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
parserRequest.logger(),
|
||||
parserRequest.messageBuilderFactory(),
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
parserRequest.in(),
|
||||
|
@ -74,15 +71,15 @@ public class DefaultForkedMavenParser extends DefaultMavenParser<MavenOptions, F
|
|||
protected List<String> getJvmArguments(Path rootDirectory) {
|
||||
if (rootDirectory != null) {
|
||||
// TODO: do this
|
||||
return Collections.emptyList();
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MavenOptions parseArgs(String source, String[] args) throws ParserException {
|
||||
protected MavenOptions parseArgs(String source, List<String> args) throws ParserException {
|
||||
try {
|
||||
return CommonsCliMavenOptions.parse(source, args);
|
||||
return CommonsCliMavenOptions.parse(source, args.toArray(new String[0]));
|
||||
} catch (ParseException e) {
|
||||
throw new ParserException("Failed to parse source " + source, e.getCause());
|
||||
}
|
||||
|
|
|
@ -52,14 +52,12 @@ public class DefaultLocalMavenParser extends DefaultMavenParser<MavenOptions, Ma
|
|||
ArrayList<CoreExtension> extensions,
|
||||
Options options) {
|
||||
return new DefaultMavenInvokerRequest<>(
|
||||
parserRequest.command(),
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
parserRequest.logger(),
|
||||
parserRequest.messageBuilderFactory(),
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
parserRequest.in(),
|
||||
|
@ -70,9 +68,9 @@ public class DefaultLocalMavenParser extends DefaultMavenParser<MavenOptions, Ma
|
|||
}
|
||||
|
||||
@Override
|
||||
protected MavenOptions parseArgs(String source, String[] args) throws ParserException {
|
||||
protected MavenOptions parseArgs(String source, List<String> args) throws ParserException {
|
||||
try {
|
||||
return CommonsCliMavenOptions.parse(source, args);
|
||||
return CommonsCliMavenOptions.parse(source, args.toArray(new String[0]));
|
||||
} catch (ParseException e) {
|
||||
throw new ParserException("Failed to parse source " + source, e.getCause());
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ public class DefaultResidentMavenInvoker
|
|||
super.close();
|
||||
}
|
||||
|
||||
public LocalContext createShadow() {
|
||||
public LocalContext copy(ResidentMavenInvokerRequest invokerRequest) {
|
||||
LocalContext shadow = new LocalContext((DefaultResidentMavenInvoker) invoker, invokerRequest);
|
||||
|
||||
shadow.logger = logger;
|
||||
|
@ -122,10 +122,12 @@ public class DefaultResidentMavenInvoker
|
|||
throw new InvokerException("Failed to init master context", e);
|
||||
}
|
||||
})
|
||||
.createShadow();
|
||||
.copy(invokerRequest);
|
||||
}
|
||||
|
||||
protected String getContextId(ResidentMavenInvokerRequest invokerRequest) {
|
||||
// TODO: in a moment Maven stop pushing user properties to system properties (and maybe something more)
|
||||
// and allow multiple instances per JVM, this may become a pool?
|
||||
return "resident";
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,10 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.maven.api.cli.Logger;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvn.resident.ResidentMavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
import org.apache.maven.cling.invoker.mvn.DefaultMavenInvokerRequest;
|
||||
|
||||
/**
|
||||
|
@ -41,14 +40,12 @@ public class DefaultResidentMavenInvokerRequest extends DefaultMavenInvokerReque
|
|||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
public DefaultResidentMavenInvokerRequest(
|
||||
String command,
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Logger logger,
|
||||
MessageBuilderFactory messageBuilderFactory,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
InputStream in,
|
||||
|
@ -58,14 +55,12 @@ public class DefaultResidentMavenInvokerRequest extends DefaultMavenInvokerReque
|
|||
List<String> jvmArguments,
|
||||
ResidentMavenOptions options) {
|
||||
super(
|
||||
command,
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
logger,
|
||||
messageBuilderFactory,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
in,
|
||||
|
|
|
@ -51,14 +51,12 @@ public class DefaultResidentMavenParser extends DefaultMavenParser<ResidentMaven
|
|||
ArrayList<CoreExtension> extensions,
|
||||
Options options) {
|
||||
return new DefaultResidentMavenInvokerRequest(
|
||||
parserRequest.command(),
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
parserRequest.logger(),
|
||||
parserRequest.messageBuilderFactory(),
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
parserRequest.in(),
|
||||
|
@ -78,9 +76,9 @@ public class DefaultResidentMavenParser extends DefaultMavenParser<ResidentMaven
|
|||
}
|
||||
|
||||
@Override
|
||||
protected ResidentMavenOptions parseArgs(String source, String[] args) throws ParserException {
|
||||
protected ResidentMavenOptions parseArgs(String source, List<String> args) throws ParserException {
|
||||
try {
|
||||
return CommonsCliResidentMavenOptions.parse(source, args);
|
||||
return CommonsCliResidentMavenOptions.parse(source, args.toArray(new String[0]));
|
||||
} catch (ParseException e) {
|
||||
throw new ParserException("Failed to parse source " + source, e.getCause());
|
||||
}
|
||||
|
|
|
@ -25,12 +25,11 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.apache.maven.api.annotations.Nonnull;
|
||||
import org.apache.maven.api.cli.Logger;
|
||||
import org.apache.maven.api.cli.Options;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvnenc.EncryptInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvnenc.EncryptOptions;
|
||||
import org.apache.maven.api.services.MessageBuilderFactory;
|
||||
import org.apache.maven.cling.invoker.BaseInvokerRequest;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
@ -40,14 +39,12 @@ public class DefaultEncryptInvokerRequest extends BaseInvokerRequest<EncryptOpti
|
|||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
public DefaultEncryptInvokerRequest(
|
||||
String command,
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Logger logger,
|
||||
MessageBuilderFactory messageBuilderFactory,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
InputStream in,
|
||||
|
@ -56,14 +53,12 @@ public class DefaultEncryptInvokerRequest extends BaseInvokerRequest<EncryptOpti
|
|||
List<CoreExtension> coreExtensions,
|
||||
Options options) {
|
||||
super(
|
||||
command,
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
logger,
|
||||
messageBuilderFactory,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
in,
|
||||
|
|
|
@ -49,14 +49,12 @@ public class DefaultEncryptParser extends BaseParser<EncryptOptions, EncryptInvo
|
|||
ArrayList<CoreExtension> extensions,
|
||||
Options options) {
|
||||
return new DefaultEncryptInvokerRequest(
|
||||
parserRequest.command(),
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
parserRequest.logger(),
|
||||
parserRequest.messageBuilderFactory(),
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
parserRequest.in(),
|
||||
|
@ -67,13 +65,13 @@ public class DefaultEncryptParser extends BaseParser<EncryptOptions, EncryptInvo
|
|||
}
|
||||
|
||||
@Override
|
||||
protected List<EncryptOptions> parseCliOptions(Path rootDirectory, String[] args) throws ParserException {
|
||||
protected List<EncryptOptions> parseCliOptions(Path rootDirectory, List<String> args) throws ParserException {
|
||||
return Collections.singletonList(parseEncryptCliOptions(args));
|
||||
}
|
||||
|
||||
protected CommonsCliEncryptOptions parseEncryptCliOptions(String[] args) throws ParserException {
|
||||
protected CommonsCliEncryptOptions parseEncryptCliOptions(List<String> args) throws ParserException {
|
||||
try {
|
||||
return CommonsCliEncryptOptions.parse(args);
|
||||
return CommonsCliEncryptOptions.parse(args.toArray(new String[0]));
|
||||
} catch (ParseException e) {
|
||||
throw new ParserException("Failed to parse command line options: " + e.getMessage(), e);
|
||||
}
|
||||
|
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.maven.cling.invoker.forked;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import org.apache.maven.cling.invoker.ProtoLogger;
|
||||
import org.apache.maven.cling.invoker.mvn.forked.DefaultForkedMavenInvoker;
|
||||
import org.apache.maven.cling.invoker.mvn.forked.DefaultForkedMavenParser;
|
||||
import org.apache.maven.jline.JLineMessageBuilderFactory;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
@Disabled("Works ONLY with Maven4!")
|
||||
public class DefaultForkedMavenInvokerTest {
|
||||
@Test
|
||||
void smoke(@TempDir Path tempDir) throws Exception {
|
||||
try (DefaultForkedMavenInvoker invoker = new DefaultForkedMavenInvoker()) {
|
||||
Files.createDirectory(tempDir.resolve(".mvn"));
|
||||
Path log = tempDir.resolve("build.log").toAbsolutePath();
|
||||
int exitcode = invoker.invoke(new DefaultForkedMavenParser()
|
||||
.parse(
|
||||
"mvn",
|
||||
new String[] {"-l", log.toString(), "clean"},
|
||||
new ProtoLogger(),
|
||||
new JLineMessageBuilderFactory()));
|
||||
System.out.println("exit code: " + exitcode);
|
||||
System.out.println("log:");
|
||||
System.out.println(Files.readString(log));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* 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.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.maven.api.cli.Invoker;
|
||||
import org.apache.maven.api.cli.Parser;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.cling.invoker.ProtoLogger;
|
||||
import org.apache.maven.jline.JLineMessageBuilderFactory;
|
||||
import org.junit.jupiter.api.Assumptions;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public abstract class MavenInvokerTestSupport<O extends MavenOptions, R extends MavenInvokerRequest<O>> {
|
||||
|
||||
protected void invoke(Path cwd, Collection<String> goals) throws Exception {
|
||||
// works only in recent Maven4
|
||||
Assumptions.assumeTrue(Files.isRegularFile(
|
||||
Paths.get(System.getProperty("maven.home")).resolve("conf").resolve("maven.properties")));
|
||||
|
||||
Files.createDirectory(cwd.resolve(".mvn"));
|
||||
|
||||
String pomString =
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.maven.samples</groupId>
|
||||
<artifactId>sample</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit-bom</artifactId>
|
||||
<version>5.11.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
""";
|
||||
Path pom = cwd.resolve("pom.xml").toAbsolutePath();
|
||||
Files.writeString(pom, pomString);
|
||||
|
||||
String appJavaString =
|
||||
"""
|
||||
package org.apache.maven.samples.sample;
|
||||
|
||||
public class App {
|
||||
public static void main(String... args) {
|
||||
System.out.println("Hello World!");
|
||||
}
|
||||
}
|
||||
""";
|
||||
Path appJava = cwd.resolve("src/main/java/org/apache/maven/samples/sample/App.java");
|
||||
Files.createDirectories(appJava.getParent());
|
||||
Files.writeString(appJava, appJavaString);
|
||||
|
||||
Parser<R> parser = createParser();
|
||||
try (Invoker<R> invoker = createInvoker()) {
|
||||
for (String goal : goals) {
|
||||
Path logFile = cwd.resolve(goal + "-build.log").toAbsolutePath();
|
||||
int exitCode = invoker.invoke(parser.parse(ParserRequest.mvn(
|
||||
List.of("-l", logFile.toString(), goal),
|
||||
new ProtoLogger(),
|
||||
new JLineMessageBuilderFactory())
|
||||
.cwd(cwd)
|
||||
.build()));
|
||||
String log = Files.readString(logFile);
|
||||
assertEquals(0, exitCode, log);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract Invoker<R> createInvoker();
|
||||
|
||||
protected abstract Parser<R> createParser();
|
||||
}
|
|
@ -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.cling.invoker.mvn.forked;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.maven.api.cli.Invoker;
|
||||
import org.apache.maven.api.cli.Parser;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvokerRequest;
|
||||
import org.apache.maven.cling.invoker.mvn.MavenInvokerTestSupport;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.CleanupMode;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
/**
|
||||
* Forked UT: it cannot use jimFS as it runs in child process.
|
||||
*/
|
||||
public class DefaultForkedMavenInvokerTest extends MavenInvokerTestSupport<MavenOptions, ForkedMavenInvokerRequest> {
|
||||
|
||||
@Override
|
||||
protected Invoker<ForkedMavenInvokerRequest> createInvoker() {
|
||||
return new DefaultForkedMavenInvoker();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parser<ForkedMavenInvokerRequest> createParser() {
|
||||
return new DefaultForkedMavenParser();
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultFs(@TempDir(cleanup = CleanupMode.ON_SUCCESS) Path tempDir) throws Exception {
|
||||
invoke(tempDir, Arrays.asList("clean", "verify"));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
package org.apache.maven.cling.invoker.mvn.local;
|
||||
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.google.common.jimfs.Configuration;
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.apache.maven.api.cli.Invoker;
|
||||
import org.apache.maven.api.cli.Parser;
|
||||
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.cling.invoker.ProtoLookup;
|
||||
import org.apache.maven.cling.invoker.mvn.MavenInvokerTestSupport;
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.CleanupMode;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
/**
|
||||
* Local UT.
|
||||
*/
|
||||
public class DefaultLocalMavenInvokerTest
|
||||
extends MavenInvokerTestSupport<MavenOptions, MavenInvokerRequest<MavenOptions>> {
|
||||
@Override
|
||||
protected Invoker<MavenInvokerRequest<MavenOptions>> createInvoker() {
|
||||
return new DefaultLocalMavenInvoker(ProtoLookup.builder()
|
||||
.addMapping(ClassWorld.class, new ClassWorld("plexus.core", ClassLoader.getSystemClassLoader()))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parser<MavenInvokerRequest<MavenOptions>> createParser() {
|
||||
return new DefaultLocalMavenParser();
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultFs(@TempDir(cleanup = CleanupMode.ON_SUCCESS) Path tempDir) throws Exception {
|
||||
invoke(tempDir, Arrays.asList("clean", "verify"));
|
||||
}
|
||||
|
||||
@Disabled("Until we move off fully from File")
|
||||
@Test
|
||||
void jimFs() throws Exception {
|
||||
try (FileSystem fs = Jimfs.newFileSystem(Configuration.unix())) {
|
||||
invoke(fs.getPath("/"), Arrays.asList("clean", "verify"));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,94 +18,52 @@
|
|||
*/
|
||||
package org.apache.maven.cling.invoker.mvn.resident;
|
||||
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.FileSystem;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.mvn.resident.ResidentMavenParser;
|
||||
import org.apache.maven.cling.invoker.ProtoLogger;
|
||||
import com.google.common.jimfs.Configuration;
|
||||
import com.google.common.jimfs.Jimfs;
|
||||
import org.apache.maven.api.cli.Invoker;
|
||||
import org.apache.maven.api.cli.Parser;
|
||||
import org.apache.maven.api.cli.mvn.resident.ResidentMavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.resident.ResidentMavenOptions;
|
||||
import org.apache.maven.cling.invoker.ProtoLookup;
|
||||
import org.apache.maven.jline.JLineMessageBuilderFactory;
|
||||
import org.apache.maven.cling.invoker.mvn.MavenInvokerTestSupport;
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.CleanupMode;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
@Disabled("Works ONLY with Maven4!")
|
||||
public class DefaultResidentMavenInvokerTest {
|
||||
/**
|
||||
* Resident UT.
|
||||
*/
|
||||
public class DefaultResidentMavenInvokerTest
|
||||
extends MavenInvokerTestSupport<ResidentMavenOptions, ResidentMavenInvokerRequest> {
|
||||
|
||||
@Override
|
||||
protected Invoker<ResidentMavenInvokerRequest> createInvoker() {
|
||||
return new DefaultResidentMavenInvoker(ProtoLookup.builder()
|
||||
.addMapping(ClassWorld.class, new ClassWorld("plexus.core", ClassLoader.getSystemClassLoader()))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Parser<ResidentMavenInvokerRequest> createParser() {
|
||||
return new DefaultResidentMavenParser();
|
||||
}
|
||||
|
||||
@Test
|
||||
void smoke(@TempDir Path tempDir) throws Exception {
|
||||
try (ClassWorld classWorld =
|
||||
new ClassWorld("plexus.core", Thread.currentThread().getContextClassLoader());
|
||||
DefaultResidentMavenInvoker invoker = new DefaultResidentMavenInvoker(ProtoLookup.builder()
|
||||
.addMapping(ClassWorld.class, classWorld)
|
||||
.build())) {
|
||||
ResidentMavenParser parser = new DefaultResidentMavenParser();
|
||||
Files.createDirectory(tempDir.resolve(".mvn"));
|
||||
Path log = tempDir.resolve("build.log").toAbsolutePath();
|
||||
void defaultFs(@TempDir(cleanup = CleanupMode.ON_SUCCESS) Path tempDir) throws Exception {
|
||||
invoke(tempDir, Arrays.asList("clean", "verify"));
|
||||
}
|
||||
|
||||
String pomString =
|
||||
"""
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.apache.maven.samples</groupId>
|
||||
<artifactId>resident-invoker</artifactId>
|
||||
<version>1.0.0</version>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.junit</groupId>
|
||||
<artifactId>junit-bom</artifactId>
|
||||
<version>5.11.1</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-api</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
""";
|
||||
Path pom = tempDir.resolve("pom.xml").toAbsolutePath();
|
||||
Files.writeString(pom, pomString);
|
||||
|
||||
int exitCode;
|
||||
|
||||
exitCode = invoker.invoke(parser.parse(ParserRequest.builder(
|
||||
"mvn",
|
||||
new String[] {"-l", log.toString(), "clean"},
|
||||
new ProtoLogger(),
|
||||
new JLineMessageBuilderFactory())
|
||||
.cwd(tempDir)
|
||||
.build()));
|
||||
System.out.println("1st exit code: " + exitCode);
|
||||
System.out.println("log:");
|
||||
System.out.println(Files.readString(log));
|
||||
|
||||
exitCode = invoker.invoke(parser.parse(ParserRequest.builder(
|
||||
"mvn",
|
||||
new String[] {"-l", log.toString(), "clean"},
|
||||
new ProtoLogger(),
|
||||
new JLineMessageBuilderFactory())
|
||||
.cwd(tempDir)
|
||||
.build()));
|
||||
System.out.println("2nd exit code: " + exitCode);
|
||||
System.out.println("log:");
|
||||
System.out.println(Files.readString(log));
|
||||
@Disabled("Until we move off fully from File")
|
||||
@Test
|
||||
void jimFs() throws Exception {
|
||||
try (FileSystem fs = Jimfs.newFileSystem(Configuration.unix())) {
|
||||
invoke(fs.getPath("/"), Arrays.asList("clean", "verify"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue