Merge pull request #184 from eed3si9n/wip/progress

Adds sbt.color flag and sbt.progress flag
This commit is contained in:
eugene yokota 2018-10-02 08:58:38 -04:00 committed by GitHub
commit f16997d3a9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 137 additions and 11 deletions

View File

@ -126,6 +126,9 @@ lazy val utilLogging = (project in internalPath / "util-logging")
// Private final class constructors changed
exclude[DirectMissingMethodProblem]("sbt.util.InterfaceUtil#ConcretePosition.this"),
exclude[DirectMissingMethodProblem]("sbt.util.InterfaceUtil#ConcreteProblem.this"),
exclude[ReversedMissingMethodProblem]("sbt.internal.util.ConsoleOut.flush"),
// This affects Scala 2.11 only it seems, so it's ok?
exclude[InheritedNewAbstractMethodProblem]("sbt.internal.util.codec.JsonProtocol.LogOptionFormat"),
),
)
.configure(addSbtIO)

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

@ -100,13 +100,63 @@ 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)
}
}
/**
* Indicates whether the super shell is enabled.
*/
lazy val showProgress: Boolean =
formatEnabledInEnv && sys.props
.get("sbt.progress")
.flatMap({ s =>
parseLogOption(s) match {
case LogOption.Always => Some(true)
case LogOption.Never => Some(false)
case _ => None
}
})
.getOrElse(true)
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 _ => LogOption.Auto
}
private[this] val generateId: AtomicInteger = new AtomicInteger
/**
@ -406,11 +456,18 @@ class ConsoleAppender private[ConsoleAppender] (
appendLog(SUCCESS_LABEL_COLOR, Level.SuccessLabel, SUCCESS_MESSAGE_COLOR, message)
}
private final val ScrollUp = "\u001B[S"
private final val DeleteLine = "\u001B[2K"
private final val CursorLeft1000 = "\u001B[1000D"
private def write(msg: String): Unit = {
val cleanedMsg =
if (!useFormat || !ansiCodesSupported) EscHelpers.removeEscapeSequences(msg)
else msg
out.println(cleanedMsg)
if (!useFormat || !ansiCodesSupported) {
out.println(EscHelpers.removeEscapeSequences(msg))
} else if (ConsoleAppender.showProgress) {
out.print(s"$ScrollUp$DeleteLine$msg${CursorLeft1000}")
out.flush()
} else {
out.println(msg)
}
}
private def appendMessage(level: Level.Value, msg: Message): Unit =

View File

@ -7,6 +7,7 @@ sealed trait ConsoleOut {
def print(s: String): Unit
def println(s: String): Unit
def println(): Unit
def flush(): Unit
}
object ConsoleOut {
@ -39,6 +40,14 @@ object ConsoleOut {
last = Some(s)
current.setLength(0)
}
def flush(): Unit = synchronized {
val s = current.toString
if (ConsoleAppender.formatEnabledInEnv && last.exists(lmsg => f(s, lmsg)))
lockObject.print(OverwriteLine)
lockObject.print(s)
last = Some(s)
current.setLength(0)
}
}
def printStreamOut(out: PrintStream): ConsoleOut = new ConsoleOut {
@ -46,17 +55,20 @@ object ConsoleOut {
def print(s: String) = out.print(s)
def println(s: String) = out.println(s)
def println() = out.println()
def flush() = out.flush()
}
def printWriterOut(out: PrintWriter): ConsoleOut = new ConsoleOut {
val lockObject = out
def print(s: String) = out.print(s)
def println(s: String) = { out.println(s); out.flush() }
def println() = { out.println(); out.flush() }
def println(s: String) = { out.println(s); flush() }
def println() = { out.println(); flush() }
def flush() = { out.flush() }
}
def bufferedWriterOut(out: BufferedWriter): ConsoleOut = new ConsoleOut {
val lockObject = out
def print(s: String) = out.write(s)
def println(s: String) = { out.write(s); println() }
def println() = { out.newLine(); out.flush() }
def println() = { out.newLine(); flush() }
def flush() = { out.flush() }
}
}