From 7c31e03d2736147ab0e8e4a96c776aa772b370d3 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 2 Sep 2019 23:58:42 -0700 Subject: [PATCH] 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). --- main/src/main/scala/sbt/Defaults.scala | 11 ++++----- main/src/main/scala/sbt/EvaluateTask.scala | 23 ++++++++++--------- main/src/main/scala/sbt/Keys.scala | 3 ++- .../main/scala/sbt/internal/LogManager.scala | 5 ++++ .../src/main/scala/sbt/internal/SysProp.scala | 1 + project/Dependencies.scala | 2 +- 6 files changed, 26 insertions(+), 19 deletions(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 3205c1a3a..6e433bc81 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -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 diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index 359f92291..a5e313464 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -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 diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 438c551ae..a54df46c6 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -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) diff --git a/main/src/main/scala/sbt/internal/LogManager.scala b/main/src/main/scala/sbt/internal/LogManager.scala index 178dd97f9..2563e6c1e 100644 --- a/main/src/main/scala/sbt/internal/LogManager.scala +++ b/main/src/main/scala/sbt/internal/LogManager.scala @@ -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, diff --git a/main/src/main/scala/sbt/internal/SysProp.scala b/main/src/main/scala/sbt/internal/SysProp.scala index 73e504a4c..72f4af731 100644 --- a/main/src/main/scala/sbt/internal/SysProp.scala +++ b/main/src/main/scala/sbt/internal/SysProp.scala @@ -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") diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 7a1afc502..c6592d052 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -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