Improve supershell appender management

To avoid reliance on jvm global variables, we need to share the super
shell state with each of the console appenders that write to the console
out. We only set the progress state for the console appenders for the
screen. This prevents messages that are below the global logging level
from modifying the progress state without preventing them from being
written to other appenders.

The ability to set the ProgressState for each of the console appenders
is added in a companion util PR.

I verified that the test output of io/test was correctly written to the
streams after this change (there were no progress lines in the output).
This commit is contained in:
Ethan Atkins 2019-09-02 23:58:42 -07:00
parent 4f2ffe9b36
commit 7c31e03d27
6 changed files with 26 additions and 19 deletions

View File

@ -298,14 +298,13 @@ object Defaults extends BuildCommon {
turbo :== SysProp.turbo,
useSuperShell := { if (insideCI.value) false else SysProp.supershell },
progressReports := {
val progress = (ThisBuild / useSuperShell).value
val rs = EvaluateTask.taskTimingProgress.toVector ++
EvaluateTask.taskTraceEvent.toVector ++ {
if (progress) Vector(EvaluateTask.taskProgress)
else Vector()
}
val rs = EvaluateTask.taskTimingProgress.toVector ++ EvaluateTask.taskTraceEvent.toVector
rs map { Keys.TaskProgress(_) }
},
progressState := {
if ((ThisBuild / useSuperShell).value) Some(new ProgressState(SysProp.supershellBlankZone))
else None
},
Previous.cache := new Previous(
Def.streamsManagerKey.value,
Previous.references.value.getReferences

View File

@ -165,12 +165,6 @@ object EvaluateTask {
Some(sharedTraceEvent)
} else None
def taskProgress: ExecuteProgress[Task] = {
val appender = MainAppender.defaultScreen(StandardMain.console)
val log = LogManager.progressLogger(appender)
new TaskProgress(log)
}
// sbt-pgp calls this
@deprecated("No longer used", "1.3.0")
private[sbt] def defaultProgress(): ExecuteProgress[Task] = ExecuteProgress.empty[Task]
@ -236,12 +230,19 @@ object EvaluateTask {
extracted,
structure
)
val reporters = maker.map(_.progress) ++
val progressReporter = extracted.get(progressState in ThisBuild).map { ps =>
ps.reset()
ConsoleAppender.setShowProgress(true)
val appender = MainAppender.defaultScreen(StandardMain.console)
appender match {
case c: ConsoleAppender => c.setProgressState(ps)
case _ =>
}
val log = LogManager.progressLogger(appender)
new TaskProgress(log)
}
val reporters = maker.map(_.progress) ++ progressReporter ++
(if (SysProp.taskTimings) new TaskTimings(reportOnShutdown = false) :: Nil else Nil)
// configure the logger for super shell
ConsoleAppender.setShowProgress((reporters collect {
case p: TaskProgress => ()
}).nonEmpty)
reporters match {
case xs if xs.isEmpty => ExecuteProgress.empty[Task]
case xs if xs.size == 1 => xs.head

View File

@ -24,7 +24,7 @@ import sbt.internal.inc.ScalaInstance
import sbt.internal.io.WatchState
import sbt.internal.librarymanagement.{ CompatibilityWarningOptions, IvySbt }
import sbt.internal.server.ServerHandler
import sbt.internal.util.{ AttributeKey, SourcePosition }
import sbt.internal.util.{ AttributeKey, ProgressState, SourcePosition }
import sbt.io._
import sbt.librarymanagement.Configurations.CompilerPlugin
import sbt.librarymanagement.LibraryManagementCodec._
@ -484,6 +484,7 @@ object Keys {
val turbo = settingKey[Boolean]("Enables (true) or disables optional performance features.")
// This key can be used to add custom ExecuteProgress instances
val progressReports = settingKey[Seq[TaskProgress]]("A function that returns a list of progress reporters.").withRank(DTask)
private[sbt] val progressState = settingKey[Option[ProgressState]]("The optional progress state if supershell is enabled.").withRank(Invisible)
private[sbt] val postProgressReports = settingKey[Unit]("Internally used to modify logger.").withRank(DTask)
@deprecated("No longer used", "1.3.0")
private[sbt] val executeProgress = settingKey[State => TaskProgress]("Experimental task execution listener.").withRank(DTask)

View File

@ -140,7 +140,12 @@ object LogManager {
val screenTrace = getOr(traceLevel.key, data, scope, state, defaultTraceLevel(state))
val backingTrace = getOr(persistTraceLevel.key, data, scope, state, Int.MaxValue)
val extraBacked = state.globalLogging.backed :: relay :: Nil
val ps = Project.extract(state).get(sbt.Keys.progressState in ThisBuild)
val consoleOpt = consoleLocally(state, console)
consoleOpt foreach {
case a: ConsoleAppender => ps.foreach(a.setProgressState)
case _ =>
}
val config = MainAppender.MainAppenderConfig(
consoleOpt,
backed,

View File

@ -91,6 +91,7 @@ object SysProp {
def supershell: Boolean = booleanOpt("sbt.supershell").getOrElse(color)
def supershellSleep: Long = long("sbt.supershell.sleep", 100L)
def supershellBlankZone: Int = int("sbt.supershell.blankzone", 5)
def defaultUseCoursier: Boolean = {
val coursierOpt = booleanOpt("sbt.coursier")

View File

@ -11,7 +11,7 @@ object Dependencies {
// sbt modules
private val ioVersion = nightlyVersion.getOrElse("1.3.0-M17")
private val utilVersion = nightlyVersion.getOrElse("1.3.0-M12")
private val utilVersion = nightlyVersion.getOrElse("1.3.0")
private val lmVersion =
sys.props.get("sbt.build.lm.version") match {
case Some(version) => version