mirror of https://github.com/apache/maven.git
[MNG-8283] Make resident able to restore state (#1779)
And move all logic out of invoke. Also, parser and other improvements, mostly adding "extension points" in form of overridable protected method. --- https://issues.apache.org/jira/browse/MNG-8283
This commit is contained in:
parent
20fe966770
commit
e369ce5782
|
@ -60,94 +60,91 @@ import static org.apache.maven.cling.invoker.Utils.stripLeadingAndTrailingQuotes
|
|||
import static org.apache.maven.cling.invoker.Utils.toMap;
|
||||
|
||||
public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>> implements Parser<R> {
|
||||
|
||||
@SuppressWarnings("VisibilityModifier")
|
||||
public static class LocalContext {
|
||||
public final ParserRequest parserRequest;
|
||||
public final Map<String, String> systemPropertiesOverrides;
|
||||
|
||||
public LocalContext(ParserRequest parserRequest) {
|
||||
this.parserRequest = parserRequest;
|
||||
this.systemPropertiesOverrides = new HashMap<>();
|
||||
}
|
||||
|
||||
public Path cwd;
|
||||
public Path installationDirectory;
|
||||
public Path userHomeDirectory;
|
||||
public Map<String, String> systemProperties;
|
||||
public Map<String, String> userProperties;
|
||||
public Path topDirectory;
|
||||
public Path rootDirectory;
|
||||
public List<CoreExtension> extensions;
|
||||
public Options options;
|
||||
|
||||
public Map<String, String> extraInterpolationSource() {
|
||||
Map<String, String> extra = new HashMap<>();
|
||||
extra.put("session.topDirectory", topDirectory.toString());
|
||||
extra.put("session.rootDirectory", rootDirectory.toString());
|
||||
return extra;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public R parse(ParserRequest parserRequest) throws ParserException, IOException {
|
||||
requireNonNull(parserRequest);
|
||||
|
||||
LocalContext context = new LocalContext(parserRequest);
|
||||
|
||||
// the basics
|
||||
HashMap<String, String> overrides = new HashMap<>();
|
||||
Path cwd = requireNonNull(getCwd(parserRequest, overrides));
|
||||
Path installationDirectory = requireNonNull(getInstallationDirectory(parserRequest, overrides));
|
||||
Path userHomeDirectory = requireNonNull(getUserHomeDirectory(parserRequest, overrides));
|
||||
context.cwd = requireNonNull(getCwd(context));
|
||||
context.installationDirectory = requireNonNull(getInstallationDirectory(context));
|
||||
context.userHomeDirectory = requireNonNull(getUserHomeDirectory(context));
|
||||
|
||||
// top/root
|
||||
Path topDirectory = requireNonNull(getTopDirectory(parserRequest, cwd));
|
||||
Path rootDirectory = requireNonNull(getRootDirectory(parserRequest, cwd, topDirectory));
|
||||
context.topDirectory = requireNonNull(getTopDirectory(context));
|
||||
context.rootDirectory = requireNonNull(getRootDirectory(context));
|
||||
|
||||
// options
|
||||
List<O> parsedOptions = parseCliOptions(rootDirectory, parserRequest.args());
|
||||
List<O> parsedOptions = parseCliOptions(context);
|
||||
|
||||
// warn about deprecated options
|
||||
parsedOptions.forEach(o -> o.warnAboutDeprecatedOptions(
|
||||
parserRequest, new PrintWriter(parserRequest.out() != null ? parserRequest.out() : System.out, true)));
|
||||
|
||||
// assemble options if needed
|
||||
O options = assembleOptions(parsedOptions);
|
||||
context.options = assembleOptions(parsedOptions);
|
||||
|
||||
// system and user properties
|
||||
Map<String, String> systemProperties = populateSystemProperties(overrides);
|
||||
Map<String, String> paths = new HashMap<>();
|
||||
paths.put("session.topDirectory", topDirectory.toString());
|
||||
paths.put("session.rootDirectory", rootDirectory.toString());
|
||||
Map<String, String> userProperties =
|
||||
populateUserProperties(systemProperties, installationDirectory, paths, options);
|
||||
context.systemProperties = populateSystemProperties(context);
|
||||
context.userProperties = populateUserProperties(context);
|
||||
|
||||
// options: interpolate
|
||||
Options interpolatedOptions = options.interpolate(Arrays.asList(paths, systemProperties, userProperties));
|
||||
context.options = context.options.interpolate(
|
||||
Arrays.asList(context.extraInterpolationSource(), context.userProperties, context.systemProperties));
|
||||
|
||||
// core extensions
|
||||
ArrayList<CoreExtension> extensions = new ArrayList<>();
|
||||
String installationExtensionsFile = userProperties.get(Constants.MAVEN_INSTALLATION_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptor(installationExtensionsFile, installationDirectory));
|
||||
context.extensions = readCoreExtensionsDescriptor(context);
|
||||
|
||||
String projectExtensionsFile = userProperties.get(Constants.MAVEN_PROJECT_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptor(projectExtensionsFile, cwd));
|
||||
|
||||
String userExtensionsFile = userProperties.get(Constants.MAVEN_USER_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptor(userExtensionsFile, userHomeDirectory));
|
||||
|
||||
return getInvokerRequest(
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
extensions,
|
||||
interpolatedOptions);
|
||||
return getInvokerRequest(context);
|
||||
}
|
||||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
protected abstract R getInvokerRequest(
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
ArrayList<CoreExtension> extensions,
|
||||
Options options);
|
||||
protected abstract R getInvokerRequest(LocalContext context);
|
||||
|
||||
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());
|
||||
protected Path getCwd(LocalContext context) throws ParserException {
|
||||
if (context.parserRequest.cwd() != null) {
|
||||
Path result = getCanonicalPath(context.parserRequest.cwd());
|
||||
context.systemPropertiesOverrides.put("user.dir", result.toString());
|
||||
return result;
|
||||
} else {
|
||||
return getCanonicalPath(Paths.get(System.getProperty("user.dir")));
|
||||
}
|
||||
}
|
||||
|
||||
protected Path getInstallationDirectory(ParserRequest parserRequest, Map<String, String> overrides)
|
||||
throws ParserException {
|
||||
protected Path getInstallationDirectory(LocalContext context) throws ParserException {
|
||||
Path result;
|
||||
if (parserRequest.mavenHome() != null) {
|
||||
result = getCanonicalPath(parserRequest.mavenHome());
|
||||
overrides.put(MAVEN_HOME, result.toString());
|
||||
if (context.parserRequest.mavenHome() != null) {
|
||||
result = getCanonicalPath(context.parserRequest.mavenHome());
|
||||
context.systemPropertiesOverrides.put(MAVEN_HOME, result.toString());
|
||||
} else {
|
||||
String mavenHome = System.getProperty(Constants.MAVEN_HOME);
|
||||
if (mavenHome == null) {
|
||||
|
@ -158,23 +155,22 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
return result;
|
||||
}
|
||||
|
||||
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());
|
||||
protected Path getUserHomeDirectory(LocalContext context) throws ParserException {
|
||||
if (context.parserRequest.userHome() != null) {
|
||||
Path result = getCanonicalPath(context.parserRequest.userHome());
|
||||
context.systemPropertiesOverrides.put("user.home", result.toString());
|
||||
return result;
|
||||
} else {
|
||||
return getCanonicalPath(Paths.get(System.getProperty("user.home")));
|
||||
}
|
||||
}
|
||||
|
||||
protected Path getTopDirectory(ParserRequest parserRequest, Path cwd) throws ParserException {
|
||||
protected Path getTopDirectory(LocalContext context) throws ParserException {
|
||||
// We need to locate the top level project which may be pointed at using
|
||||
// the -f/--file option.
|
||||
Path topDirectory = cwd;
|
||||
Path topDirectory = requireNonNull(context.cwd);
|
||||
boolean isAltFile = false;
|
||||
for (String arg : parserRequest.args()) {
|
||||
for (String arg : context.parserRequest.args()) {
|
||||
if (isAltFile) {
|
||||
// this is the argument following -f/--file
|
||||
Path path = topDirectory.resolve(stripLeadingAndTrailingQuotes(arg));
|
||||
|
@ -199,32 +195,34 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
return getCanonicalPath(topDirectory);
|
||||
}
|
||||
|
||||
protected Path getRootDirectory(ParserRequest parserRequest, Path cwd, Path topDirectory) throws ParserException {
|
||||
protected Path getRootDirectory(LocalContext context) throws ParserException {
|
||||
RootLocator rootLocator =
|
||||
ServiceLoader.load(RootLocator.class).iterator().next();
|
||||
Path rootDirectory = rootLocator.findRoot(topDirectory);
|
||||
Path rootDirectory = rootLocator.findRoot(requireNonNull(context.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(
|
||||
: getCanonicalPath(context.cwd.resolve(requireNonNull(
|
||||
System.getProperty("maven.multiModuleProjectDirectory"),
|
||||
"maven.multiModuleProjectDirectory is not set")));
|
||||
if (rootDirectory == null) {
|
||||
parserRequest.logger().warn(rootLocator.getNoRootMessage());
|
||||
context.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");
|
||||
context.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 {
|
||||
protected Map<String, String> populateSystemProperties(LocalContext context) throws ParserException {
|
||||
Properties systemProperties = new Properties();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -248,18 +246,11 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
systemProperties.setProperty("maven.build.version", mavenBuildVersion);
|
||||
|
||||
Map<String, String> result = toMap(systemProperties);
|
||||
if (overrides != null) {
|
||||
result.putAll(overrides);
|
||||
}
|
||||
result.putAll(context.systemPropertiesOverrides);
|
||||
return result;
|
||||
}
|
||||
|
||||
protected Map<String, String> populateUserProperties(
|
||||
Map<String, String> systemProperties,
|
||||
Path installationDirectory,
|
||||
Map<String, String> paths,
|
||||
Options options)
|
||||
throws ParserException, IOException {
|
||||
protected Map<String, String> populateUserProperties(LocalContext context) throws ParserException, IOException {
|
||||
Properties userProperties = new Properties();
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
@ -268,47 +259,63 @@ public abstract class BaseParser<O extends Options, R extends InvokerRequest<O>>
|
|||
// are most dominant.
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
Map<String, String> userSpecifiedProperties = options.userProperties().orElse(new HashMap<>());
|
||||
userProperties.putAll(userSpecifiedProperties);
|
||||
Map<String, String> userSpecifiedProperties =
|
||||
context.options.userProperties().orElse(new HashMap<>());
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
// Load config files
|
||||
// ----------------------------------------------------------------------
|
||||
Map<String, String> paths = context.extraInterpolationSource();
|
||||
Function<String, String> callback =
|
||||
or(paths::get, prefix("cli.", userSpecifiedProperties::get), systemProperties::get);
|
||||
or(paths::get, prefix("cli.", userSpecifiedProperties::get), context.systemProperties::get);
|
||||
|
||||
Path mavenConf;
|
||||
if (systemProperties.get(MAVEN_INSTALLATION_CONF) != null) {
|
||||
mavenConf = installationDirectory.resolve(systemProperties.get(MAVEN_INSTALLATION_CONF));
|
||||
} else if (systemProperties.get("maven.conf") != null) {
|
||||
mavenConf = installationDirectory.resolve(systemProperties.get("maven.conf"));
|
||||
} else if (systemProperties.get(MAVEN_HOME) != null) {
|
||||
mavenConf = installationDirectory
|
||||
.resolve(systemProperties.get(MAVEN_HOME))
|
||||
if (context.systemProperties.get(MAVEN_INSTALLATION_CONF) != null) {
|
||||
mavenConf = context.installationDirectory.resolve(context.systemProperties.get(MAVEN_INSTALLATION_CONF));
|
||||
} else if (context.systemProperties.get("maven.conf") != null) {
|
||||
mavenConf = context.installationDirectory.resolve(context.systemProperties.get("maven.conf"));
|
||||
} else if (context.systemProperties.get(MAVEN_HOME) != null) {
|
||||
mavenConf = context.installationDirectory
|
||||
.resolve(context.systemProperties.get(MAVEN_HOME))
|
||||
.resolve("conf");
|
||||
} else {
|
||||
mavenConf = installationDirectory.resolve("");
|
||||
mavenConf = context.installationDirectory.resolve("");
|
||||
}
|
||||
Path propertiesFile = mavenConf.resolve("maven.properties");
|
||||
MavenPropertiesLoader.loadProperties(userProperties, propertiesFile, callback, false);
|
||||
|
||||
// CLI specified properties are most dominant
|
||||
userProperties.putAll(userSpecifiedProperties);
|
||||
|
||||
return toMap(userProperties);
|
||||
}
|
||||
|
||||
protected abstract List<O> parseCliOptions(Path rootDirectory, List<String> args)
|
||||
throws ParserException, IOException;
|
||||
protected abstract List<O> parseCliOptions(LocalContext context) throws ParserException, IOException;
|
||||
|
||||
protected abstract O assembleOptions(List<O> parsedOptions);
|
||||
|
||||
protected List<CoreExtension> readCoreExtensionsDescriptor(String extensionsFile, Path cwd)
|
||||
protected List<CoreExtension> readCoreExtensionsDescriptor(LocalContext context)
|
||||
throws ParserException, IOException {
|
||||
ArrayList<CoreExtension> extensions = new ArrayList<>();
|
||||
String installationExtensionsFile = context.userProperties.get(Constants.MAVEN_INSTALLATION_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptorFromFile(
|
||||
context.installationDirectory.resolve(installationExtensionsFile)));
|
||||
|
||||
String projectExtensionsFile = context.userProperties.get(Constants.MAVEN_PROJECT_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptorFromFile(context.cwd.resolve(projectExtensionsFile)));
|
||||
|
||||
String userExtensionsFile = context.userProperties.get(Constants.MAVEN_USER_EXTENSIONS);
|
||||
extensions.addAll(readCoreExtensionsDescriptorFromFile(context.userHomeDirectory.resolve(userExtensionsFile)));
|
||||
|
||||
return extensions;
|
||||
}
|
||||
|
||||
protected List<CoreExtension> readCoreExtensionsDescriptorFromFile(Path extensionsFile)
|
||||
throws ParserException, IOException {
|
||||
try {
|
||||
if (extensionsFile != null) {
|
||||
Path extensionsPath = cwd.resolve(extensionsFile);
|
||||
if (Files.exists(extensionsPath)) {
|
||||
try (InputStream is = Files.newInputStream(extensionsPath)) {
|
||||
return new CoreExtensionsStaxReader().read(is, true).getExtensions();
|
||||
}
|
||||
if (extensionsFile != null && Files.exists(extensionsFile)) {
|
||||
try (InputStream is = Files.newInputStream(extensionsFile)) {
|
||||
return new CoreExtensionsStaxReader().read(is, true).getExtensions();
|
||||
}
|
||||
}
|
||||
return List.of();
|
||||
|
|
|
@ -403,6 +403,10 @@ public abstract class CommonsCliOptions implements Options {
|
|||
return commandLine;
|
||||
}
|
||||
|
||||
public org.apache.commons.cli.Options getOptions() {
|
||||
return options;
|
||||
}
|
||||
|
||||
public Set<Option> getUsedDeprecatedOptions() {
|
||||
return usedDeprecatedOptions;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,19 @@ public abstract class LookupInvoker<
|
|||
O extends Options, R extends InvokerRequest<O>, C extends LookupInvoker.LookupInvokerContext<O, R, C>>
|
||||
implements Invoker<R> {
|
||||
|
||||
/**
|
||||
* Exception for intentional exit: No message or anything will be displayed, just the
|
||||
* carried exit code will be returned from {@link #invoke(InvokerRequest)} method.
|
||||
*/
|
||||
public static final class ExitException extends InvokerException {
|
||||
private final int exitCode;
|
||||
|
||||
public ExitException(int exitCode) {
|
||||
super("EXIT");
|
||||
this.exitCode = exitCode;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("VisibilityModifier")
|
||||
public static class LookupInvokerContext<
|
||||
O extends Options, R extends InvokerRequest<O>, C extends LookupInvokerContext<O, R, C>>
|
||||
|
@ -124,6 +137,7 @@ public abstract class LookupInvoker<
|
|||
public ILoggerFactory loggerFactory;
|
||||
public Slf4jConfiguration slf4jConfiguration;
|
||||
public Slf4jConfiguration.Level loggerLevel;
|
||||
public ClassLoader currentThreadContextClassLoader;
|
||||
public ContainerCapsule containerCapsule;
|
||||
public Lookup lookup;
|
||||
public SettingsBuilder settingsBuilder;
|
||||
|
@ -153,51 +167,41 @@ public abstract class LookupInvoker<
|
|||
public int invoke(R invokerRequest) throws InvokerException {
|
||||
requireNonNull(invokerRequest);
|
||||
|
||||
Properties oldProps = (Properties) System.getProperties().clone();
|
||||
ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
|
||||
try (C context = createContext(invokerRequest)) {
|
||||
Properties props = (Properties) System.getProperties().clone();
|
||||
try {
|
||||
HashSet<String> sys =
|
||||
new HashSet<>(invokerRequest.systemProperties().keySet());
|
||||
invokerRequest.userProperties().entrySet().stream()
|
||||
.filter(k -> !sys.contains(k.getKey()))
|
||||
.forEach(k -> System.setProperty(k.getKey(), k.getValue()));
|
||||
System.setProperty(
|
||||
Constants.MAVEN_HOME,
|
||||
invokerRequest.installationDirectory().toString());
|
||||
|
||||
validate(context);
|
||||
prepare(context);
|
||||
configureLogging(context);
|
||||
activateLogging(context);
|
||||
|
||||
if (invokerRequest.options().help().isPresent()) {
|
||||
invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), context.stdOut);
|
||||
return 0;
|
||||
if (context.currentThreadContextClassLoader != null) {
|
||||
Thread.currentThread().setContextClassLoader(context.currentThreadContextClassLoader);
|
||||
}
|
||||
if (invokerRequest.options().showVersionAndExit().isPresent()) {
|
||||
if (invokerRequest.options().quiet().orElse(false)) {
|
||||
context.stdOut.println(CLIReportingUtils.showVersionMinimal());
|
||||
} else {
|
||||
context.stdOut.println(CLIReportingUtils.showVersion());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
preCommands(context);
|
||||
container(context);
|
||||
lookup(context);
|
||||
init(context);
|
||||
postCommands(context);
|
||||
settings(context);
|
||||
return execute(context);
|
||||
return doInvoke(context);
|
||||
} catch (ExitException e) {
|
||||
return e.exitCode;
|
||||
} catch (Exception e) {
|
||||
throw handleException(context, e);
|
||||
} finally {
|
||||
System.setProperties(props);
|
||||
}
|
||||
} finally {
|
||||
Thread.currentThread().setContextClassLoader(oldCL);
|
||||
System.setProperties(oldProps);
|
||||
}
|
||||
}
|
||||
|
||||
protected int doInvoke(C context) throws Exception {
|
||||
pushProperties(context);
|
||||
validate(context);
|
||||
prepare(context);
|
||||
configureLogging(context);
|
||||
activateLogging(context);
|
||||
helpOrVersionAndMayExit(context);
|
||||
preCommands(context);
|
||||
container(context);
|
||||
lookup(context);
|
||||
init(context);
|
||||
postCommands(context);
|
||||
settings(context);
|
||||
return execute(context);
|
||||
}
|
||||
|
||||
protected InvokerException handleException(LookupInvokerContext<O, R, C> context, Exception e)
|
||||
throws InvokerException {
|
||||
boolean showStackTrace = context.invokerRequest.options().showErrors().orElse(false);
|
||||
|
@ -217,6 +221,16 @@ public abstract class LookupInvoker<
|
|||
|
||||
protected abstract C createContext(R invokerRequest) throws InvokerException;
|
||||
|
||||
protected void pushProperties(C context) throws Exception {
|
||||
R invokerRequest = context.invokerRequest;
|
||||
HashSet<String> sys = new HashSet<>(invokerRequest.systemProperties().keySet());
|
||||
invokerRequest.userProperties().entrySet().stream()
|
||||
.filter(k -> !sys.contains(k.getKey()))
|
||||
.forEach(k -> System.setProperty(k.getKey(), k.getValue()));
|
||||
System.setProperty(
|
||||
Constants.MAVEN_HOME, invokerRequest.installationDirectory().toString());
|
||||
}
|
||||
|
||||
protected void validate(C context) throws Exception {}
|
||||
|
||||
protected void prepare(C context) throws Exception {}
|
||||
|
@ -298,6 +312,22 @@ public abstract class LookupInvoker<
|
|||
}
|
||||
}
|
||||
|
||||
protected void helpOrVersionAndMayExit(C context) throws Exception {
|
||||
R invokerRequest = context.invokerRequest;
|
||||
if (invokerRequest.options().help().isPresent()) {
|
||||
invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), context.stdOut);
|
||||
throw new ExitException(0);
|
||||
}
|
||||
if (invokerRequest.options().showVersionAndExit().isPresent()) {
|
||||
if (invokerRequest.options().quiet().orElse(false)) {
|
||||
context.stdOut.println(CLIReportingUtils.showVersionMinimal());
|
||||
} else {
|
||||
context.stdOut.println(CLIReportingUtils.showVersion());
|
||||
}
|
||||
throw new ExitException(0);
|
||||
}
|
||||
}
|
||||
|
||||
protected void preCommands(C context) throws Exception {
|
||||
Options mavenOptions = context.invokerRequest.options();
|
||||
if (mavenOptions.verbose().orElse(false) || mavenOptions.showVersion().orElse(false)) {
|
||||
|
|
|
@ -57,6 +57,7 @@ import org.codehaus.plexus.PlexusConstants;
|
|||
import org.codehaus.plexus.PlexusContainer;
|
||||
import org.codehaus.plexus.classworlds.ClassWorld;
|
||||
import org.codehaus.plexus.classworlds.realm.ClassRealm;
|
||||
import org.codehaus.plexus.logging.LoggerManager;
|
||||
import org.slf4j.ILoggerFactory;
|
||||
|
||||
import static org.apache.maven.cling.invoker.Utils.toPlexusLoggingLevel;
|
||||
|
@ -110,9 +111,10 @@ public class PlexusContainerCapsuleFactory<
|
|||
|
||||
// NOTE: To avoid inconsistencies, we'll use the TCCL exclusively for lookups
|
||||
container.setLookupRealm(null);
|
||||
context.currentThreadContextClassLoader = container.getContainerRealm();
|
||||
Thread.currentThread().setContextClassLoader(container.getContainerRealm());
|
||||
|
||||
container.setLoggerManager(new Slf4jLoggerManager());
|
||||
container.setLoggerManager(createLoggerManager());
|
||||
R invokerRequest = context.invokerRequest;
|
||||
Function<String, String> extensionSource = expression -> {
|
||||
String value = invokerRequest.userProperties().get(expression);
|
||||
|
@ -167,6 +169,10 @@ public class PlexusContainerCapsuleFactory<
|
|||
};
|
||||
}
|
||||
|
||||
protected LoggerManager createLoggerManager() {
|
||||
return new Slf4jLoggerManager();
|
||||
}
|
||||
|
||||
protected void customizeContainerConfiguration(C context, ContainerConfiguration configuration) throws Exception {}
|
||||
|
||||
protected void customizeContainer(C context, PlexusContainer container) throws Exception {}
|
||||
|
@ -261,7 +267,7 @@ public class PlexusContainerCapsuleFactory<
|
|||
ClassLoader oldCL = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
container.setLookupRealm(null);
|
||||
container.setLoggerManager(new Slf4jLoggerManager());
|
||||
container.setLoggerManager(createLoggerManager());
|
||||
container.getLoggerManager().setThresholds(toPlexusLoggingLevel(context.loggerLevel));
|
||||
Thread.currentThread().setContextClassLoader(container.getContainerRealm());
|
||||
|
||||
|
|
|
@ -24,13 +24,10 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.maven.api.cli.Options;
|
||||
import org.apache.maven.api.cli.ParserException;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.api.cli.mvn.MavenParser;
|
||||
|
@ -38,27 +35,14 @@ import org.apache.maven.cling.invoker.BaseParser;
|
|||
|
||||
public abstract class BaseMavenParser<O extends MavenOptions, R extends MavenInvokerRequest<O>> extends BaseParser<O, R>
|
||||
implements MavenParser<R> {
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
@Override
|
||||
protected abstract R getInvokerRequest(
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
ArrayList<CoreExtension> extensions,
|
||||
Options options);
|
||||
|
||||
@Override
|
||||
protected List<O> parseCliOptions(Path rootDirectory, List<String> args) throws ParserException, IOException {
|
||||
protected List<O> parseCliOptions(LocalContext context) throws ParserException, IOException {
|
||||
ArrayList<O> result = new ArrayList<>();
|
||||
// CLI args
|
||||
result.add(parseMavenCliOptions(args));
|
||||
result.add(parseMavenCliOptions(context.parserRequest.args()));
|
||||
// maven.config; if exists
|
||||
Path mavenConfig = rootDirectory.resolve(".mvn/maven.config");
|
||||
Path mavenConfig = context.rootDirectory.resolve(".mvn/maven.config");
|
||||
if (Files.isRegularFile(mavenConfig)) {
|
||||
result.add(parseMavenConfigOptions(mavenConfig));
|
||||
}
|
||||
|
|
|
@ -18,49 +18,32 @@
|
|||
*/
|
||||
package org.apache.maven.cling.invoker.mvn;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.maven.api.cli.Options;
|
||||
import org.apache.maven.api.cli.ParserException;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.api.cli.mvn.MavenParser;
|
||||
|
||||
public class DefaultMavenParser extends BaseMavenParser<MavenOptions, MavenInvokerRequest<MavenOptions>>
|
||||
implements MavenParser<MavenInvokerRequest<MavenOptions>> {
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
@Override
|
||||
protected DefaultMavenInvokerRequest<MavenOptions> getInvokerRequest(
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
ArrayList<CoreExtension> extensions,
|
||||
Options options) {
|
||||
protected DefaultMavenInvokerRequest<MavenOptions> getInvokerRequest(LocalContext context) {
|
||||
return new DefaultMavenInvokerRequest<>(
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
parserRequest.in(),
|
||||
parserRequest.out(),
|
||||
parserRequest.err(),
|
||||
extensions,
|
||||
(MavenOptions) options);
|
||||
context.parserRequest,
|
||||
context.cwd,
|
||||
context.installationDirectory,
|
||||
context.userHomeDirectory,
|
||||
context.userProperties,
|
||||
context.systemProperties,
|
||||
context.topDirectory,
|
||||
context.rootDirectory,
|
||||
context.parserRequest.in(),
|
||||
context.parserRequest.out(),
|
||||
context.parserRequest.err(),
|
||||
context.extensions,
|
||||
(MavenOptions) context.options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -19,15 +19,10 @@
|
|||
package org.apache.maven.cling.invoker.mvn.forked;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.maven.api.cli.Options;
|
||||
import org.apache.maven.api.cli.ParserException;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvn.MavenOptions;
|
||||
import org.apache.maven.api.cli.mvn.forked.ForkedMavenInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvn.forked.ForkedMavenParser;
|
||||
|
@ -40,32 +35,22 @@ public class DefaultForkedMavenParser extends BaseMavenParser<MavenOptions, Fork
|
|||
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
@Override
|
||||
protected ForkedMavenInvokerRequest getInvokerRequest(
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
ArrayList<CoreExtension> extensions,
|
||||
Options options) {
|
||||
protected ForkedMavenInvokerRequest getInvokerRequest(LocalContext context) {
|
||||
return new DefaultForkedMavenInvokerRequest(
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
parserRequest.in(),
|
||||
parserRequest.out(),
|
||||
parserRequest.err(),
|
||||
extensions,
|
||||
getJvmArguments(rootDirectory),
|
||||
(MavenOptions) options);
|
||||
context.parserRequest,
|
||||
context.cwd,
|
||||
context.installationDirectory,
|
||||
context.userHomeDirectory,
|
||||
context.userProperties,
|
||||
context.systemProperties,
|
||||
context.topDirectory,
|
||||
context.rootDirectory,
|
||||
context.parserRequest.in(),
|
||||
context.parserRequest.out(),
|
||||
context.parserRequest.err(),
|
||||
context.extensions,
|
||||
getJvmArguments(context.rootDirectory),
|
||||
(MavenOptions) context.options);
|
||||
}
|
||||
|
||||
protected List<String> getJvmArguments(Path rootDirectory) {
|
||||
|
|
|
@ -55,6 +55,9 @@ public class DefaultResidentMavenInvoker
|
|||
}
|
||||
|
||||
public LocalContext copy(MavenInvokerRequest<MavenOptions> invokerRequest) {
|
||||
if (invokerRequest == this.invokerRequest) {
|
||||
return this;
|
||||
}
|
||||
LocalContext shadow = new LocalContext((DefaultResidentMavenInvoker) invoker, invokerRequest);
|
||||
|
||||
shadow.logger = logger;
|
||||
|
@ -109,19 +112,7 @@ public class DefaultResidentMavenInvoker
|
|||
@Override
|
||||
protected LocalContext createContext(MavenInvokerRequest<MavenOptions> invokerRequest) {
|
||||
return residentContext
|
||||
.computeIfAbsent(getContextId(invokerRequest), k -> {
|
||||
LocalContext master = new LocalContext(this, invokerRequest);
|
||||
try {
|
||||
validate(master);
|
||||
prepare(master);
|
||||
configureLogging(master);
|
||||
container(master);
|
||||
lookup(master);
|
||||
return master;
|
||||
} catch (Exception e) {
|
||||
throw new InvokerException("Failed to init master context", e);
|
||||
}
|
||||
})
|
||||
.computeIfAbsent(getContextId(invokerRequest), k -> new LocalContext(this, invokerRequest))
|
||||
.copy(invokerRequest);
|
||||
}
|
||||
|
||||
|
@ -133,7 +124,7 @@ public class DefaultResidentMavenInvoker
|
|||
|
||||
@Override
|
||||
protected void container(LocalContext context) throws Exception {
|
||||
if (context.maven == null) {
|
||||
if (context.containerCapsule == null) {
|
||||
super.container(context);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,55 +18,38 @@
|
|||
*/
|
||||
package org.apache.maven.cling.invoker.mvnenc;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.cli.ParseException;
|
||||
import org.apache.maven.api.cli.Options;
|
||||
import org.apache.maven.api.cli.ParserException;
|
||||
import org.apache.maven.api.cli.ParserRequest;
|
||||
import org.apache.maven.api.cli.extensions.CoreExtension;
|
||||
import org.apache.maven.api.cli.mvnenc.EncryptInvokerRequest;
|
||||
import org.apache.maven.api.cli.mvnenc.EncryptOptions;
|
||||
import org.apache.maven.api.cli.mvnenc.EncryptParser;
|
||||
import org.apache.maven.cling.invoker.BaseParser;
|
||||
|
||||
public class DefaultEncryptParser extends BaseParser<EncryptOptions, EncryptInvokerRequest> implements EncryptParser {
|
||||
@SuppressWarnings("ParameterNumber")
|
||||
@Override
|
||||
protected EncryptInvokerRequest getInvokerRequest(
|
||||
ParserRequest parserRequest,
|
||||
Path cwd,
|
||||
Path installationDirectory,
|
||||
Path userHomeDirectory,
|
||||
Map<String, String> userProperties,
|
||||
Map<String, String> systemProperties,
|
||||
Path topDirectory,
|
||||
Path rootDirectory,
|
||||
ArrayList<CoreExtension> extensions,
|
||||
Options options) {
|
||||
protected EncryptInvokerRequest getInvokerRequest(LocalContext context) {
|
||||
return new DefaultEncryptInvokerRequest(
|
||||
parserRequest,
|
||||
cwd,
|
||||
installationDirectory,
|
||||
userHomeDirectory,
|
||||
userProperties,
|
||||
systemProperties,
|
||||
topDirectory,
|
||||
rootDirectory,
|
||||
parserRequest.in(),
|
||||
parserRequest.out(),
|
||||
parserRequest.err(),
|
||||
extensions,
|
||||
options);
|
||||
context.parserRequest,
|
||||
context.cwd,
|
||||
context.installationDirectory,
|
||||
context.userHomeDirectory,
|
||||
context.userProperties,
|
||||
context.systemProperties,
|
||||
context.topDirectory,
|
||||
context.rootDirectory,
|
||||
context.parserRequest.in(),
|
||||
context.parserRequest.out(),
|
||||
context.parserRequest.err(),
|
||||
context.extensions,
|
||||
context.options);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<EncryptOptions> parseCliOptions(Path rootDirectory, List<String> args) throws ParserException {
|
||||
return Collections.singletonList(parseEncryptCliOptions(args));
|
||||
protected List<EncryptOptions> parseCliOptions(LocalContext context) throws ParserException {
|
||||
return Collections.singletonList(parseEncryptCliOptions(context.parserRequest.args()));
|
||||
}
|
||||
|
||||
protected CommonsCliEncryptOptions parseEncryptCliOptions(List<String> args) throws ParserException {
|
||||
|
|
Loading…
Reference in New Issue