From d2b1426a1fa6823536d36c9cff40202e625725e9 Mon Sep 17 00:00:00 2001 From: mkljakubowski Date: Thu, 29 Aug 2019 15:22:42 +0200 Subject: [PATCH 01/11] evaluate test result only once --- testing/src/main/scala/sbt/JUnitXmlTestsListener.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala index 7dfc84776..e95d87923 100644 --- a/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala +++ b/testing/src/main/scala/sbt/JUnitXmlTestsListener.scala @@ -244,8 +244,9 @@ class JUnitXmlTestsListener(val outputDir: String, logger: Logger) extends Tests new File(targetDir, s"TEST-${normalizeName(withTestSuite(_.name))}.xml").getAbsolutePath // TODO would be nice to have a logger and log this with level debug // System.err.println("Writing JUnit XML test report: " + file) - XML.save(legacyFile, withTestSuite(_.stop()), "UTF-8", true, null) - XML.save(file, withTestSuite(_.stop()), "UTF-8", true, null) + val testSuiteResult = withTestSuite(_.stop()) + XML.save(legacyFile, testSuiteResult, "UTF-8", true, null) + XML.save(file, testSuiteResult, "UTF-8", true, null) testSuite.remove() } From 49bcef029d63de3df116ebb7434ef20bc5a21f78 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Sat, 31 Aug 2019 16:37:41 -0700 Subject: [PATCH 02/11] Display only valid pages in scripted completions The tab completions for scripted have long been broken. They display a number of non-sensical pages like '*0of9' or '*1of0'. Some of the multiparser changes seem to have caused these invalid --- main/src/main/scala/sbt/ScriptedPlugin.scala | 6 ++++-- project/Scripted.scala | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/main/src/main/scala/sbt/ScriptedPlugin.scala b/main/src/main/scala/sbt/ScriptedPlugin.scala index 113fdd114..0cd518d27 100644 --- a/main/src/main/scala/sbt/ScriptedPlugin.scala +++ b/main/src/main/scala/sbt/ScriptedPlugin.scala @@ -136,8 +136,10 @@ object ScriptedPlugin extends AutoPlugin { val groupP = token(id.examples(pairMap.keySet)) <~ token('/') // A parser for page definitions - val pageP: Parser[ScriptedTestPage] = ("*" ~ NatBasic ~ "of" ~ NatBasic) map { - case _ ~ page ~ _ ~ total => ScriptedTestPage(page, total) + val pageNumber = NatBasic & not('0', "zero page number") + val pageP: Parser[ScriptedTestPage] = ("*" ~> pageNumber ~ ("of" ~> pageNumber)) flatMap { + case (page, total) if page <= total => success(ScriptedTestPage(page, total)) + case (page, total) => failure(s"Page $page was greater than $total") } // Grabs the filenames from a given test group in the current page definition. diff --git a/project/Scripted.scala b/project/Scripted.scala index 67194b2cf..30e2868b3 100644 --- a/project/Scripted.scala +++ b/project/Scripted.scala @@ -53,8 +53,10 @@ object Scripted { val groupP = token(id.examples(pairMap.keySet)) <~ token('/') // A parser for page definitions - val pageP: Parser[ScriptedTestPage] = ("*" ~ NatBasic ~ "of" ~ NatBasic) map { - case _ ~ page ~ _ ~ total => ScriptedTestPage(page, total) + val pageNumber = NatBasic & not('0', "zero page number") + val pageP: Parser[ScriptedTestPage] = ("*" ~> pageNumber ~ ("of" ~> pageNumber)) flatMap { + case (page, total) if page <= total => success(ScriptedTestPage(page, total)) + case (page, total) => failure(s"Page $page was greater than $total") } // Grabs the filenames from a given test group in the current page definition. From 30ede13a0909406e50c2b7b066328b9dd589bf4b Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Sat, 31 Aug 2019 12:46:10 -0700 Subject: [PATCH 03/11] Fix task timings I noticed that the reports generated when using sbt.task.timings=true made very little sense. They were displaying timings for tests that couldn't possibly have been run. I tracked this down to the TaskTimings be stored in the progressReport setting which meant they were reused across multiple task runs. After this change, the reports made a lot more sense. --- main/src/main/scala/sbt/EvaluateTask.scala | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index a056beb0e..359f92291 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -156,12 +156,8 @@ object EvaluateTask { lazy private val sharedProgress = new TaskTimings(reportOnShutdown = true) def taskTimingProgress: Option[ExecuteProgress[Task]] = - if (SysProp.taskTimings) { - if (SysProp.taskTimingsOnShutdown) - Some(sharedProgress) - else - Some(new TaskTimings(reportOnShutdown = false)) - } else None + if (SysProp.taskTimingsOnShutdown) Some(sharedProgress) + else None lazy private val sharedTraceEvent = new TaskTraceEvent() def taskTraceEvent: Option[ExecuteProgress[Task]] = @@ -240,7 +236,8 @@ object EvaluateTask { extracted, structure ) - val reporters = maker map { _.progress } + val reporters = maker.map(_.progress) ++ + (if (SysProp.taskTimings) new TaskTimings(reportOnShutdown = false) :: Nil else Nil) // configure the logger for super shell ConsoleAppender.setShowProgress((reporters collect { case p: TaskProgress => () From c525fa25516c18a817f8a50ab7a1527d90651f16 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Sat, 31 Aug 2019 12:49:14 -0700 Subject: [PATCH 04/11] Use managedFileStampCache for dependency classpath It is redundant and slow to restamp all of the dependency classpath files when they have likely already been stamped by a subproject. For the classfiles of subprojects, we fill the managedFileStampCache with the values returned by the zinc compile analysis product stamps. This is why they are probably already in the managed cache and should be up to date so long as zinc is working correctly. I noticed that various outputFileStamps tasks were showing up in the task timing report when I ran Test / definedTests in the main sbt project. That task became about 400ms faster after this change. --- main/src/main/scala/sbt/Defaults.scala | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index c8062c48f..3205c1a3a 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2041,7 +2041,12 @@ object Classpaths { excludeFilter in unmanagedJars value ) ).map(exportClasspath) ++ Seq( - sbt.nio.Keys.dependencyClasspathFiles := data(dependencyClasspath.value).map(_.toPath), + dependencyClasspathFiles := data(dependencyClasspath.value).map(_.toPath), + dependencyClasspathFiles / outputFileStamps := { + val cache = managedFileStampCache.value + val stamper = outputFileStamper.value + dependencyClasspathFiles.value.flatMap(p => cache.getOrElseUpdate(p, stamper).map(p -> _)) + } ) private[this] def exportClasspath(s: Setting[Task[Classpath]]): Setting[Task[Classpath]] = From a02a58dcfaa7888be55143956388444e0c518ba3 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 2 Sep 2019 11:23:05 -0700 Subject: [PATCH 05/11] Allow supershell in no color mode Disabling supershell when color mode is disabled is a sensible default (especially for piped output). However, I think it should still be possible to use supershell in no color mode. This requires a util change that also enables supershell in no color mode. --- main/src/main/scala/sbt/internal/SysProp.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main/src/main/scala/sbt/internal/SysProp.scala b/main/src/main/scala/sbt/internal/SysProp.scala index fa34b7822..73e504a4c 100644 --- a/main/src/main/scala/sbt/internal/SysProp.scala +++ b/main/src/main/scala/sbt/internal/SysProp.scala @@ -88,7 +88,7 @@ object SysProp { def fileCacheSize: Long = SizeParser(System.getProperty("sbt.file.cache.size", "128M")).getOrElse(128L * 1024 * 1024) - def supershell: Boolean = color && getOrTrue("sbt.supershell") + def supershell: Boolean = booleanOpt("sbt.supershell").getOrElse(color) def supershellSleep: Long = long("sbt.supershell.sleep", 100L) From b996675c935d9ce68e30eec1be9eb26f2d8d2488 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 2 Sep 2019 14:48:36 -0700 Subject: [PATCH 06/11] Name test tasks with the test name Ref https://github.com/sbt/sbt/issues/4911. This names each parallel test task with the name of the task so that supershell can display it. It only applies for parallel tests. When run sequentially, supershell will still display executeTests. --- main-actions/src/main/scala/sbt/Tests.scala | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/main-actions/src/main/scala/sbt/Tests.scala b/main-actions/src/main/scala/sbt/Tests.scala index 0c89b1dd0..80d651bd9 100644 --- a/main-actions/src/main/scala/sbt/Tests.scala +++ b/main-actions/src/main/scala/sbt/Tests.scala @@ -306,7 +306,10 @@ object Tests { fun: TestFunction, tags: Seq[(Tag, Int)] ): Task[Map[String, SuiteResult]] = { - val base = task { (name, fun.apply()) } + val base = Task[(String, (SuiteResult, Seq[TestTask]))]( + Info[(String, (SuiteResult, Seq[TestTask]))]().setName(name), + Pure(() => (name, fun.apply()), `inline` = false) + ) val taggedBase = base.tagw(tags: _*).tag(fun.tags.map(ConcurrentRestrictions.Tag(_)): _*) taggedBase flatMap { case (name, (result, nested)) => From 7c31e03d2736147ab0e8e4a96c776aa772b370d3 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Mon, 2 Sep 2019 23:58:42 -0700 Subject: [PATCH 07/11] 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 From fa3a09368efb81ad5c3a791626ebbf1df474995e Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 3 Sep 2019 23:51:13 -0400 Subject: [PATCH 08/11] bump io, lm, and zinc to 1.3.0 --- project/Dependencies.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/project/Dependencies.scala b/project/Dependencies.scala index c6592d052..0a3aa0bc5 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -10,14 +10,14 @@ object Dependencies { def nightlyVersion: Option[String] = sys.props.get("sbt.build.version") // sbt modules - private val ioVersion = nightlyVersion.getOrElse("1.3.0-M17") + private val ioVersion = nightlyVersion.getOrElse("1.3.0") private val utilVersion = nightlyVersion.getOrElse("1.3.0") private val lmVersion = sys.props.get("sbt.build.lm.version") match { case Some(version) => version - case _ => nightlyVersion.getOrElse("1.3.0-M8") + case _ => nightlyVersion.getOrElse("1.3.0") } - val zincVersion = nightlyVersion.getOrElse("1.3.0-M9") + val zincVersion = nightlyVersion.getOrElse("1.3.0") private val sbtIO = "org.scala-sbt" %% "io" % ioVersion From 665eb8f8709a9c74a4291f20546025da339f5572 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Wed, 4 Sep 2019 01:24:08 -0400 Subject: [PATCH 09/11] sbt 1.3.0 --- build.sbt | 2 +- project/build.properties | 2 +- src/main/conscript/scalas/launchconfig | 2 +- src/main/conscript/screpl/launchconfig | 2 +- src/main/conscript/xsbt/launchconfig | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build.sbt b/build.sbt index 34ec14849..ec648ffb8 100644 --- a/build.sbt +++ b/build.sbt @@ -8,7 +8,7 @@ import scala.xml.transform.{ RewriteRule, RuleTransformer } import scala.util.Try ThisBuild / version := { - val v = "1.3.0-SNAPSHOT" + val v = "1.3.1-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / scalafmtOnCompile := !(Global / insideCI).value diff --git a/project/build.properties b/project/build.properties index 2bdd560f2..080a737ed 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.0-RC4 +sbt.version=1.3.0 diff --git a/src/main/conscript/scalas/launchconfig b/src/main/conscript/scalas/launchconfig index ff9e8dae5..f972decaf 100644 --- a/src/main/conscript/scalas/launchconfig +++ b/src/main/conscript/scalas/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[1.2.0]} + version: ${sbt.version-read(sbt.version)[1.3.0]} class: sbt.ScriptMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/screpl/launchconfig b/src/main/conscript/screpl/launchconfig index ff6e22916..cb9f15e6c 100644 --- a/src/main/conscript/screpl/launchconfig +++ b/src/main/conscript/screpl/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[1.2.0]} + version: ${sbt.version-read(sbt.version)[1.3.0]} class: sbt.ConsoleMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} diff --git a/src/main/conscript/xsbt/launchconfig b/src/main/conscript/xsbt/launchconfig index f65ff3ced..854c9bfc2 100644 --- a/src/main/conscript/xsbt/launchconfig +++ b/src/main/conscript/xsbt/launchconfig @@ -4,7 +4,7 @@ [app] org: ${sbt.organization-org.scala-sbt} name: sbt - version: ${sbt.version-read(sbt.version)[1.2.0]} + version: ${sbt.version-read(sbt.version)[1.3.0]} class: sbt.xMain components: xsbti,extra cross-versioned: ${sbt.cross.versioned-false} From a0dc3fc06a7b923d4556a4c2e6305d6a76069aa3 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 5 Sep 2019 10:18:03 -0700 Subject: [PATCH 10/11] Bump sbt dogfood version --- project/build.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/project/build.properties b/project/build.properties index c8997c4a9..080a737ed 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.3.0-RC5 +sbt.version=1.3.0 From a82e7892abf9f33b219a94ce57342dc504c8b1a0 Mon Sep 17 00:00:00 2001 From: Ethan Atkins Date: Thu, 5 Sep 2019 10:38:57 -0700 Subject: [PATCH 11/11] Bump sbt version --- build.sbt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sbt b/build.sbt index 704a6be0d..98da9bcee 100644 --- a/build.sbt +++ b/build.sbt @@ -8,7 +8,7 @@ import scala.xml.transform.{ RewriteRule, RuleTransformer } import scala.util.Try ThisBuild / version := { - val v = "1.3.1-SNAPSHOT" + val v = "1.4.0-SNAPSHOT" nightlyVersion.getOrElse(v) } ThisBuild / scalafmtOnCompile := !(Global / insideCI).value