Merge branch 'develop' into evaluate-task-memory-leak

This commit is contained in:
Ethan Atkins 2020-10-21 11:49:01 -07:00 committed by GitHub
commit 7ad20edbd3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 70 additions and 64 deletions

View File

@ -64,8 +64,8 @@ object ConsoleLogger {
*/
def apply(
out: ConsoleOut = ConsoleOut.systemOut,
ansiCodesSupported: Boolean = ConsoleAppender.formatEnabledInEnv,
useFormat: Boolean = ConsoleAppender.formatEnabledInEnv,
ansiCodesSupported: Boolean = Terminal.isAnsiSupported,
useFormat: Boolean = Terminal.isColorEnabled,
suppressedMessage: SuppressedTraceContext => Option[String] =
ConsoleAppender.noSuppressedMessage
): ConsoleLogger =
@ -148,7 +148,8 @@ object ConsoleAppender {
* 3. -Dsbt.colour=always/auto/never/true/false
* 4. -Dsbt.log.format=always/auto/never/true/false
*/
lazy val formatEnabledInEnv: Boolean = Terminal.formatEnabledInEnv
@deprecated("Use Terminal.isAnsiSupported or Terminal.isColorEnabled", "1.4.0")
lazy val formatEnabledInEnv: Boolean = Terminal.isAnsiSupported
private[sbt] def parseLogOption(s: String): LogOption = Terminal.parseLogOption(s) match {
case Some(true) => LogOption.Always
@ -204,7 +205,7 @@ object ConsoleAppender {
* @param out Where to write messages.
* @return A new `ConsoleAppender` that writes to `out`.
*/
def apply(name: String, out: ConsoleOut): Appender = apply(name, out, formatEnabledInEnv)
def apply(name: String, out: ConsoleOut): Appender = apply(name, out, Terminal.isAnsiSupported)
/**
* A new `ConsoleAppender` identified by `name`, and that writes to `out`.
@ -218,8 +219,10 @@ object ConsoleAppender {
name: String,
out: ConsoleOut,
suppressedMessage: SuppressedTraceContext => Option[String]
): Appender =
apply(name, out, formatEnabledInEnv, formatEnabledInEnv, suppressedMessage)
): Appender = {
val ansi = Terminal.isAnsiSupported
apply(name, out, ansi, ansi, suppressedMessage)
}
/**
* A new `ConsoleAppender` identified by `name`, and that writes to `out`.
@ -230,7 +233,7 @@ object ConsoleAppender {
* @return A new `ConsoleAppender` that writes to `out`.
*/
def apply(name: String, out: ConsoleOut, useFormat: Boolean): Appender =
apply(name, out, useFormat || formatEnabledInEnv, useFormat, noSuppressedMessage)
apply(name, out, useFormat || Terminal.isAnsiSupported, useFormat, noSuppressedMessage)
/**
* A new `ConsoleAppender` identified by `name`, and that writes to `out`.
@ -368,14 +371,7 @@ trait Appender extends AutoCloseable {
private[util] def ansiCodesSupported: Boolean = properties.isAnsiSupported
private[util] def useFormat: Boolean = properties.isColorEnabled
private def reset: String = {
if (ansiCodesSupported && useFormat) scala.Console.RESET
else ""
}
private def clearScreenAfterCursor: String = {
if (ansiCodesSupported && useFormat) ClearScreenAfterCursor
else ""
}
private def reset: String = scala.Console.RESET
private val SUCCESS_LABEL_COLOR = GREEN
private val SUCCESS_MESSAGE_COLOR = reset
@ -465,19 +461,23 @@ trait Appender extends AutoCloseable {
if (message == null) ()
else {
val len =
labelColor.length + label.length + messageColor.length + reset.length * 3 + clearScreenAfterCursor.length
labelColor.length + label.length + messageColor.length + reset.length * 3 + ClearScreenAfterCursor.length
val builder: StringBuilder = new StringBuilder(len)
message.linesIterator.foreach { line =>
builder.ensureCapacity(len + line.length + 4)
builder.setLength(0)
def fmted(a: String, b: String) = builder.append(reset).append(a).append(b).append(reset)
def fmted(a: String, b: String) = {
if (useFormat) builder.append(reset).append(a).append(b).append(reset)
else builder.append(b)
}
builder.append(reset).append('[')
if (useFormat) builder.append(reset)
builder.append('[')
fmted(labelColor, label)
builder.append("] ")
fmted(messageColor, line)
builder.append(clearScreenAfterCursor)
if (ansiCodesSupported) builder.append(ClearScreenAfterCursor)
write(builder.toString)
}
}
@ -489,8 +489,15 @@ trait Appender extends AutoCloseable {
}
private def write(msg: String): Unit = {
val toWrite =
if (!useFormat || !ansiCodesSupported) EscHelpers.removeEscapeSequences(msg) else msg
// There is no api for removing only colors but not other ansi escape sequences
// so we do nothing if useFormat is false but ansiCodesSupported is true which is
// a rare use case but if ansiCodesSupported is true, color codes should work so
// the output may have unwanted colors but it would still be legible. This should
// only be relevant if the log message string itself contains ansi escape sequences
// other than color codes which is very unlikely.
val toWrite = if (!ansiCodesSupported) {
if (useFormat) EscHelpers.stripMoves(msg) else EscHelpers.removeEscapeSequences(msg)
} else msg
out.println(toWrite)
}

View File

@ -64,7 +64,7 @@ object ConsoleOut {
def println(s: String): Unit = synchronized { current.append(s); println() }
def println(): Unit = synchronized {
val s = current.toString
if (ConsoleAppender.formatEnabledInEnv && last.exists(lmsg => f(s, lmsg)))
if (Terminal.isAnsiSupported && last.exists(lmsg => f(s, lmsg)))
lockObject.print(OverwriteLine)
lockObject.println(s)
last = Some(s)
@ -72,7 +72,7 @@ object ConsoleOut {
}
def flush(): Unit = synchronized {
val s = current.toString
if (ConsoleAppender.formatEnabledInEnv && last.exists(lmsg => f(s, lmsg)))
if (Terminal.isAnsiSupported && last.exists(lmsg => f(s, lmsg)))
lockObject.print(OverwriteLine)
lockObject.print(s)
last = Some(s)

View File

@ -16,7 +16,7 @@ import org.jline.utils.{ ClosedException, NonBlockingReader }
import org.jline.terminal.{ Attributes, Size, Terminal => JTerminal }
import org.jline.terminal.Attributes.{ InputFlag, LocalFlag }
import org.jline.terminal.Terminal.SignalHandler
import org.jline.terminal.impl.{ AbstractTerminal, DumbTerminal }
import org.jline.terminal.impl.AbstractTerminal
import org.jline.terminal.impl.jansi.JansiSupportImpl
import org.jline.terminal.impl.jansi.win.JansiWinSysTerminal
import org.jline.utils.OSUtils
@ -73,11 +73,6 @@ private[sbt] object JLine3 {
term
}
private[sbt] def apply(term: Terminal): JTerminal = {
if (System.getProperty("jline.terminal", "") == "none" || !Terminal.formatEnabledInEnv)
new DumbTerminal(term.inputStream, term.outputStream)
else wrapTerminal(term)
}
private[this] def wrapTerminal(term: Terminal): JTerminal = {
new AbstractTerminal(
term.name,
"nocapabilities",

View File

@ -88,10 +88,10 @@ object MainAppender {
ConsoleAppender(name, console, suppressedMessage = suppressedMessage)
def defaultBacked: PrintWriter => Appender =
defaultBacked(generateGlobalBackingName, ConsoleAppender.formatEnabledInEnv)
defaultBacked(generateGlobalBackingName, Terminal.isAnsiSupported)
def defaultBacked(loggerName: String): PrintWriter => Appender =
defaultBacked(loggerName, ConsoleAppender.formatEnabledInEnv)
defaultBacked(loggerName, Terminal.isAnsiSupported)
def defaultBacked(useFormat: Boolean): PrintWriter => Appender =
defaultBacked(generateGlobalBackingName, useFormat)

View File

@ -306,19 +306,22 @@ object Terminal {
case _ => sys.props.get("sbt.log.format").flatMap(parseLogOption)
}
}
private[sbt] lazy val formatEnabledInEnv: Boolean = logFormatEnabled.getOrElse(useColorDefault)
private[this] lazy val superShellEnabled = sys.props.get("sbt.supershell").map(_ == "true")
private[sbt] lazy val isAnsiSupported: Boolean =
logFormatEnabled.orElse(superShellEnabled).getOrElse(useColorDefault && !isCI)
private[this] val isDumbTerminal = "dumb" == System.getenv("TERM")
private[this] val hasConsole = Option(java.lang.System.console).isDefined
private[this] def useColorDefault: Boolean = {
// This approximates that both stdin and stdio are connected,
// so by default color will be turned off for pipes and redirects.
props.map(_.color).orElse(isColorEnabledProp).getOrElse(hasConsole && !isDumbTerminal)
props.map(_.color).orElse(isColorEnabledProp).getOrElse((hasConsole && !isDumbTerminal) || isCI)
}
private[this] lazy val isColorEnabledProp: Option[Boolean] =
sys.props.get("sbt.color").orElse(sys.props.get("sbt.colour")).flatMap(parseLogOption)
private[sbt] lazy val isColorEnabled = useColorDefault
private[sbt] def red(str: String, doRed: Boolean): String =
if (formatEnabledInEnv && doRed) Console.RED + str + Console.RESET
if (isColorEnabled && doRed) Console.RED + str + Console.RESET
else str
/**
@ -330,8 +333,8 @@ object Terminal {
*/
private[sbt] def withStreams[T](isServer: Boolean)(f: => T): T =
// In ci environments, don't touch the io streams unless run with -Dsbt.io.virtual=true
if (System.getProperty("sbt.io.virtual", "") == "true" || (logFormatEnabled.getOrElse(true) && !isCI)) {
hasProgress.set(isServer && formatEnabledInEnv)
if (System.getProperty("sbt.io.virtual", "") == "true" || !isCI) {
hasProgress.set(isServer && isAnsiSupported)
consoleTerminalHolder.set(newConsoleTerminal())
activeTerminal.set(consoleTerminalHolder.get)
try withOut(withIn(f))
@ -745,7 +748,7 @@ object Terminal {
private[this] def fixTerminalProperty(): Unit = {
val terminalProperty = "jline.terminal"
val newValue =
if (!formatEnabledInEnv) "none"
if (!isAnsiSupported) "none"
else
System.getProperty(terminalProperty) match {
case "jline.UnixTerminal" => "unix"
@ -794,7 +797,8 @@ object Terminal {
val size = system.getSize
(size.getColumns, size.getRows)
}
override lazy val isAnsiSupported: Boolean = !isDumbTerminal && formatEnabledInEnv && !isCI
override lazy val isAnsiSupported: Boolean =
!isDumbTerminal && Terminal.isAnsiSupported && !isCI
override private[sbt] def progressState: ProgressState = consoleProgressState.get
override def isEchoEnabled: Boolean =
try system.echo()
@ -839,7 +843,7 @@ object Terminal {
override def isColorEnabled: Boolean =
props
.map(_.color)
.getOrElse(isColorEnabledProp.getOrElse(formatEnabledInEnv))
.getOrElse(isColorEnabledProp.getOrElse(Terminal.isColorEnabled))
override def isSupershellEnabled: Boolean =
props
@ -963,8 +967,8 @@ object Terminal {
override def getStringCapability(capability: String): String = null
override def getWidth: Int = 0
override def inputStream: InputStream = nullInputStream
override def isAnsiSupported: Boolean = formatEnabledInEnv
override def isColorEnabled: Boolean = isColorEnabledProp.getOrElse(formatEnabledInEnv)
override def isAnsiSupported: Boolean = Terminal.isAnsiSupported
override def isColorEnabled: Boolean = isColorEnabledProp.getOrElse(Terminal.isColorEnabled)
override def isEchoEnabled: Boolean = false
override def isSuccessEnabled: Boolean = true
override def isSupershellEnabled: Boolean = false

View File

@ -18,7 +18,7 @@ import sbt.util.Logger
import sbt.ConcurrentRestrictions.Tag
import sbt.protocol.testing._
import sbt.internal.util.Util.{ AnyOps, none }
import sbt.internal.util.{ ConsoleAppender, RunningProcesses }
import sbt.internal.util.{ RunningProcesses, Terminal }
private[sbt] object ForkTests {
def apply(
@ -97,7 +97,7 @@ private[sbt] object ForkTests {
val is = new ObjectInputStream(socket.getInputStream)
try {
val config = new ForkConfiguration(ConsoleAppender.formatEnabledInEnv, parallel)
val config = new ForkConfiguration(Terminal.isAnsiSupported, parallel)
os.writeObject(config)
val taskdefs = opts.tests.map { t =>

View File

@ -10,13 +10,13 @@ package sbt
import java.util.regex.Pattern
import scala.Console.{ BOLD, RESET }
import sbt.internal.util.ConsoleAppender
import sbt.internal.util.Terminal
object Highlight {
def showMatches(pattern: Pattern)(line: String): Option[String] = {
val matcher = pattern.matcher(line)
if (ConsoleAppender.formatEnabledInEnv) {
if (Terminal.isColorEnabled) {
// ANSI codes like \033[39m (normal text color) don't work on Windows
val highlighted = matcher.replaceAll(scala.Console.RED + "$0" + RESET)
if (highlighted == line) None else Some(highlighted)
@ -26,5 +26,5 @@ object Highlight {
None
}
def bold(s: String) =
if (ConsoleAppender.formatEnabledInEnv) BOLD + s.replace(RESET, RESET + BOLD) + RESET else s
if (Terminal.isColorEnabled) BOLD + s.replace(RESET, RESET + BOLD) + RESET else s
}

View File

@ -15,7 +15,7 @@ import sbt.KeyRanks.{ DTask, Invisible }
import sbt.Scope.{ GlobalScope, ThisScope }
import sbt.internal.util.Types.const
import sbt.internal.util.complete.Parser
import sbt.internal.util._
import sbt.internal.util.{ Terminal => ITerminal, _ }
import Util._
import sbt.util.Show
import xsbti.VirtualFile
@ -173,7 +173,7 @@ object Def extends Init[Scope] with TaskMacroExtra with InitializeImplicits {
Scope.displayMasked(scoped.scope, scoped.key.label, mask, showZeroConfig)
def withColor(s: String, color: Option[String]): String =
withColor(s, color, useColor = ConsoleAppender.formatEnabledInEnv)
withColor(s, color, useColor = ITerminal.isColorEnabled)
def withColor(s: String, color: Option[String], useColor: Boolean): String = color match {
case Some(c) if useColor => c + s + scala.Console.RESET
case _ => s

View File

@ -10,7 +10,7 @@ package sbt.std
import sbt.SettingKey
import sbt.dsl.LinterLevel
import sbt.dsl.LinterLevel.{ Abort, Warn }
import sbt.internal.util.ConsoleAppender
import sbt.internal.util.Terminal
import sbt.internal.util.appmacro.{ Convert, LinterDSL }
import scala.io.AnsiColor
@ -191,10 +191,10 @@ object OnlyTaskDynLinterDSL extends BaseTaskLinterDSL {
}
object TaskLinterDSLFeedback {
private final val startBold = if (ConsoleAppender.formatEnabledInEnv) AnsiColor.BOLD else ""
private final val startRed = if (ConsoleAppender.formatEnabledInEnv) AnsiColor.RED else ""
private final val startGreen = if (ConsoleAppender.formatEnabledInEnv) AnsiColor.GREEN else ""
private final val reset = if (ConsoleAppender.formatEnabledInEnv) AnsiColor.RESET else ""
private final val startBold = if (Terminal.isColorEnabled) AnsiColor.BOLD else ""
private final val startRed = if (Terminal.isColorEnabled) AnsiColor.RED else ""
private final val startGreen = if (Terminal.isColorEnabled) AnsiColor.GREEN else ""
private final val reset = if (Terminal.isColorEnabled) AnsiColor.RESET else ""
private final val ProblemHeader = s"${startRed}problem$reset"
private final val SolutionHeader = s"${startGreen}solution$reset"

View File

@ -17,7 +17,7 @@ import sbt.Scope.Global
import sbt.internal.Aggregation.KeyValue
import sbt.internal.TaskName._
import sbt.internal._
import sbt.internal.util._
import sbt.internal.util.{ Terminal => ITerminal, _ }
import sbt.librarymanagement.{ Resolver, UpdateReport }
import sbt.std.Transform.DummyTaskMap
import sbt.util.{ Logger, Show }
@ -368,7 +368,7 @@ object EvaluateTask {
for ((key, msg, ex) <- keyed if (msg.isDefined || ex.isDefined)) {
val msgString = (msg.toList ++ ex.toList.map(ErrorHandling.reducedToString)).mkString("\n\t")
val log = getStreams(key, streams).log
val display = contextDisplay(state, ConsoleAppender.formatEnabledInEnv)
val display = contextDisplay(state, ITerminal.isColorEnabled)
log.error("(" + display.show(key) + ") " + msgString)
}
}

View File

@ -105,7 +105,7 @@ private[sbt] object xMain {
} finally {
// Clear any stray progress lines
ShutdownHooks.close()
if (ITerminal.formatEnabledInEnv) {
if (ITerminal.isAnsiSupported) {
System.out.print(ConsoleAppender.ClearScreenAfterCursor)
System.out.flush()
}

View File

@ -14,7 +14,7 @@ import sbt.Def.ScopedKey
import sbt.Keys._
import sbt.Scope.GlobalScope
import sbt.internal.util.MainAppender._
import sbt.internal.util._
import sbt.internal.util.{ Terminal => ITerminal, _ }
import sbt.util.{ Level, LogExchange, Logger, LoggerContext }
import org.apache.logging.log4j.core.{ Appender => XAppender }
@ -319,7 +319,7 @@ object LogManager {
private[this] def slog: Logger =
Option(ref.get) getOrElse sys.error("Settings logger used after project was loaded.")
override val ansiCodesSupported = ConsoleAppender.formatEnabledInEnv
override val ansiCodesSupported = ITerminal.isAnsiSupported
override def trace(t: => Throwable) = slog.trace(t)
override def success(message: => String) = slog.success(message)
override def log(level: Level.Value, message: => String) = slog.log(level, message)

View File

@ -114,10 +114,10 @@ object RemoteCache {
findJar(classifier, v, jars) match {
case Some(jar) =>
extractJar(art, jar)
log.info(s"remote cache artifact extracted for $classifier")
log.info(s"remote cache artifact extracted for $p $classifier")
case None =>
log.info(s"remote cache artifact not found for $classifier")
log.info(s"remote cache artifact not found for $p $classifier")
}
}
found = true

View File

@ -12,7 +12,7 @@ import java.util.Locale
import scala.util.control.NonFatal
import scala.concurrent.duration._
import sbt.internal.util.ConsoleAppender
import sbt.internal.util.{ Terminal => ITerminal }
import sbt.internal.util.complete.SizeParser
// See also BuildPaths.scala
@ -106,7 +106,7 @@ object SysProp {
* 3. -Dsbt.colour=always/auto/never/true/false
* 4. -Dsbt.log.format=always/auto/never/true/false
*/
lazy val color: Boolean = ConsoleAppender.formatEnabledInEnv
lazy val color: Boolean = ITerminal.isColorEnabled
def closeClassLoaders: Boolean = getOrFalse("sbt.classloader.close")

View File

@ -9,7 +9,7 @@ package sbt
package internal.testing
import testing.{ Logger => TLogger }
import sbt.internal.util.{ BufferedAppender, ConsoleAppender, ManagedLogger }
import sbt.internal.util.{ BufferedAppender, ManagedLogger, Terminal }
import sbt.util.{ Level, ShowLines }
import sbt.protocol.testing._
import java.util.concurrent.atomic.AtomicInteger
@ -96,7 +96,7 @@ object TestLogger {
def debug(s: String) = log(Level.Debug, TestStringEvent(s))
def trace(t: Throwable) = logger.trace(t)
private def log(level: Level.Value, event: TestStringEvent) = logger.logEvent(level, event)
def ansiCodesSupported() = ConsoleAppender.formatEnabledInEnv
def ansiCodesSupported() = Terminal.isAnsiSupported
}
private[sbt] def toTestItemEvent(event: TestEvent): TestItemEvent =