From 94bc4de2ea54afa09a353034ed06edf0f68a8d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20Boutemy?= Date: Thu, 22 Sep 2016 17:46:53 +0200 Subject: [PATCH] [MNG-6093] use monkey patched slf4j-simple provider with Maven color --- apache-maven/pom.xml | 4 +- .../maven/slf4j-configuration.properties | 1 + maven-slf4j-provider/pom.xml | 116 ++++++++++++++++++ .../org/slf4j/impl/MavenSimpleLogger.java | 115 +++++++++++++++++ .../slf4j/impl/MavenSimpleLoggerFactory.java | 44 +++++++ .../src/main/script/patch-slf4j-simple.groovy | 53 ++++++++ maven-slf4j-provider/src/site/site.xml | 36 ++++++ pom.xml | 6 + src/site/xdoc/index.xml | 2 + 9 files changed, 375 insertions(+), 2 deletions(-) create mode 100644 maven-slf4j-provider/pom.xml create mode 100644 maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java create mode 100644 maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLoggerFactory.java create mode 100644 maven-slf4j-provider/src/main/script/patch-slf4j-simple.groovy create mode 100644 maven-slf4j-provider/src/site/site.xml diff --git a/apache-maven/pom.xml b/apache-maven/pom.xml index f7c28edf9f..b2fa989cb4 100644 --- a/apache-maven/pom.xml +++ b/apache-maven/pom.xml @@ -88,8 +88,8 @@ aether-transport-wagon - org.slf4j - slf4j-simple + org.apache.maven + maven-slf4j-provider org.fusesource.jansi diff --git a/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties b/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties index 87418363b1..ae1bc39eb7 100644 --- a/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties +++ b/maven-embedder/src/main/resources/META-INF/maven/slf4j-configuration.properties @@ -18,5 +18,6 @@ # key = Slf4j effective logger factory implementation # value = corresponding o.a.m.cli.logging.Slf4jConfiguration class org.slf4j.impl.SimpleLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration +org.slf4j.impl.MavenSimpleLoggerFactory org.apache.maven.cli.logging.impl.Slf4jSimpleConfiguration org.slf4j.helpers.Log4jLoggerFactory org.apache.maven.cli.logging.impl.Log4j2Configuration ch.qos.logback.classic.LoggerContext org.apache.maven.cli.logging.impl.LogbackConfiguration diff --git a/maven-slf4j-provider/pom.xml b/maven-slf4j-provider/pom.xml new file mode 100644 index 0000000000..81af3827fe --- /dev/null +++ b/maven-slf4j-provider/pom.xml @@ -0,0 +1,116 @@ + + + + + + 4.0.0 + + + org.apache.maven + maven + 3.5.0-SNAPSHOT + + + maven-slf4j-provider + + Maven SLF4J Simple Provider + + Maven SLF4J provider based on SLF4J's simple provider, monkey-patched to support Maven styled colors + for levels and stacktraces rendering. + + + + + org.slf4j + slf4j-api + + + org.apache.maven.shared + maven-shared-utils + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + + org.slf4j + slf4j-simple + ${slf4jVersion} + jar + sources + false + ${project.build.directory}/generated-sources/slf4j-simple + org/slf4j/impl/*.java + + + + + + unzip-slf4j-simple + + unpack + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.12 + + + add-slf4j-simple + generate-sources + + add-source + + + + ${project.build.directory}/generated-sources/slf4j-simple + + + + + + + org.codehaus.gmaven + groovy-maven-plugin + 2.0 + + + patch-slf4j-simple + process-sources + + execute + + + ${project.basedir}/src/main/script/patch-slf4j-simple.groovy + + + + + + + \ No newline at end of file diff --git a/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java new file mode 100644 index 0000000000..17f1f484c3 --- /dev/null +++ b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLogger.java @@ -0,0 +1,115 @@ +package org.slf4j.impl; + +/* + * 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. + */ + +import static org.apache.maven.shared.utils.logging.MessageUtils.buffer; + +import java.io.PrintStream; + +/** + * Logger for Maven, that support colorization of levels and stacktraces. + * This class implements 2 methods introduced in slf4j-simple provider local copy. + * @since 3.5.0 + */ +public class MavenSimpleLogger + extends SimpleLogger +{ + MavenSimpleLogger( String name ) + { + super( name ); + } + + @Override + protected String renderLevel( int level ) + { + switch ( level ) + { + case LOG_LEVEL_TRACE: + return buffer().debug( "TRACE" ).toString(); + case LOG_LEVEL_DEBUG: + return buffer().debug( "DEBUG" ).toString(); + case LOG_LEVEL_INFO: + return buffer().info( "INFO" ).toString(); + case LOG_LEVEL_WARN: + return buffer().warning( "WARNING" ).toString(); + case LOG_LEVEL_ERROR: + default: + return buffer().error( "ERROR" ).toString(); + } + } + + @Override + protected void renderThrowable( Throwable t, PrintStream stream ) + { + stream.print( buffer().failure( t.getClass().getName() ) ); + if ( t.getMessage() != null ) + { + stream.print( ": " ); + stream.print( buffer().failure( t.getMessage() ) ); + } + stream.println(); + + while ( t != null ) + { + for ( StackTraceElement e : t.getStackTrace() ) + { + stream.print( " " ); + stream.print( buffer().strong( "at" ) ); + stream.print( " " + e.getClassName() + "." + e.getMethodName() ); + stream.print( buffer().a( " (" ).strong( getLocation( e ) ).a( ")" ) ); + stream.println(); + } + + t = t.getCause(); + if ( t != null ) + { + stream.print( buffer().strong( "Caused by" ).a( ": " ).a( t.getClass().getName() ) ); + if ( t.getMessage() != null ) + { + stream.print( ": " ); + stream.print( buffer().failure( t.getMessage() ) ); + } + stream.println(); + } + } + } + + protected String getLocation( final StackTraceElement e ) + { + assert e != null; + + if ( e.isNativeMethod() ) + { + return "Native Method"; + } + else if ( e.getFileName() == null ) + { + return "Unknown Source"; + } + else if ( e.getLineNumber() >= 0 ) + { + return String.format( "%s:%s", e.getFileName(), e.getLineNumber() ); + } + else + { + return e.getFileName(); + } + } +} diff --git a/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLoggerFactory.java b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLoggerFactory.java new file mode 100644 index 0000000000..d56e346181 --- /dev/null +++ b/maven-slf4j-provider/src/main/java/org/slf4j/impl/MavenSimpleLoggerFactory.java @@ -0,0 +1,44 @@ +package org.slf4j.impl; + +/* + * 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. + */ + +import org.slf4j.Logger; + +public class MavenSimpleLoggerFactory + extends SimpleLoggerFactory +{ + /** + * Return an appropriate {@link MavenSimpleLogger} instance by name. + */ + public Logger getLogger( String name ) + { + Logger simpleLogger = loggerMap.get( name ); + if ( simpleLogger != null ) + { + return simpleLogger; + } + else + { + Logger newInstance = new MavenSimpleLogger( name ); + Logger oldInstance = loggerMap.putIfAbsent( name, newInstance ); + return oldInstance == null ? newInstance : oldInstance; + } + } +} diff --git a/maven-slf4j-provider/src/main/script/patch-slf4j-simple.groovy b/maven-slf4j-provider/src/main/script/patch-slf4j-simple.groovy new file mode 100644 index 0000000000..bba864662f --- /dev/null +++ b/maven-slf4j-provider/src/main/script/patch-slf4j-simple.groovy @@ -0,0 +1,53 @@ + +/* + * 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. + */ + +dir = new File( basedir, 'target/generated-sources/slf4j-simple/org/slf4j/impl' ); + +file = new File( dir, 'StaticLoggerBinder.java' ); +content = file.text; + +// check if already patched +if ( content.contains( 'MavenSimpleLoggerFactory' ) ) +{ + println ' slf4j-simple already patched'; + return; +} + + +println ' patching StaticLoggerBinder.java'; +content = content.replaceAll( 'SimpleLoggerFactory', 'MavenSimpleLoggerFactory' ); +file.write( content ); + + +println ' patching SimpleLogger.java'; +file = new File( dir, 'SimpleLogger.java' ); +content = file.text; +content = content.replaceAll( 'private static final int LOG_LEVEL_', 'protected static final int LOG_LEVEL_' ); +content = content.replaceAll( 't.printStackTrace(TARGET_STREAM)', 'renderThrowable(t, TARGET_STREAM);' ); + +index = content.indexOf( 'switch (level) {' ); +end = content.indexOf( '}', index ) + 1; +content = content.substring( 0, index ) + 'buf.append(renderLevel(level));' + content.substring( end ); + +content = content.substring( 0, content.lastIndexOf( '}' ) ); +content += ' protected void renderThrowable(Throwable t, PrintStream stream) {}\n'; +content += ' protected String renderLevel(int level) { return ""; }\n}\n'; + +file.write( content ); diff --git a/maven-slf4j-provider/src/site/site.xml b/maven-slf4j-provider/src/site/site.xml new file mode 100644 index 0000000000..3a16bf98b5 --- /dev/null +++ b/maven-slf4j-provider/src/site/site.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index f8b67aa643..fba262b16d 100644 --- a/pom.xml +++ b/pom.xml @@ -84,6 +84,7 @@ maven-artifact maven-aether-provider maven-repository-metadata + maven-slf4j-provider maven-embedder maven-compat apache-maven @@ -217,6 +218,11 @@ maven-builder-support ${project.version} + + org.apache.maven + maven-slf4j-provider + ${project.version} + diff --git a/src/site/xdoc/index.xml b/src/site/xdoc/index.xml index b98b4ee258..11fa0dea46 100644 --- a/src/site/xdoc/index.xml +++ b/src/site/xdoc/index.xml @@ -55,6 +55,8 @@ maven-settings maven-model-builder maven-model + maven-slf4j-provider + slf4j-api commons-cli wagon-provider-api plexus-sec-dispatcher