Skip to content

Commit

Permalink
[MNG-8283] More mvnd related changes (#1775)
Browse files Browse the repository at this point in the history
Changes:
* there is only one parser for "just maven", no need for 3
* aligned scopes (public) of local context for simplicity, we can fix visibility later
* allow custom guice modules (unused, may undo this)
* split logging setup in two steps: config and activate

---

https://issues.apache.org/jira/browse/MNG-8283
  • Loading branch information
cstamas authored Oct 4, 2024
1 parent 533790b commit 60ae468
Show file tree
Hide file tree
Showing 21 changed files with 173 additions and 632 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,16 @@
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.cli.InvokerException;
import org.apache.maven.api.cli.mvn.MavenInvoker;
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
import org.apache.maven.api.cli.mvn.MavenOptions;

/**
* Resident invoker. Instance is shut down when this instance is closed.
*
* @since 4.0.0
*/
@Experimental
public interface ResidentMavenInvoker extends MavenInvoker<ResidentMavenInvokerRequest> {
public interface ResidentMavenInvoker extends MavenInvoker<MavenInvokerRequest<MavenOptions>> {
/**
* Closes cleanly the daemon.
*/
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
import org.apache.maven.api.cli.mvn.MavenOptions;
import org.apache.maven.cling.invoker.ProtoLogger;
import org.apache.maven.cling.invoker.ProtoLookup;
import org.apache.maven.cling.invoker.mvn.DefaultMavenParser;
import org.apache.maven.cling.invoker.mvn.local.DefaultLocalMavenInvoker;
import org.apache.maven.cling.invoker.mvn.local.DefaultLocalMavenParser;
import org.apache.maven.jline.JLineMessageBuilderFactory;
import org.codehaus.plexus.classworlds.ClassWorld;

Expand Down Expand Up @@ -67,6 +67,6 @@ protected Invoker<MavenInvokerRequest<MavenOptions>> createInvoker() {

@Override
protected MavenInvokerRequest<MavenOptions> parseArguments(String[] args) throws ParserException, IOException {
return new DefaultLocalMavenParser().mvn(args, new ProtoLogger(), new JLineMessageBuilderFactory());
return new DefaultMavenParser().mvn(args, new ProtoLogger(), new JLineMessageBuilderFactory());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ protected LookupInvokerContext(LookupInvoker<O, R, C> invoker, R invokerRequest)

public Logger logger;
public ILoggerFactory loggerFactory;
public Slf4jConfiguration slf4jConfiguration;
public Slf4jConfiguration.Level loggerLevel;
public ContainerCapsule containerCapsule;
public Lookup lookup;
Expand Down Expand Up @@ -156,6 +157,7 @@ public int invoke(R invokerRequest) throws InvokerException {
validate(context);
prepare(context);
logging(context);
activateLogging(context);

if (invokerRequest.options().help().isPresent()) {
invokerRequest.options().displayHelp(context.invokerRequest.parserRequest(), context.stdOut);
Expand Down Expand Up @@ -231,15 +233,15 @@ protected void logging(C context) throws Exception {
}

context.loggerFactory = LoggerFactory.getILoggerFactory();
Slf4jConfiguration slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(context.loggerFactory);
context.slf4jConfiguration = Slf4jConfigurationFactory.getConfiguration(context.loggerFactory);

context.loggerLevel = Slf4jConfiguration.Level.INFO;
if (mavenOptions.verbose().orElse(false)) {
context.loggerLevel = Slf4jConfiguration.Level.DEBUG;
} else if (mavenOptions.quiet().orElse(false)) {
context.loggerLevel = Slf4jConfiguration.Level.ERROR;
}
slf4jConfiguration.setRootLoggerLevel(context.loggerLevel);
context.slf4jConfiguration.setRootLoggerLevel(context.loggerLevel);
// else fall back to default log level specified in conf
// see https://issues.apache.org/jira/browse/MNG-2570

Expand All @@ -255,8 +257,13 @@ protected void logging(C context) throws Exception {
throw new InvokerException("Cannot set up log " + e.getMessage(), e);
}
}
}

protected void activateLogging(C context) throws Exception {
R invokerRequest = context.invokerRequest;
Options mavenOptions = invokerRequest.options();

slf4jConfiguration.activate();
context.slf4jConfiguration.activate();
org.slf4j.Logger l = context.loggerFactory.getLogger(this.getClass().getName());
context.logger = (level, message, error) -> l.atLevel(org.slf4j.event.Level.valueOf(level.name()))
.setCause(error)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import java.util.function.Function;

import com.google.inject.AbstractModule;
import com.google.inject.Module;
import org.apache.maven.api.Constants;
import org.apache.maven.api.cli.InvokerException;
import org.apache.maven.api.cli.InvokerRequest;
Expand Down Expand Up @@ -103,16 +104,9 @@ protected PlexusContainer container(C context) throws Exception {
exportedArtifacts.addAll(extension.getExportedArtifacts());
exportedPackages.addAll(extension.getExportedPackages());
}
final CoreExports exports = new CoreExports(containerRealm, exportedArtifacts, exportedPackages);
CoreExports exports = new CoreExports(containerRealm, exportedArtifacts, exportedPackages);
Thread.currentThread().setContextClassLoader(containerRealm);
DefaultPlexusContainer container = new DefaultPlexusContainer(cc, new AbstractModule() {
@Override
protected void configure() {
bind(ILoggerFactory.class).toInstance(context.loggerFactory);
bind(CoreExports.class).toInstance(exports);
bind(MessageBuilderFactory.class).toInstance(context.invokerRequest.messageBuilderFactory());
}
});
DefaultPlexusContainer container = new DefaultPlexusContainer(cc, getCustomModule(context, exports));

// NOTE: To avoid inconsistencies, we'll use the TCCL exclusively for lookups
container.setLookupRealm(null);
Expand Down Expand Up @@ -157,6 +151,22 @@ protected void configure() {
return container;
}

/**
* Note: overriding this method should be avoided. Preferred way to replace Maven components is the "normal" way
* where the components are on index (are annotated with JSR330 annotations and Sisu index is created) and, they
* have priorities set.
*/
protected Module getCustomModule(C context, CoreExports exports) {
return new AbstractModule() {
@Override
protected void configure() {
bind(ILoggerFactory.class).toInstance(context.loggerFactory);
bind(CoreExports.class).toInstance(exports);
bind(MessageBuilderFactory.class).toInstance(context.invokerRequest.messageBuilderFactory());
}
};
}

protected void customizeContainerConfiguration(C context, ContainerConfiguration configuration) throws Exception {}

protected void customizeContainer(C context, PlexusContainer container) throws Exception {}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.cling.invoker.mvn;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import org.apache.maven.api.cli.Options;
import org.apache.maven.api.cli.ParserException;
import org.apache.maven.api.cli.ParserRequest;
import org.apache.maven.api.cli.extensions.CoreExtension;
import org.apache.maven.api.cli.mvn.MavenInvokerRequest;
import org.apache.maven.api.cli.mvn.MavenOptions;
import org.apache.maven.api.cli.mvn.MavenParser;
import org.apache.maven.cling.invoker.BaseParser;

public abstract class BaseMavenParser<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 {
ArrayList<O> result = new ArrayList<>();
// CLI args
result.add(parseMavenCliOptions(args));
// maven.config; if exists
Path mavenConfig = rootDirectory.resolve(".mvn/maven.config");
if (Files.isRegularFile(mavenConfig)) {
result.add(parseMavenConfigOptions(mavenConfig));
}
return result;
}

protected O parseMavenCliOptions(List<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())) {
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)
throw new ParserException("Unrecognized maven.config file entries: "
+ options.goals().get());
}
return options;
}
}

protected abstract O parseArgs(String source, List<String> args) throws ParserException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ public abstract class DefaultMavenInvoker<
extends LookupInvoker<O, R, C> implements MavenInvoker<R> {

@SuppressWarnings("VisibilityModifier")
protected static class MavenContext<
public static class MavenContext<
O extends MavenOptions,
R extends MavenInvokerRequest<O>,
C extends DefaultMavenInvoker.MavenContext<O, R, C>>
Expand Down
Loading

0 comments on commit 60ae468

Please sign in to comment.