diff --git a/internal/util-logging/src/main/contraband-scala/sbt/internal/util/LogOption.scala b/internal/util-logging/src/main/contraband-scala/sbt/internal/util/LogOption.scala new file mode 100644 index 000000000..769da7982 --- /dev/null +++ b/internal/util-logging/src/main/contraband-scala/sbt/internal/util/LogOption.scala @@ -0,0 +1,15 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.util +/** value for logging options like color */ +sealed abstract class LogOption extends Serializable +object LogOption { + + + case object Always extends LogOption + case object Never extends LogOption + case object Auto extends LogOption +} diff --git a/internal/util-logging/src/main/contraband-scala/sbt/internal/util/codec/JsonProtocol.scala b/internal/util-logging/src/main/contraband-scala/sbt/internal/util/codec/JsonProtocol.scala index a94906dda..15e4d9cb2 100644 --- a/internal/util-logging/src/main/contraband-scala/sbt/internal/util/codec/JsonProtocol.scala +++ b/internal/util-logging/src/main/contraband-scala/sbt/internal/util/codec/JsonProtocol.scala @@ -9,4 +9,5 @@ trait JsonProtocol extends sjsonnew.BasicJsonProtocol with sbt.internal.util.codec.TraceEventFormats with sbt.internal.util.codec.AbstractEntryFormats with sbt.internal.util.codec.SuccessEventFormats + with sbt.internal.util.codec.LogOptionFormats object JsonProtocol extends JsonProtocol \ No newline at end of file diff --git a/internal/util-logging/src/main/contraband-scala/sbt/internal/util/codec/LogOptionFormats.scala b/internal/util-logging/src/main/contraband-scala/sbt/internal/util/codec/LogOptionFormats.scala new file mode 100644 index 000000000..e52700c19 --- /dev/null +++ b/internal/util-logging/src/main/contraband-scala/sbt/internal/util/codec/LogOptionFormats.scala @@ -0,0 +1,31 @@ +/** + * This code is generated using [[http://www.scala-sbt.org/contraband/ sbt-contraband]]. + */ + +// DO NOT EDIT MANUALLY +package sbt.internal.util.codec +import _root_.sjsonnew.{ Unbuilder, Builder, JsonFormat, deserializationError } +trait LogOptionFormats { self: sjsonnew.BasicJsonProtocol => +implicit lazy val LogOptionFormat: JsonFormat[sbt.internal.util.LogOption] = new JsonFormat[sbt.internal.util.LogOption] { + override def read[J](jsOpt: Option[J], unbuilder: Unbuilder[J]): sbt.internal.util.LogOption = { + jsOpt match { + case Some(js) => + unbuilder.readString(js) match { + case "Always" => sbt.internal.util.LogOption.Always + case "Never" => sbt.internal.util.LogOption.Never + case "Auto" => sbt.internal.util.LogOption.Auto + } + case None => + deserializationError("Expected JsString but found None") + } + } + override def write[J](obj: sbt.internal.util.LogOption, builder: Builder[J]): Unit = { + val str = obj match { + case sbt.internal.util.LogOption.Always => "Always" + case sbt.internal.util.LogOption.Never => "Never" + case sbt.internal.util.LogOption.Auto => "Auto" + } + builder.writeString(str) + } +} +} diff --git a/internal/util-logging/src/main/contraband/logging.contra b/internal/util-logging/src/main/contraband/logging.contra index 19b019c66..73d0b1a56 100644 --- a/internal/util-logging/src/main/contraband/logging.contra +++ b/internal/util-logging/src/main/contraband/logging.contra @@ -25,3 +25,10 @@ type TraceEvent implements sbt.internal.util.AbstractEntry { type SuccessEvent { message: String! } + +## value for logging options like color +enum LogOption { + Always + Never + Auto +} diff --git a/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala b/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala index d5f6f7919..f070a1252 100644 --- a/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala +++ b/internal/util-logging/src/main/scala/sbt/internal/util/ConsoleAppender.scala @@ -101,13 +101,49 @@ object ConsoleAppender { /** Hide stack trace altogether. */ val noSuppressedMessage = (_: SuppressedTraceContext) => None - /** Indicates whether formatting has been disabled in environment variables. */ + /** + * Indicates whether formatting has been disabled in environment variables. + * 1. -Dsbt.log.noformat=true means no formatting. + * 2. -Dsbt.color=always/auto/never/true/false + * 3. -Dsbt.colour=always/auto/never/true/false + * 4. -Dsbt.log.format=always/auto/never/true/false + */ val formatEnabledInEnv: Boolean = { - import java.lang.Boolean.{ getBoolean, parseBoolean } - val value = System.getProperty("sbt.log.format") - if (value eq null) (ansiSupported && !getBoolean("sbt.log.noformat")) else parseBoolean(value) + def useColorDefault: Boolean = { + // This approximates that both stdin and stdio are connected, + // so by default color will be turned off for pipes and redirects. + val hasConsole = Option(java.lang.System.console).isDefined + ansiSupported && hasConsole + } + sys.props.get("sbt.log.noformat") match { + case Some(_) => !java.lang.Boolean.getBoolean("sbt.log.noformat") + case _ => + sys.props + .get("sbt.color") + .orElse(sys.props.get("sbt.colour")) + .orElse(sys.props.get("sbt.log.format")) + .flatMap({ s => + parseLogOption(s) match { + case LogOption.Always => Some(true) + case LogOption.Never => Some(false) + case _ => None + } + }) + .getOrElse(useColorDefault) + } } + private[sbt] def parseLogOption(s: String): LogOption = + s.toLowerCase match { + case "always" => LogOption.Always + case "auto" => LogOption.Auto + case "never" => LogOption.Never + case "true" => LogOption.Always + case "false" => LogOption.Never + case "default" => LogOption.Auto + case _ => LogOption.Auto + } + private[this] val generateId: AtomicInteger = new AtomicInteger /**