add sbt.color flag

This implements a new sbt.color flag that takes always/auto/never/true/false value as a replacement of current sbt.log.format=true/false flag.

When neither flags are set, the default behavior is to enable color when the terminal supports ANSI and it detects an stdout console (as opposed to redirects).

Fixes https://github.com/sbt/sbt/issues/4284
This commit is contained in:
Eugene Yokota 2018-09-30 20:59:19 -04:00
parent dbd17e63e2
commit 53c9b84858
5 changed files with 94 additions and 4 deletions

View File

@ -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
}

View File

@ -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

View File

@ -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)
}
}
}

View File

@ -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
}

View File

@ -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
/**