Get rid of maven-shared-utils (#1158)

Given maven-shared-utils is being deprecated (see MSHARED-1269), we need to remove its usage in maven.  Maven core only uses the logging/message related classes from maven-shared-utils, so this PR enhance the initial v4 api with the needed interfaces and move the jansi specific code into maven-embedder.
This commit is contained in:
Guillaume Nodet 2023-06-15 16:51:32 +02:00 committed by GitHub
parent 967d8fc19c
commit a2d435b74a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 789 additions and 146 deletions

View File

@ -28,13 +28,22 @@ import org.apache.maven.api.annotations.Nonnull;
*/
public interface MessageBuilder {
/**
* Append message content in success style.
* By default, bold green
* Append message content in debug style.
* By default, bold cyan
* @param message the message to append
* @return the current builder
*/
@Nonnull
MessageBuilder success(Object message);
MessageBuilder debug(Object message);
/**
* Append message content in info style.
* By default, bold blue
* @param message the message to append
* @return the current builder
*/
@Nonnull
MessageBuilder info(Object message);
/**
* Append message content in warning style.
@ -45,6 +54,24 @@ public interface MessageBuilder {
@Nonnull
MessageBuilder warning(Object message);
/**
* Append message content in error style.
* By default, bold red
* @param message the message to append
* @return the current builder
*/
@Nonnull
MessageBuilder error(Object message);
/**
* Append message content in success style.
* By default, bold green
* @param message the message to append
* @return the current builder
*/
@Nonnull
MessageBuilder success(Object message);
/**
* Append message content in failure style.
* By default, bold red

View File

@ -99,10 +99,6 @@ under the License.
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-util</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-shared-utils</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.plexus</artifactId>

View File

@ -24,106 +24,128 @@ import org.apache.maven.api.services.MessageBuilder;
@Experimental
public class DefaultMessageBuilder implements MessageBuilder {
private final @Nonnull org.apache.maven.shared.utils.logging.MessageBuilder delegate;
public DefaultMessageBuilder(@Nonnull org.apache.maven.shared.utils.logging.MessageBuilder delegate) {
this.delegate = delegate;
private final StringBuilder buffer;
public DefaultMessageBuilder() {
this(new StringBuilder());
}
public DefaultMessageBuilder(StringBuilder buffer) {
this.buffer = buffer;
}
@Override
@Nonnull
public MessageBuilder success(Object o) {
delegate.success(o);
return this;
public MessageBuilder debug(Object o) {
return a(o);
}
@Override
@Nonnull
public MessageBuilder info(Object o) {
return a(o);
}
@Override
@Nonnull
public MessageBuilder warning(Object o) {
delegate.warning(o);
return this;
return a(o);
}
@Override
@Nonnull
public MessageBuilder error(Object o) {
return a(o);
}
@Override
@Nonnull
public MessageBuilder success(Object o) {
return a(o);
}
@Override
@Nonnull
public MessageBuilder failure(Object o) {
delegate.failure(o);
return this;
return a(o);
}
@Override
@Nonnull
public MessageBuilder strong(Object o) {
delegate.strong(o);
return this;
return a(o);
}
@Override
@Nonnull
public MessageBuilder mojo(Object o) {
delegate.mojo(o);
return this;
return a(o);
}
@Override
@Nonnull
public MessageBuilder project(Object o) {
delegate.project(o);
return this;
return a(o);
}
@Override
@Nonnull
public MessageBuilder a(char[] chars, int i, int i1) {
delegate.a(chars, i, i1);
buffer.append(chars, i, i1);
return this;
}
@Override
@Nonnull
public MessageBuilder a(char[] chars) {
delegate.a(chars);
buffer.append(chars);
return this;
}
@Override
@Nonnull
public MessageBuilder a(CharSequence charSequence, int i, int i1) {
delegate.a(charSequence, i, i1);
buffer.append(charSequence, i, i1);
return this;
}
@Override
@Nonnull
public MessageBuilder a(CharSequence charSequence) {
delegate.a(charSequence);
buffer.append(charSequence);
return this;
}
@Override
@Nonnull
public MessageBuilder a(Object o) {
delegate.a(o);
buffer.append(o);
return this;
}
@Override
@Nonnull
public MessageBuilder newline() {
delegate.newline();
buffer.append(System.getProperty("line.separator"));
return this;
}
@Override
@Nonnull
public MessageBuilder format(String s, Object... objects) {
delegate.format(s, objects);
buffer.append(String.format(s, objects));
return this;
}
@Override
@Nonnull
public String build() {
return delegate.toString();
return buffer.toString();
}
@Override
public String toString() {
return build();
}
}

View File

@ -18,6 +18,8 @@
*/
package org.apache.maven.internal.impl;
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
@ -27,32 +29,35 @@ import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.shared.utils.logging.MessageUtils;
@Experimental
@Named
@Singleton
@Priority(-1)
public class DefaultMessageBuilderFactory implements MessageBuilderFactory {
@Inject
public DefaultMessageBuilderFactory() {}
@Override
public boolean isColorEnabled() {
return MessageUtils.isColorEnabled();
return false;
}
@Override
public int getTerminalWidth() {
return MessageUtils.getTerminalWidth();
return -1;
}
@Override
@Nonnull
public MessageBuilder builder() {
return new DefaultMessageBuilder(MessageUtils.buffer());
return new DefaultMessageBuilder();
}
@Override
@Nonnull
public MessageBuilder builder(@Nonnull StringBuilder stringBuilder) {
return new DefaultMessageBuilder(MessageUtils.buffer(Objects.requireNonNull(stringBuilder)));
return new DefaultMessageBuilder(Objects.requireNonNull(stringBuilder));
}
}

View File

@ -18,11 +18,11 @@
*/
package org.apache.maven.lifecycle;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.internal.impl.DefaultMessageBuilderFactory;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
/**
* @author <a href="mailto:jason@maven.org">Jason van Zyl</a>
@ -58,15 +58,27 @@ public class LifecycleExecutionException extends Exception {
}
public LifecycleExecutionException(MojoExecution execution, MavenProject project, Throwable cause) {
this(createMessage(execution, project, cause), execution, project, cause);
this(new DefaultMessageBuilderFactory(), execution, project, cause);
}
public LifecycleExecutionException(
MessageBuilderFactory messageBuilderFactory,
MojoExecution execution,
MavenProject project,
Throwable cause) {
this(createMessage(messageBuilderFactory, execution, project, cause), execution, project, cause);
}
public MavenProject getProject() {
return project;
}
private static String createMessage(MojoExecution execution, MavenProject project, Throwable cause) {
MessageBuilder buffer = buffer(256);
private static String createMessage(
MessageBuilderFactory messageBuilderFactory,
MojoExecution execution,
MavenProject project,
Throwable cause) {
MessageBuilder buffer = messageBuilderFactory.builder(256);
buffer.a("Failed to execute goal");

View File

@ -18,6 +18,7 @@
*/
package org.apache.maven.lifecycle.internal;
import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
@ -26,6 +27,8 @@ import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.api.xml.XmlNode;
import org.apache.maven.internal.xml.XmlNodeImpl;
import org.apache.maven.lifecycle.MojoExecutionConfigurator;
@ -35,8 +38,6 @@ import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -50,6 +51,9 @@ import static java.util.Arrays.stream;
public class DefaultMojoExecutionConfigurator implements MojoExecutionConfigurator {
private final Logger logger = LoggerFactory.getLogger(getClass());
@Inject
MessageBuilderFactory messageBuilderFactory;
@Override
public void configure(MavenProject project, MojoExecution mojoExecution, boolean allowPluginLevelConfig) {
String g = mojoExecution.getPlugin().getGroupId();
@ -136,7 +140,8 @@ public class DefaultMojoExecutionConfigurator implements MojoExecutionConfigurat
unknownParameters = getUnknownParameters(mojoExecution, parametersNamesAll);
unknownParameters.forEach(name -> {
MessageBuilder messageBuilder = MessageUtils.buffer()
MessageBuilder messageBuilder = messageBuilderFactory
.builder()
.warning("Parameter '")
.warning(name)
.warning("' is unknown for plugin '")

View File

@ -33,6 +33,7 @@ import java.util.Set;
import java.util.stream.Collectors;
import org.apache.maven.RepositoryUtils;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.ArtifactUtils;
import org.apache.maven.eventspy.internal.EventSpyDispatcher;
@ -75,16 +76,20 @@ public class LifecycleDependencyResolver {
private final ProjectArtifactsCache projectArtifactsCache;
private final MessageBuilderFactory messageBuilderFactory;
@Inject
public LifecycleDependencyResolver(
ProjectDependenciesResolver dependenciesResolver,
ProjectArtifactFactory artifactFactory,
EventSpyDispatcher eventSpyDispatcher,
ProjectArtifactsCache projectArtifactsCache) {
ProjectArtifactsCache projectArtifactsCache,
MessageBuilderFactory messageBuilderFactory) {
this.dependenciesResolver = dependenciesResolver;
this.artifactFactory = artifactFactory;
this.eventSpyDispatcher = eventSpyDispatcher;
this.projectArtifactsCache = projectArtifactsCache;
this.messageBuilderFactory = messageBuilderFactory;
}
public static List<MavenProject> getProjects(MavenProject project, MavenSession session, boolean aggregator) {
@ -253,7 +258,7 @@ public class LifecycleDependencyResolver {
logger.warn("Try running the build up to the lifecycle phase \"package\"");
} else {
throw new LifecycleExecutionException(null, project, e);
throw new LifecycleExecutionException(messageBuilderFactory, null, project, e);
}
}

View File

@ -36,6 +36,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
import org.apache.maven.artifact.resolver.filter.CumulativeScopeArtifactFilter;
@ -86,6 +87,8 @@ public class MojoExecutor {
private final Provider<MojosExecutionStrategy> mojosExecutionStrategy;
private final MessageBuilderFactory messageBuilderFactory;
private final Map<Thread, MojoDescriptor> mojos = new ConcurrentHashMap<>();
@Inject
@ -94,12 +97,14 @@ public class MojoExecutor {
MavenPluginManager mavenPluginManager,
LifecycleDependencyResolver lifeCycleDependencyResolver,
ExecutionEventCatapult eventCatapult,
Provider<MojosExecutionStrategy> mojosExecutionStrategy) {
Provider<MojosExecutionStrategy> mojosExecutionStrategy,
MessageBuilderFactory messageBuilderFactory) {
this.pluginManager = pluginManager;
this.mavenPluginManager = mavenPluginManager;
this.lifeCycleDependencyResolver = lifeCycleDependencyResolver;
this.eventCatapult = eventCatapult;
this.mojosExecutionStrategy = mojosExecutionStrategy;
this.messageBuilderFactory = messageBuilderFactory;
}
public DependencyContext newDependencyContext(MavenSession session, List<MojoExecution> mojoExecutions) {
@ -185,7 +190,7 @@ public class MojoExecutor {
try {
mavenPluginManager.checkPrerequisites(mojoDescriptor.getPluginDescriptor());
} catch (PluginIncompatibleException e) {
throw new LifecycleExecutionException(mojoExecution, session.getCurrentProject(), e);
throw new LifecycleExecutionException(messageBuilderFactory, mojoExecution, session.getCurrentProject(), e);
}
if (mojoDescriptor.isProjectRequired() && !session.getRequest().isProjectPresent()) {
@ -193,14 +198,15 @@ public class MojoExecutor {
"Goal requires a project to execute" + " but there is no POM in this directory ("
+ session.getExecutionRootDirectory() + ")."
+ " Please verify you invoked Maven from the correct directory.");
throw new LifecycleExecutionException(mojoExecution, null, cause);
throw new LifecycleExecutionException(messageBuilderFactory, mojoExecution, null, cause);
}
if (mojoDescriptor.isOnlineRequired() && session.isOffline()) {
if (MojoExecution.Source.CLI.equals(mojoExecution.getSource())) {
Throwable cause = new IllegalStateException(
"Goal requires online mode for execution" + " but Maven is currently offline.");
throw new LifecycleExecutionException(mojoExecution, session.getCurrentProject(), cause);
throw new LifecycleExecutionException(
messageBuilderFactory, mojoExecution, session.getCurrentProject(), cause);
} else {
eventCatapult.fire(ExecutionEvent.Type.MojoSkipped, session, mojoExecution);
@ -329,7 +335,8 @@ public class MojoExecutor {
| PluginManagerException
| PluginConfigurationException
| MojoExecutionException e) {
throw new LifecycleExecutionException(mojoExecution, session.getCurrentProject(), e);
throw new LifecycleExecutionException(
messageBuilderFactory, mojoExecution, session.getCurrentProject(), e);
}
eventCatapult.fire(ExecutionEvent.Type.MojoSucceeded, session, mojoExecution);

View File

@ -22,11 +22,11 @@ import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.PluginValidationManager;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.plugin.descriptor.Parameter;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
import org.codehaus.plexus.configuration.PlexusConfiguration;
@ -39,9 +39,13 @@ import org.codehaus.plexus.configuration.PlexusConfiguration;
@Named
class DeprecatedPluginValidator extends AbstractMavenPluginDescriptorSourcedParametersValidator {
private final MessageBuilderFactory messageBuilderFactory;
@Inject
DeprecatedPluginValidator(PluginValidationManager pluginValidationManager) {
DeprecatedPluginValidator(
PluginValidationManager pluginValidationManager, MessageBuilderFactory messageBuilderFactory) {
super(pluginValidationManager);
this.messageBuilderFactory = messageBuilderFactory;
}
@Override
@ -94,7 +98,8 @@ class DeprecatedPluginValidator extends AbstractMavenPluginDescriptorSourcedPara
}
private String logDeprecatedMojo(MojoDescriptor mojoDescriptor) {
return MessageUtils.buffer()
return messageBuilderFactory
.builder()
.warning("Goal '")
.warning(mojoDescriptor.getGoal())
.warning("' is deprecated: ")

View File

@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.lifecycle.LifecycleExecutionException;
import org.apache.maven.lifecycle.internal.ExecutionEventCatapult;
@ -47,7 +48,7 @@ public class MojoExecutorStub extends MojoExecutor { // This is being lazy inste
public final List<MojoExecution> executions = Collections.synchronizedList(new ArrayList<>());
public MojoExecutorStub() {
super(null, null, null, null, null);
super(null, null, null, null, null, null);
}
public MojoExecutorStub(
@ -55,8 +56,15 @@ public class MojoExecutorStub extends MojoExecutor { // This is being lazy inste
MavenPluginManager mavenPluginManager,
LifecycleDependencyResolver lifeCycleDependencyResolver,
ExecutionEventCatapult eventCatapult,
Provider<MojosExecutionStrategy> mojosExecutionStrategy) {
super(pluginManager, mavenPluginManager, lifeCycleDependencyResolver, eventCatapult, mojosExecutionStrategy);
Provider<MojosExecutionStrategy> mojosExecutionStrategy,
MessageBuilderFactory messageBuilderFactory) {
super(
pluginManager,
mavenPluginManager,
lifeCycleDependencyResolver,
eventCatapult,
mojosExecutionStrategy,
messageBuilderFactory);
}
@Override

View File

@ -72,10 +72,6 @@ under the License.
<groupId>org.apache.maven.resolver</groupId>
<artifactId>maven-resolver-util</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-shared-utils</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-slf4j-wrapper</artifactId>
@ -146,6 +142,11 @@ under the License.
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
@ -156,11 +157,6 @@ under the License.
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>

View File

@ -28,7 +28,7 @@ import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.apache.maven.cli.jansi.MessageUtils;
/**
* @author Jason van Zyl

View File

@ -25,11 +25,10 @@ import java.util.Date;
import java.util.Locale;
import java.util.Properties;
import org.apache.maven.cli.jansi.MessageUtils;
import org.codehaus.plexus.util.Os;
import org.slf4j.Logger;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
/**
* Utility class used to report errors, statistics, application version info, etc.
*
@ -54,7 +53,8 @@ public final class CLIReportingUtils {
final String ls = System.lineSeparator();
Properties properties = getBuildProperties();
StringBuilder version = new StringBuilder(256);
version.append(buffer().strong(createMavenVersionString(properties))).append(ls);
version.append(MessageUtils.builder().strong(createMavenVersionString(properties)))
.append(ls);
version.append(reduce(properties.getProperty("distributionShortName") + " home: "
+ System.getProperty("maven.home", "<unknown Maven " + "home>")))
.append(ls);

View File

@ -46,6 +46,8 @@ import org.apache.commons.cli.UnrecognizedOptionException;
import org.apache.maven.BuildAbort;
import org.apache.maven.InternalErrorException;
import org.apache.maven.Maven;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.building.FileSource;
import org.apache.maven.building.Problem;
import org.apache.maven.building.Source;
@ -56,6 +58,8 @@ import org.apache.maven.cli.event.ExecutionEventLogger;
import org.apache.maven.cli.internal.BootstrapCoreExtensionManager;
import org.apache.maven.cli.internal.extension.model.CoreExtension;
import org.apache.maven.cli.internal.extension.model.io.xpp3.CoreExtensionsXpp3Reader;
import org.apache.maven.cli.jansi.JansiMessageBuilderFactory;
import org.apache.maven.cli.jansi.MessageUtils;
import org.apache.maven.cli.logging.Slf4jConfiguration;
import org.apache.maven.cli.logging.Slf4jConfigurationFactory;
import org.apache.maven.cli.logging.Slf4jLoggerManager;
@ -87,8 +91,6 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.properties.internal.EnvironmentUtils;
import org.apache.maven.properties.internal.SystemProperties;
import org.apache.maven.session.scope.internal.SessionScopeModule;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.apache.maven.toolchain.building.DefaultToolchainsBuildingRequest;
import org.apache.maven.toolchain.building.ToolchainsBuilder;
import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
@ -124,7 +126,6 @@ import static org.apache.maven.cli.CLIManager.COLOR;
import static org.apache.maven.cli.CLIManager.FORCE_INTERACTIVE;
import static org.apache.maven.cli.CLIManager.NON_INTERACTIVE;
import static org.apache.maven.cli.ResolveFile.resolveFile;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
// TODO push all common bits back to plexus cli and prepare for transition to Guice. We don't need 50 ways to make CLIs
@ -177,6 +178,8 @@ public class MavenCli {
private CLIManager cliManager;
private MessageBuilderFactory messageBuilderFactory;
private static final Pattern NEXT_LINE = Pattern.compile("\r?\n");
public MavenCli() {
@ -186,6 +189,7 @@ public class MavenCli {
// This supports painless invocation by the Verifier during embedded execution of the core ITs
public MavenCli(ClassWorld classWorld) {
this.classWorld = classWorld;
this.messageBuilderFactory = new JansiMessageBuilderFactory();
}
public static void main(String[] args) {
@ -589,13 +593,12 @@ public class MavenCli {
if (slf4jLogger.isDebugEnabled()) {
slf4jLogger.debug("Message scheme: {}", (MessageUtils.isColorEnabled() ? "color" : "plain"));
if (MessageUtils.isColorEnabled()) {
MessageBuilder buff = MessageUtils.buffer();
MessageBuilder buff = MessageUtils.builder();
buff.a("Message styles: ");
buff.a(MessageUtils.level().debug("debug")).a(' ');
buff.a(MessageUtils.level().info("info")).a(' ');
buff.a(MessageUtils.level().warning("warning")).a(' ');
buff.a(MessageUtils.level().error("error")).a(' ');
buff.debug("debug").a(' ');
buff.info("info").a(' ');
buff.warning("warning").a(' ');
buff.error("error").a(' ');
buff.success("success").a(' ');
buff.failure("failure").a(' ');
buff.strong("strong").a(' ');
@ -679,6 +682,7 @@ public class MavenCli {
protected void configure() {
bind(ILoggerFactory.class).toInstance(slf4jLoggerFactory);
bind(CoreExports.class).toInstance(exports);
bind(MessageBuilderFactory.class).toInstance(messageBuilderFactory);
}
});
@ -964,10 +968,12 @@ public class MavenCli {
if (!cliRequest.showErrors) {
slf4jLogger.error(
"To see the full stack trace of the errors, re-run Maven with the '{}' switch",
buffer().strong("-e"));
MessageUtils.builder().strong("-e"));
}
if (!slf4jLogger.isDebugEnabled()) {
slf4jLogger.error("Re-run Maven using the '{}' switch to enable verbose output", buffer().strong("-X"));
slf4jLogger.error(
"Re-run Maven using the '{}' switch to enable verbose output",
MessageUtils.builder().strong("-X"));
}
if (!references.isEmpty()) {
@ -976,7 +982,7 @@ public class MavenCli {
+ ", please read the following articles:");
for (Map.Entry<String, String> entry : references.entrySet()) {
slf4jLogger.error("{} {}", buffer().strong(entry.getValue()), entry.getKey());
slf4jLogger.error("{} {}", MessageUtils.builder().strong(entry.getValue()), entry.getKey());
}
}
@ -1010,7 +1016,7 @@ public class MavenCli {
private void logBuildResumeHint(String resumeBuildHint) {
slf4jLogger.error("");
slf4jLogger.error("After correcting the problems, you can resume the build with the command");
slf4jLogger.error(buffer().a(" ").strong(resumeBuildHint).toString());
slf4jLogger.error(MessageUtils.builder().a(" ").strong(resumeBuildHint).toString());
}
/**
@ -1059,9 +1065,9 @@ public class MavenCli {
if (referenceKey != null && !referenceKey.isEmpty()) {
if (msg.indexOf('\n') < 0) {
msg += " -> " + buffer().strong(referenceKey);
msg += " -> " + MessageUtils.builder().strong(referenceKey);
} else {
msg += "\n-> " + buffer().strong(referenceKey);
msg += "\n-> " + MessageUtils.builder().strong(referenceKey);
}
}
@ -1425,7 +1431,7 @@ public class MavenCli {
}
private ExecutionListener determineExecutionListener() {
ExecutionListener executionListener = new ExecutionEventLogger();
ExecutionListener executionListener = new ExecutionEventLogger(messageBuilderFactory);
if (eventSpyDispatcher != null) {
return eventSpyDispatcher.chainListener(executionListener);
} else {

View File

@ -23,6 +23,8 @@ import java.nio.file.Path;
import java.util.List;
import java.util.Objects;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
import org.apache.maven.execution.AbstractExecutionListener;
import org.apache.maven.execution.BuildFailure;
import org.apache.maven.execution.BuildSuccess;
@ -35,8 +37,6 @@ import org.apache.maven.logwrapper.MavenSlf4jWrapperFactory;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.plugin.descriptor.MojoDescriptor;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.logging.MessageBuilder;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.codehaus.plexus.util.StringUtils;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
@ -44,7 +44,6 @@ import org.slf4j.LoggerFactory;
import static org.apache.maven.cli.CLIReportingUtils.formatDuration;
import static org.apache.maven.cli.CLIReportingUtils.formatTimestamp;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
/**
* Logs execution events to logger, eventually user-supplied.
@ -52,8 +51,6 @@ import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
* @author Benjamin Bentmann
*/
public class ExecutionEventLogger extends AbstractExecutionListener {
private final Logger logger;
private static final int MAX_LOG_PREFIX_SIZE = 8; // "[ERROR] "
private static final int PROJECT_STATUS_SUFFIX_SIZE = 20; // "SUCCESS [ 0.000 s]"
private static final int MIN_TERMINAL_WIDTH = 60;
@ -61,26 +58,25 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
private static final int MAX_TERMINAL_WIDTH = 130;
private static final int MAX_PADDED_BUILD_TIME_DURATION_LENGTH = 9;
private final MessageBuilderFactory messageBuilderFactory;
private final Logger logger;
private final int terminalWidth;
private final int lineLength;
private final int maxProjectNameLength;
private int totalProjects;
private volatile int currentVisitedProjectCount;
public ExecutionEventLogger() {
this(LoggerFactory.getLogger(ExecutionEventLogger.class));
public ExecutionEventLogger(MessageBuilderFactory messageBuilderFactory) {
this(messageBuilderFactory, LoggerFactory.getLogger(ExecutionEventLogger.class));
}
public ExecutionEventLogger(int terminalWidth) {
this(LoggerFactory.getLogger(ExecutionEventLogger.class), terminalWidth);
public ExecutionEventLogger(MessageBuilderFactory messageBuilderFactory, Logger logger) {
this(messageBuilderFactory, logger, messageBuilderFactory.getTerminalWidth());
}
public ExecutionEventLogger(Logger logger) {
this(logger, MessageUtils.getTerminalWidth());
}
public ExecutionEventLogger(Logger logger, int terminalWidth) {
public ExecutionEventLogger(MessageBuilderFactory messageBuilderFactory, Logger logger, int terminalWidth) {
this.logger = Objects.requireNonNull(logger, "logger cannot be null");
this.messageBuilderFactory = messageBuilderFactory;
this.terminalWidth = Math.min(
MAX_TERMINAL_WIDTH,
Math.max(terminalWidth < 0 ? DEFAULT_TERMINAL_WIDTH : terminalWidth, MIN_TERMINAL_WIDTH));
@ -103,7 +99,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
}
private void infoMain(String msg) {
logger.info(buffer().strong(msg).toString());
logger.info(builder().strong(msg).toString());
}
@Override
@ -225,9 +221,9 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
BuildSummary buildSummary = result.getBuildSummary(project);
if (buildSummary == null) {
buffer.append(buffer().warning("SKIPPED"));
buffer.append(builder().warning("SKIPPED"));
} else if (buildSummary instanceof BuildSuccess) {
buffer.append(buffer().success("SUCCESS"));
buffer.append(builder().success("SUCCESS"));
buffer.append(" [");
String buildTimeDuration = formatDuration(buildSummary.getTime());
int padSize = MAX_PADDED_BUILD_TIME_DURATION_LENGTH - buildTimeDuration.length();
@ -237,7 +233,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
buffer.append(buildTimeDuration);
buffer.append(']');
} else if (buildSummary instanceof BuildFailure) {
buffer.append(buffer().failure("FAILURE"));
buffer.append(builder().failure("FAILURE"));
buffer.append(" [");
String buildTimeDuration = formatDuration(buildSummary.getTime());
int padSize = MAX_PADDED_BUILD_TIME_DURATION_LENGTH - buildTimeDuration.length();
@ -254,7 +250,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
private void logResult(MavenSession session) {
infoLine('-');
MessageBuilder buffer = buffer();
MessageBuilder buffer = builder();
if (session.getResult().hasExceptions()) {
buffer.failure("BUILD FAILURE");
@ -264,6 +260,10 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
logger.info(buffer.toString());
}
private MessageBuilder builder() {
return messageBuilderFactory.builder();
}
private void logStats(MavenSession session) {
infoLine('-');
@ -312,7 +312,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
postHeader + chars('-', Math.max(0, lineLength - headerLen - prefix.length() + preHeader.length()));
logger.info(
buffer().strong(prefix).project(projectKey).strong(suffix).toString());
builder().strong(prefix).project(projectKey).strong(suffix).toString());
// Building Project Name Version [i/n]
String building = "Building " + event.getProject().getName() + " "
@ -369,7 +369,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
if (logger.isInfoEnabled()) {
logger.info("");
MessageBuilder buffer = buffer().strong("--- ");
MessageBuilder buffer = builder().strong("--- ");
append(buffer, event.getMojoExecution());
append(buffer, event.getProject());
buffer.strong(" ---");
@ -389,7 +389,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
if (logger.isInfoEnabled()) {
logger.info("");
MessageBuilder buffer = buffer().strong(">>> ");
MessageBuilder buffer = builder().strong(">>> ");
append(buffer, event.getMojoExecution());
buffer.strong(" > ");
appendForkInfo(buffer, event.getMojoExecution().getMojoDescriptor());
@ -411,7 +411,7 @@ public class ExecutionEventLogger extends AbstractExecutionListener {
if (logger.isInfoEnabled()) {
logger.info("");
MessageBuilder buffer = buffer().strong("<<< ");
MessageBuilder buffer = builder().strong("<<< ");
append(buffer, event.getMojoExecution());
buffer.strong(" < ");
appendForkInfo(buffer, event.getMojoExecution().getMojoDescriptor());

View File

@ -0,0 +1,156 @@
/*
* 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.cli.jansi;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.services.MessageBuilder;
import org.fusesource.jansi.Ansi;
@Experimental
public class JansiMessageBuilder implements MessageBuilder {
private final Ansi ansi;
public JansiMessageBuilder() {
this.ansi = Ansi.ansi();
}
public JansiMessageBuilder(StringBuilder sb) {
this.ansi = Ansi.ansi(sb);
}
@Override
@Nonnull
public MessageBuilder debug(Object o) {
return style(Style.DEBUG, o);
}
@Override
@Nonnull
public MessageBuilder info(Object o) {
return style(Style.INFO, o);
}
@Override
@Nonnull
public MessageBuilder warning(Object o) {
return style(Style.WARNING, o);
}
@Override
@Nonnull
public MessageBuilder error(Object o) {
return style(Style.ERROR, o);
}
@Override
@Nonnull
public MessageBuilder success(Object o) {
return style(Style.SUCCESS, o);
}
@Override
@Nonnull
public MessageBuilder failure(Object o) {
return style(Style.FAILURE, o);
}
@Override
@Nonnull
public MessageBuilder strong(Object o) {
return style(Style.STRONG, o);
}
@Override
@Nonnull
public MessageBuilder mojo(Object o) {
return style(Style.MOJO, o);
}
@Override
@Nonnull
public MessageBuilder project(Object o) {
return style(Style.PROJECT, o);
}
private MessageBuilder style(Style style, Object o) {
style.apply(ansi).a(o).reset();
return this;
}
@Override
@Nonnull
public MessageBuilder a(char[] chars, int i, int i1) {
ansi.a(chars, i, i1);
return this;
}
@Override
@Nonnull
public MessageBuilder a(char[] chars) {
ansi.a(chars);
return this;
}
@Override
@Nonnull
public MessageBuilder a(CharSequence charSequence, int i, int i1) {
ansi.a(charSequence, i, i1);
return this;
}
@Override
@Nonnull
public MessageBuilder a(CharSequence charSequence) {
ansi.a(charSequence);
return this;
}
@Override
@Nonnull
public MessageBuilder a(Object o) {
ansi.a(o);
return this;
}
@Override
@Nonnull
public MessageBuilder newline() {
ansi.newline();
return this;
}
@Override
@Nonnull
public MessageBuilder format(String s, Object... objects) {
ansi.format(s, objects);
return this;
}
@Override
@Nonnull
public String build() {
return ansi.toString();
}
@Override
public String toString() {
return build();
}
}

View File

@ -0,0 +1,55 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.maven.cli.jansi;
import javax.inject.Named;
import javax.inject.Singleton;
import org.apache.maven.api.annotations.Experimental;
import org.apache.maven.api.annotations.Nonnull;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.api.services.MessageBuilderFactory;
@Experimental
@Named
@Singleton
public class JansiMessageBuilderFactory implements MessageBuilderFactory {
@Override
public boolean isColorEnabled() {
return MessageUtils.isColorEnabled();
}
@Override
public int getTerminalWidth() {
return MessageUtils.getTerminalWidth();
}
@Override
@Nonnull
public MessageBuilder builder() {
return builder(new StringBuilder());
}
@Override
@Nonnull
public MessageBuilder builder(@Nonnull StringBuilder stringBuilder) {
return MessageUtils.builder(stringBuilder);
}
}

View File

@ -0,0 +1,193 @@
/*
* 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.cli.jansi;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.internal.impl.DefaultMessageBuilder;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.AnsiConsole;
import org.fusesource.jansi.AnsiMode;
/**
* Colored message utils, to manage colors consistently across plugins (only if Maven version is at least 3.5.0).
* For Maven version before 3.5.0, message built with this util will never add color.
* <p>
* Internally, <a href="http://fusesource.github.io/jansi/">Jansi</a> is used to render
* <a href="https://en.wikipedia.org/wiki/ANSI_escape_code#Colors">ANSI colors</a> on any platform.
* @since 3.1.0
*/
public class MessageUtils {
private static final boolean JANSI;
/** Reference to the JVM shutdown hook, if registered */
private static Thread shutdownHook;
/** Synchronization monitor for the "uninstall" */
private static final Object STARTUP_SHUTDOWN_MONITOR = new Object();
static {
boolean jansi = true;
try {
// Jansi is provided by Maven core since 3.5.0
Class.forName("org.fusesource.jansi.Ansi");
} catch (ClassNotFoundException cnfe) {
jansi = false;
}
JANSI = jansi;
}
/**
* Install color support.
* This method is called by Maven core, and calling it is not necessary in plugins.
*/
public static void systemInstall() {
if (JANSI) {
AnsiConsole.systemInstall();
}
}
/**
* Undo a previous {@link #systemInstall()}. If {@link #systemInstall()} was called
* multiple times, {@link #systemUninstall()} must be called call the same number of times before
* it is actually uninstalled.
*/
public static void systemUninstall() {
synchronized (STARTUP_SHUTDOWN_MONITOR) {
doSystemUninstall();
// hook can only set when Jansi is true
if (shutdownHook != null) {
try {
Runtime.getRuntime().removeShutdownHook(shutdownHook);
} catch (IllegalStateException ex) {
// ignore - VM is already shutting down
}
}
}
}
private static void doSystemUninstall() {
if (JANSI) {
AnsiConsole.systemUninstall();
}
}
/**
* Enables message color (if Jansi is available).
* @param flag to enable Jansi
*/
public static void setColorEnabled(boolean flag) {
if (JANSI) {
AnsiConsole.out().setMode(flag ? AnsiMode.Force : AnsiMode.Strip);
Ansi.setEnabled(flag);
System.setProperty(
AnsiConsole.JANSI_MODE, flag ? AnsiConsole.JANSI_MODE_FORCE : AnsiConsole.JANSI_MODE_STRIP);
boolean installed = AnsiConsole.isInstalled();
while (AnsiConsole.isInstalled()) {
AnsiConsole.systemUninstall();
}
if (installed) {
AnsiConsole.systemInstall();
}
}
}
/**
* Is message color enabled: requires Jansi available (through Maven) and the color has not been disabled.
* @return whether colored messages are enabled
*/
public static boolean isColorEnabled() {
return JANSI ? Ansi.isEnabled() : false;
}
/**
* Create a default message buffer.
* @return a new buffer
*/
public static MessageBuilder builder() {
return builder(new StringBuilder());
}
/**
* Create a message buffer with an internal buffer of defined size.
* @param size size of the buffer
* @return a new buffer
*/
public static MessageBuilder builder(int size) {
return builder(new StringBuilder(size));
}
/**
* Create a message buffer with defined String builder.
* @param builder initial content of the message buffer
* @return a new buffer
*/
public static MessageBuilder builder(StringBuilder builder) {
return JANSI && isColorEnabled() ? new JansiMessageBuilder(builder) : new DefaultMessageBuilder(builder);
}
/**
* Remove any ANSI code from a message (colors or other escape sequences).
* @param msg message eventually containing ANSI codes
* @return the message with ANSI codes removed
*/
public static String stripAnsiCodes(String msg) {
return msg.replaceAll("\u001B\\[[;\\d]*[ -/]*[@-~]", "");
}
/**
* Register a shutdown hook with the JVM runtime, uninstalling Ansi support on
* JVM shutdown unless is has already been uninstalled at that time.
* <p>Delegates to {@link #doSystemUninstall()} for the actual uninstall procedure
*
* @see Runtime#addShutdownHook(Thread)
* @see MessageUtils#systemUninstall()
* @see #doSystemUninstall()
*/
public static void registerShutdownHook() {
if (JANSI && shutdownHook == null) {
// No shutdown hook registered yet.
shutdownHook = new Thread() {
@Override
public void run() {
synchronized (STARTUP_SHUTDOWN_MONITOR) {
while (AnsiConsole.isInstalled()) {
doSystemUninstall();
}
}
}
};
Runtime.getRuntime().addShutdownHook(shutdownHook);
}
}
/**
* Get the terminal width or -1 if the width cannot be determined.
*
* @return the terminal width
*/
public static int getTerminalWidth() {
if (JANSI) {
int width = AnsiConsole.getTerminalWidth();
return width > 0 ? width : -1;
} else {
return -1;
}
}
}

View File

@ -0,0 +1,147 @@
/*
* 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.cli.jansi;
import java.util.Locale;
import org.fusesource.jansi.Ansi;
import org.fusesource.jansi.Ansi.Color;
/**
* Configurable message styles.
* @since 3.1.0
*/
enum Style {
DEBUG("bold,cyan"),
INFO("bold,blue"),
WARNING("bold,yellow"),
ERROR("bold,red"),
SUCCESS("bold,green"),
FAILURE("bold,red"),
STRONG("bold"),
MOJO("green"),
PROJECT("cyan");
private final boolean bold;
private final boolean bright;
private final Color color;
private final boolean bgBright;
private final Color bgColor;
Style(String defaultValue) {
boolean currentBold = false;
boolean currentBright = false;
Color currentColor = null;
boolean currentBgBright = false;
Color currentBgColor = null;
String value = System.getProperty("style." + name().toLowerCase(Locale.ENGLISH), defaultValue)
.toLowerCase(Locale.ENGLISH);
for (String token : value.split(",")) {
if ("bold".equals(token)) {
currentBold = true;
} else if (token.startsWith("bg")) {
token = token.substring(2);
if (token.startsWith("bright")) {
currentBgBright = true;
token = token.substring(6);
}
currentBgColor = toColor(token);
} else {
if (token.startsWith("bright")) {
currentBright = true;
token = token.substring(6);
}
currentColor = toColor(token);
}
}
this.bold = currentBold;
this.bright = currentBright;
this.color = currentColor;
this.bgBright = currentBgBright;
this.bgColor = currentBgColor;
}
private static Color toColor(String token) {
for (Color color : Color.values()) {
if (color.toString().equalsIgnoreCase(token)) {
return color;
}
}
return null;
}
Ansi apply(Ansi ansi) {
if (bold) {
ansi.bold();
}
if (color != null) {
if (bright) {
ansi.fgBright(color);
} else {
ansi.fg(color);
}
}
if (bgColor != null) {
if (bgBright) {
ansi.bgBright(bgColor);
} else {
ansi.bg(bgColor);
}
}
return ansi;
}
@Override
public String toString() {
if (!bold && color == null && bgColor == null) {
return name();
}
StringBuilder sb = new StringBuilder(name() + '=');
if (bold) {
sb.append("bold");
}
if (color != null) {
if (sb.length() > 0) {
sb.append(',');
}
if (bright) {
sb.append("bright");
}
sb.append(color.name());
}
if (bgColor != null) {
if (sb.length() > 0) {
sb.append(',');
}
sb.append("bg");
if (bgBright) {
sb.append("bright");
}
sb.append(bgColor.name());
}
return sb.toString();
}
}

View File

@ -35,6 +35,7 @@ import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.maven.Maven;
import org.apache.maven.cli.jansi.MessageUtils;
import org.apache.maven.cli.transfer.ConsoleMavenTransferListener;
import org.apache.maven.cli.transfer.QuietMavenTransferListener;
import org.apache.maven.cli.transfer.Slf4jMavenTransferListener;
@ -44,7 +45,6 @@ import org.apache.maven.execution.ProfileActivation;
import org.apache.maven.execution.ProjectActivation;
import org.apache.maven.model.root.DefaultRootLocator;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.apache.maven.toolchain.building.ToolchainsBuildingRequest;
import org.apache.maven.toolchain.building.ToolchainsBuildingResult;
import org.codehaus.plexus.DefaultPlexusContainer;

View File

@ -22,10 +22,11 @@ import java.io.File;
import com.google.common.collect.ImmutableList;
import org.apache.commons.io.FilenameUtils;
import org.apache.maven.cli.jansi.JansiMessageBuilderFactory;
import org.apache.maven.cli.jansi.MessageUtils;
import org.apache.maven.execution.ExecutionEvent;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.utils.logging.MessageUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
@ -44,6 +45,7 @@ class ExecutionEventLoggerTest {
private Logger logger;
private ExecutionEventLogger executionEventLogger;
private JansiMessageBuilderFactory messageBuilderFactory = new JansiMessageBuilderFactory();
@BeforeAll
static void setUp() {
@ -59,7 +61,7 @@ class ExecutionEventLoggerTest {
void beforeEach() {
logger = mock(Logger.class);
when(logger.isInfoEnabled()).thenReturn(true);
executionEventLogger = new ExecutionEventLogger(logger);
executionEventLogger = new ExecutionEventLogger(messageBuilderFactory, logger);
}
@Test
@ -143,25 +145,25 @@ class ExecutionEventLoggerTest {
when(event.getProject()).thenReturn(project);
// default width
new ExecutionEventLogger(logger, -1).projectStarted(event);
new ExecutionEventLogger(messageBuilderFactory, logger, -1).projectStarted(event);
Mockito.verify(logger).info("----------------------------[ maven-plugin ]----------------------------");
// terminal width: 30
new ExecutionEventLogger(logger, 30).projectStarted(event);
new ExecutionEventLogger(messageBuilderFactory, logger, 30).projectStarted(event);
Mockito.verify(logger).info("------------------[ maven-plugin ]------------------");
// terminal width: 70
new ExecutionEventLogger(logger, 70).projectStarted(event);
new ExecutionEventLogger(messageBuilderFactory, logger, 70).projectStarted(event);
Mockito.verify(logger).info("-----------------------[ maven-plugin ]-----------------------");
// terminal width: 110
new ExecutionEventLogger(logger, 110).projectStarted(event);
new ExecutionEventLogger(messageBuilderFactory, logger, 110).projectStarted(event);
Mockito.verify(logger)
.info(
"-------------------------------------------[ maven-plugin ]-------------------------------------------");
// terminal width: 200
new ExecutionEventLogger(logger, 200).projectStarted(event);
new ExecutionEventLogger(messageBuilderFactory, logger, 200).projectStarted(event);
Mockito.verify(logger)
.info(
"-----------------------------------------------------[ maven-plugin ]-----------------------------------------------------");

View File

@ -38,12 +38,16 @@ under the License.
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-shared-utils</artifactId>
<groupId>org.apache.maven</groupId>
<artifactId>maven-slf4j-wrapper</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-slf4j-wrapper</artifactId>
<artifactId>maven-api-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
</dependency>
</dependencies>

View File

@ -20,8 +20,8 @@ package org.slf4j.impl;
import java.io.PrintStream;
import static org.apache.maven.shared.utils.logging.MessageUtils.buffer;
import static org.apache.maven.shared.utils.logging.MessageUtils.level;
import org.apache.maven.api.services.MessageBuilder;
import org.apache.maven.cli.jansi.MessageUtils;
/**
* Logger for Maven, that support colorization of levels and stacktraces. This class implements 2 methods introduced in
@ -38,16 +38,16 @@ public class MavenSimpleLogger extends SimpleLogger {
protected String renderLevel(int level) {
switch (level) {
case LOG_LEVEL_TRACE:
return level().debug("TRACE");
return builder().debug("TRACE").build();
case LOG_LEVEL_DEBUG:
return level().debug("DEBUG");
return builder().debug("DEBUG").build();
case LOG_LEVEL_INFO:
return level().info("INFO");
return builder().info("INFO").build();
case LOG_LEVEL_WARN:
return level().warning("WARNING");
return builder().warning("WARNING").build();
case LOG_LEVEL_ERROR:
default:
return level().error("ERROR");
return builder().error("ERROR").build();
}
}
@ -56,10 +56,10 @@ public class MavenSimpleLogger extends SimpleLogger {
if (t == null) {
return;
}
stream.print(buffer().failure(t.getClass().getName()));
stream.print(builder().failure(t.getClass().getName()));
if (t.getMessage() != null) {
stream.print(": ");
stream.print(buffer().failure(t.getMessage()));
stream.print(builder().failure(t.getMessage()));
}
stream.println();
@ -70,9 +70,9 @@ public class MavenSimpleLogger extends SimpleLogger {
for (StackTraceElement e : t.getStackTrace()) {
stream.print(prefix);
stream.print(" ");
stream.print(buffer().strong("at"));
stream.print(builder().strong("at"));
stream.print(" " + e.getClassName() + "." + e.getMethodName());
stream.print(buffer().a(" (").strong(getLocation(e)).a(")"));
stream.print(builder().a(" (").strong(getLocation(e)).a(")"));
stream.println();
}
for (Throwable se : t.getSuppressed()) {
@ -85,10 +85,10 @@ public class MavenSimpleLogger extends SimpleLogger {
}
private void writeThrowable(Throwable t, PrintStream stream, String caption, String prefix) {
stream.print(buffer().a(prefix).strong(caption).a(": ").a(t.getClass().getName()));
stream.print(builder().a(prefix).strong(caption).a(": ").a(t.getClass().getName()));
if (t.getMessage() != null) {
stream.print(": ");
stream.print(buffer().failure(t.getMessage()));
stream.print(builder().failure(t.getMessage()));
}
stream.println();
@ -108,4 +108,8 @@ public class MavenSimpleLogger extends SimpleLogger {
return e.getFileName();
}
}
private MessageBuilder builder() {
return MessageUtils.builder();
}
}

12
pom.xml
View File

@ -299,18 +299,6 @@ under the License.
<artifactId>plexus-interpolation</artifactId>
<version>${plexusInterpolationVersion}</version>
</dependency>
<dependency>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-shared-utils</artifactId>
<version>3.3.4</version>
<exclusions>
<!-- We use org.apache.maven.shared.utils.logging only in Maven Core -->
<exclusion>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.fusesource.jansi</groupId>
<artifactId>jansi</artifactId>