From 8aa740574b91d670919df50663218688cc7eac27 Mon Sep 17 00:00:00 2001 From: Eugene Yokota Date: Tue, 1 Oct 2024 03:15:28 -0400 Subject: [PATCH] Move suspendChannel to EvaluateTask --- .../main/scala/sbt/BackgroundJobService.scala | 7 ++++++- main/src/main/scala/sbt/Defaults.scala | 18 ++++-------------- main/src/main/scala/sbt/EvaluateTask.scala | 11 +++++++++++ main/src/main/scala/sbt/Keys.scala | 6 +++--- .../main/scala/sbt/internal/Aggregation.scala | 18 +++++++++++++----- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/main/src/main/scala/sbt/BackgroundJobService.scala b/main/src/main/scala/sbt/BackgroundJobService.scala index 973ebe075..e268b96ce 100644 --- a/main/src/main/scala/sbt/BackgroundJobService.scala +++ b/main/src/main/scala/sbt/BackgroundJobService.scala @@ -111,4 +111,9 @@ abstract class JobHandle { def spawningTask: ScopedKey[_] } -case class RunInfo(handle: JobHandle) +/** + * This datatype is used signal the task engine or the commands + * that the background job is emulated to be a foreground job on + * the originating channel. + */ +case class EmulateForeground(handle: JobHandle) diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index ee3088346..05fa8d9fd 100644 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -2152,27 +2152,17 @@ object Defaults extends BuildCommon { } // `runMain` calls bgRunMain in the background and pauses the current channel - def foregroundRunMainTask: Initialize[InputTask[RunInfo]] = + def foregroundRunMainTask: Initialize[InputTask[EmulateForeground]] = Def.inputTask { val handle = bgRunMain.evaluated - val service = bgJobService.value - val st = state.value - st.remainingCommands match - case Nil => service.waitForTry(handle).get - case _ => service.pauseChannelDuringJob(st, handle) - RunInfo(handle) + EmulateForeground(handle) } // `run` task calls bgRun in the background and pauses the current channel - def foregroundRunTask: Initialize[InputTask[RunInfo]] = + def foregroundRunTask: Initialize[InputTask[EmulateForeground]] = Def.inputTask { val handle = bgRun.evaluated - val service = bgJobService.value - val st = state.value - st.remainingCommands match - case Nil => service.waitForTry(handle).get - case _ => service.pauseChannelDuringJob(st, handle) - RunInfo(handle) + EmulateForeground(handle) } def runMainTask( diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index 3e1dabea6..b9f6be65b 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -512,6 +512,16 @@ object EvaluateTask { case Some(t: Task[?]) => transformNode(t).isEmpty case _ => true } + def suspendChannel[A1]( + state: State, + result: Result[A1] + ): Unit = + (state.getSetting(Global / Keys.bgJobService), result) match + case (Some(service), Result.Value(List(KeyValue(_, EmulateForeground(handle))))) => + state.remainingCommands match + case Nil => service.waitForTry(handle).get + case _ => service.pauseChannelDuringJob(state, handle) + case _ => () def run() = { val x = new Execute( Execute.config(config.checkCycles, overwriteNode), @@ -529,6 +539,7 @@ object EvaluateTask { } finally shutdown() val replaced = transformInc(result) logIncResult(replaced, state, streams) + suspendChannel(newState, replaced) (newState, replaced) } object runningEngine extends RunningTaskEngine { diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index bfa5b7225..c34311b5b 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -319,9 +319,9 @@ object Keys { // Run Keys val selectMainClass = taskKey[Option[String]]("Selects the main class to run.").withRank(BMinusTask) val mainClass = taskKey[Option[String]]("Defines the main class for packaging or running.").withRank(BPlusTask) - val run = inputKey[RunInfo]("Runs a main class, passing along arguments provided on the command line.").withRank(APlusTask) - val runBlock = inputKey[RunInfo]("Runs a main class, and blocks until it's done.").withRank(DTask) - val runMain = inputKey[RunInfo]("Runs the main class selected by the first argument, passing the remaining arguments to the main method.").withRank(ATask) + val run = inputKey[EmulateForeground]("Runs a main class, passing along arguments provided on the command line.").withRank(APlusTask) + val runBlock = inputKey[EmulateForeground]("Runs a main class, and blocks until it's done.").withRank(DTask) + val runMain = inputKey[EmulateForeground]("Runs the main class selected by the first argument, passing the remaining arguments to the main method.").withRank(ATask) val discoveredMainClasses = taskKey[Seq[String]]("Auto-detects main classes.").withRank(BMinusTask) val runner = taskKey[ScalaRun]("Implementation used to run a main class.").withRank(DTask) val trapExit = settingKey[Boolean]("If true, enables exit trapping and thread management for 'run'-like tasks. This was removed in sbt 1.6.0 due to JDK 17 deprecating Security Manager.").withRank(CSetting) diff --git a/main/src/main/scala/sbt/internal/Aggregation.scala b/main/src/main/scala/sbt/internal/Aggregation.scala index 7fb75371e..690788ce3 100644 --- a/main/src/main/scala/sbt/internal/Aggregation.scala +++ b/main/src/main/scala/sbt/internal/Aggregation.scala @@ -79,17 +79,25 @@ object Aggregation { val success = results match case Result.Value(_) => true case Result.Inc(_) => false - // run task ends earlier than the program run - val isRunInfo = results match - case Result.Value(Seq(KeyValue(_, RunInfo(_)))) => true - case _ => false + val isPaused = currentChannel(state) match + case Some(channel) => channel.isPaused + case None => false results.toEither.foreach { r => if show.taskValues then printSettings(r, show.print) else () } - if show.success && !isRunInfo && !state.get(suppressShow).getOrElse(false) then + if !isPaused && show.success && !state.get(suppressShow).getOrElse(false) then printSuccess(start, stop, extracted, success, cacheSummary, log) else () + private def currentChannel(state: State): Option[CommandChannel] = + state.currentCommand match + case Some(exec) => + exec.source match + case Some(source) => + StandardMain.exchange.channels.find(_.name == source.channelName) + case _ => None + case _ => None + def timedRun[A]( s: State, ts: Values[Task[A]],