diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 4885dea22..8ce837d93 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -27,7 +27,7 @@ import sbt.internal.io.WatchState import sbt.internal.librarymanagement.{ CompatibilityWarningOptions, IvySbt } import sbt.internal.remotecache.RemoteCacheArtifact import sbt.internal.server.ServerHandler -import sbt.internal.util.{ Appender, AttributeKey, ProgressState, SourcePosition } +import sbt.internal.util.{ AttributeKey, ProgressState, SourcePosition } import sbt.io._ import sbt.librarymanagement.Configurations.CompilerPlugin import sbt.librarymanagement.LibraryManagementCodec._ @@ -61,7 +61,7 @@ object Keys { val timingFormat = settingKey[java.text.DateFormat]("The format used for displaying the completion time.").withRank(CSetting) @deprecated("", "1.4.0") val extraLoggers = settingKey[ScopedKey[_] => Seq[XAppender]]("A function that provides additional loggers for a given setting.").withRank(DSetting) - val extraAppenders = settingKey[ScopedKey[_] => Seq[Appender]]("A function that provides additional loggers for a given setting.").withRank(DSetting) + val extraAppenders = settingKey[AppenderSupplier]("A function that provides additional loggers for a given setting.").withRank(DSetting) val useLog4J = settingKey[Boolean]("Toggles whether or not to use log4j for sbt internal loggers.").withRank(Invisible) val logManager = settingKey[LogManager]("The log manager, which creates Loggers for different contexts.").withRank(DSetting) private[sbt] val loggerContext = AttributeKey[LoggerContext]("sbt-logger-context", "The logger config which creates Loggers for different contexts.", Int.MaxValue) diff --git a/main/src/main/scala/sbt/internal/LogManager.scala b/main/src/main/scala/sbt/internal/LogManager.scala index 99722dbf6..315989bfa 100644 --- a/main/src/main/scala/sbt/internal/LogManager.scala +++ b/main/src/main/scala/sbt/internal/LogManager.scala @@ -16,6 +16,7 @@ import sbt.Scope.GlobalScope import sbt.internal.util.MainAppender._ import sbt.internal.util._ import sbt.util.{ Level, LogExchange, Logger, LoggerContext } +import org.apache.logging.log4j.core.{ Appender => XAppender } sealed abstract class LogManager { def apply( @@ -44,6 +45,14 @@ sealed abstract class LogManager { backgroundLog(data, state, task, LoggerContext.globalContext) } +/** + * A functional interface that allows us to preserve binary compatibility + * for LogManager.defaults with the old log4j variant. + */ +trait AppenderSupplier { + def apply(s: ScopedKey[_]): Seq[Appender] +} + object LogManager { import java.util.concurrent.atomic.AtomicInteger private val generateId: AtomicInteger = new AtomicInteger @@ -75,8 +84,14 @@ object LogManager { def defaultManager(console: ConsoleOut): LogManager = withLoggers((_, _) => defaultScreen(console)) + @deprecated( + "use defaults that takes AppenderSupplier instead of ScopedKey[_] => Seq[Appender]", + "1.4.0" + ) + def defaults(extra: ScopedKey[_] => Seq[XAppender], console: ConsoleOut): LogManager = + defaults((sk: ScopedKey[_]) => extra(sk).map(new ConsoleAppenderFromLog4J("extra", _)), console) // This is called by Defaults. - def defaults(extra: ScopedKey[_] => Seq[Appender], console: ConsoleOut): LogManager = + def defaults(extra: AppenderSupplier, console: ConsoleOut): LogManager = withLoggers( (task, state) => defaultScreen(console, suppressedMessage(task, state)), extra = extra @@ -89,14 +104,14 @@ object LogManager { screen: (ScopedKey[_], State) => Appender = (_, s) => defaultScreen(s.globalLogging.console), backed: PrintWriter => Appender = defaultBacked, relay: Unit => Appender = defaultRelay, - extra: ScopedKey[_] => Seq[Appender] = _ => Nil + extra: AppenderSupplier = _ => Nil ): LogManager = new DefaultLogManager(screen, backed, relay, extra) private class DefaultLogManager( screen: (ScopedKey[_], State) => Appender, backed: PrintWriter => Appender, relay: Unit => Appender, - extra: ScopedKey[_] => Seq[Appender] + extra: AppenderSupplier ) extends LogManager { def apply( data: Settings[Scope],