diff --git a/main-command/src/main/scala/sbt/MainControl.scala b/main-command/src/main/scala/sbt/MainControl.scala index 4a959fd19..69d0d2fdb 100644 --- a/main-command/src/main/scala/sbt/MainControl.scala +++ b/main-command/src/main/scala/sbt/MainControl.scala @@ -21,8 +21,6 @@ final case class Reboot( def arguments = argsList.toArray } -private[sbt] case object Reload extends Exception(null, null, false, false) - final case class ApplicationID( groupID: String, name: String, diff --git a/main/src/main/scala/sbt/EvaluateTask.scala b/main/src/main/scala/sbt/EvaluateTask.scala index 784fd8197..a056beb0e 100644 --- a/main/src/main/scala/sbt/EvaluateTask.scala +++ b/main/src/main/scala/sbt/EvaluateTask.scala @@ -346,7 +346,7 @@ object EvaluateTask { ExceptionCategory(ex) match { case AlreadyHandled => () case m: MessageOnly => if (msg.isEmpty) log.error(m.message) - case f: Full => if (f.exception != Reload) log.trace(f.exception) + case f: Full => log.trace(f.exception) } } @@ -354,7 +354,7 @@ object EvaluateTask { val msgString = (msg.toList ++ ex.toList.map(ErrorHandling.reducedToString)).mkString("\n\t") val log = getStreams(key, streams).log val display = contextDisplay(state, ConsoleAppender.formatEnabledInEnv) - if (!ex.contains(Reload)) log.error("(" + display.show(key) + ") " + msgString) + log.error("(" + display.show(key) + ") " + msgString) } } diff --git a/main/src/main/scala/sbt/MainLoop.scala b/main/src/main/scala/sbt/MainLoop.scala index 14c0937cc..99bc333aa 100644 --- a/main/src/main/scala/sbt/MainLoop.scala +++ b/main/src/main/scala/sbt/MainLoop.scala @@ -144,10 +144,7 @@ object MainLoop { case Right(s) => s case Left(t: xsbti.FullReload) => throw t case Left(t: RebootCurrent) => throw t - case Left(Reload) => - val remaining = state.currentCommand.toList ::: state.remainingCommands - state.copy(remainingCommands = Exec("reload", None, None) :: remaining) - case Left(t) => state.handleError(t) + case Left(t) => state.handleError(t) } } catch { case oom: OutOfMemoryError if oom.getMessage.contains("Metaspace") => diff --git a/main/src/main/scala/sbt/internal/Aggregation.scala b/main/src/main/scala/sbt/internal/Aggregation.scala index cf6b19d44..df7e43ee3 100644 --- a/main/src/main/scala/sbt/internal/Aggregation.scala +++ b/main/src/main/scala/sbt/internal/Aggregation.scala @@ -9,17 +9,14 @@ package sbt package internal import java.text.DateFormat -import java.util.{ Collections, IdentityHashMap } -import Def.ScopedKey -import Keys.{ showSuccess, showTiming, timingFormat } +import sbt.Def.ScopedKey +import sbt.Keys.{ showSuccess, showTiming, timingFormat } import sbt.internal.util.complete.Parser -import sbt.internal.util.{ AttributeKey, Dag, HList, Settings, Util } +import sbt.internal.util.complete.Parser.{ failure, seq, success } +import sbt.internal.util._ +import sbt.std.Transform.DummyTaskMap import sbt.util.{ Logger, Show } -import Parser.{ failure, seq, success } -import std.Transform.DummyTaskMap - -import scala.annotation.tailrec sealed trait Aggregation object Aggregation { @@ -115,25 +112,7 @@ object Aggregation { )(implicit display: Show[ScopedKey[_]]): State = { val complete = timedRun[T](s, ts, extra) showRun(complete, show) - /* - * In the first implementation, we tried to use Set[Incomplete] for visited. It had very poor - * performance because hashCode can be expensive on Incomplete -- especially when the - * Incomplete has many instances in the causes field. - */ - lazy val visited = Collections - .newSetFromMap[Incomplete](new IdentityHashMap[Incomplete, java.lang.Boolean]) - @tailrec def findReload(incomplete: Incomplete, remaining: List[Incomplete]): Boolean = { - visited.add(incomplete) - incomplete.directCause.contains(Reload) || ((remaining ::: incomplete.causes.toList) - .filterNot(visited.contains) match { - case Nil => false - case h :: tail => findReload(h, tail.filterNot(visited.contains)) - }) - } complete.results match { - case Inc(i) if findReload(i, i.causes.toList) => - val remaining = s.currentCommand.toList ::: s.remainingCommands - complete.state.copy(remainingCommands = Exec("reload", None, None) :: remaining) case Inc(i) => complete.state.handleError(i) case Value(_) => complete.state } diff --git a/main/src/main/scala/sbt/internal/nio/CheckBuildSources.scala b/main/src/main/scala/sbt/internal/nio/CheckBuildSources.scala index 289a50d17..3aeaf5b57 100644 --- a/main/src/main/scala/sbt/internal/nio/CheckBuildSources.scala +++ b/main/src/main/scala/sbt/internal/nio/CheckBuildSources.scala @@ -15,12 +15,12 @@ import sbt.nio.Keys._ import sbt.nio.file.{ ChangedFiles, Glob, RecursiveGlob } private[sbt] object CheckBuildSources { - private[sbt] def needReloadImpl: Def.Initialize[Task[Unit]] = Def.task { + private[sbt] def needReloadImpl: Def.Initialize[Task[StateTransform]] = Def.task { val logger = streams.value.log - val checkMetaBuildParam = state.value.get(hasCheckedMetaBuild) - val firstTime = checkMetaBuildParam.fold(true)(_.get == false) + val st: State = state.value + val firstTime = st.get(hasCheckedMetaBuild).fold(true)(_.compareAndSet(false, true)) (onChangedBuildSource in Scope.Global).value match { - case IgnoreSourceChanges => () + case IgnoreSourceChanges => new StateTransform(st) case o => logger.debug("Checking for meta build source updates") (changedInputFiles in checkBuildSources).value match { @@ -37,18 +37,20 @@ private[sbt] object CheckBuildSources { val prefix = rawPrefix.linesIterator.filterNot(_.trim.isEmpty).mkString("\n") if (o == ReloadOnSourceChanges) { logger.info(s"$prefix\nReloading sbt...") - throw Reload + val remaining = + Exec("reload", None, None) :: st.currentCommand.toList ::: st.remainingCommands + new StateTransform(st.copy(currentCommand = None, remainingCommands = remaining)) } else { val tail = "Apply these changes by running `reload`.\nAutomatically reload the " + "build when source changes are detected by setting " + "`Global / onChangedBuildSource := ReloadOnSourceChanges`.\nDisable this " + "warning by setting `Global / onChangedBuildSource := IgnoreSourceChanges`." logger.warn(s"$prefix\n$tail") + new StateTransform(st) } - case _ => () + case _ => new StateTransform(st) } } - checkMetaBuildParam.foreach(_.set(true)) } private[sbt] def buildSourceFileInputs: Def.Initialize[Seq[Glob]] = Def.setting { if (onChangedBuildSource.value != IgnoreSourceChanges) { diff --git a/main/src/main/scala/sbt/nio/Keys.scala b/main/src/main/scala/sbt/nio/Keys.scala index 4da20e066..e15bda4e6 100644 --- a/main/src/main/scala/sbt/nio/Keys.scala +++ b/main/src/main/scala/sbt/nio/Keys.scala @@ -50,7 +50,7 @@ object Keys { taskKey[FileTreeView.Nio[FileAttributes]]("A view of the local file system tree") val checkBuildSources = - taskKey[Unit]("Check if any meta build sources have changed").withRank(DSetting) + taskKey[StateTransform]("Check if any meta build sources have changed").withRank(DSetting) // watch related settings val watchAntiEntropyRetentionPeriod = settingKey[FiniteDuration](