diff --git a/build.sbt b/build.sbt index 1b75bd567..6c9cda6fb 100644 --- a/build.sbt +++ b/build.sbt @@ -18,6 +18,7 @@ ThisBuild / Test / scalafmtOnCompile := !(Global / insideCI).value def buildLevelSettings: Seq[Setting[_]] = inThisBuild( Seq( + doc in Compile := file("/dev/null"), organization := "org.scala-sbt", description := "sbt is an interactive build tool", bintrayOrganization := Some("sbt"), @@ -47,6 +48,7 @@ def buildLevelSettings: Seq[Setting[_]] = homepage := Some(url("https://github.com/sbt/sbt")), scmInfo := Some(ScmInfo(url("https://github.com/sbt/sbt"), "git@github.com:sbt/sbt.git")), resolvers += Resolver.mavenLocal, + scalafmtOnCompile := false, ) ) @@ -60,6 +62,7 @@ def commonSettings: Seq[Setting[_]] = Def.settings( |""".stripMargin ) ), + doc in Compile := file("/dev/null"), scalaVersion := baseScalaVersion, componentID := None, resolvers += Resolver.typesafeIvyRepo("releases"), @@ -393,6 +396,7 @@ lazy val scriptedSbtReduxProj = (project in file("scripted-sbt-redux")) .dependsOn(commandProj) .settings( baseSettings, + doc in Compile := file("/dev/null"), name := "Scripted sbt Redux", libraryDependencies ++= Seq(launcherInterface % "provided"), resourceGenerators in Compile += Def task { @@ -640,6 +644,7 @@ lazy val mainProj = (project in file("main")) ) .settings( testedBaseSettings, + doc in Compile := file("/dev/null"), name := "Main", checkPluginCross := { val sv = scalaVersion.value diff --git a/main-command/src/main/scala/sbt/BasicCommandStrings.scala b/main-command/src/main/scala/sbt/BasicCommandStrings.scala index 5240a060f..331852d12 100644 --- a/main-command/src/main/scala/sbt/BasicCommandStrings.scala +++ b/main-command/src/main/scala/sbt/BasicCommandStrings.scala @@ -151,7 +151,7 @@ $HelpCommand def Multi: String = ";" def MultiBrief: (String, String) = ( - Multi + " (" + Multi + " )*", + " (" + Multi + " )*", "Runs the provided semicolon-separated commands." ) def MultiDetailed: String = diff --git a/main-command/src/main/scala/sbt/MainControl.scala b/main-command/src/main/scala/sbt/MainControl.scala index 4995be5bf..4a959fd19 100644 --- a/main-command/src/main/scala/sbt/MainControl.scala +++ b/main-command/src/main/scala/sbt/MainControl.scala @@ -21,7 +21,7 @@ final case class Reboot( def arguments = argsList.toArray } -case object Reload extends Exception(null, null, false, false) +private[sbt] case object Reload extends Exception(null, null, false, false) final case class ApplicationID( groupID: String, diff --git a/main/src/main/scala/sbt/Defaults.scala b/main/src/main/scala/sbt/Defaults.scala index 79ad043c7..f430d0685 100755 --- a/main/src/main/scala/sbt/Defaults.scala +++ b/main/src/main/scala/sbt/Defaults.scala @@ -154,15 +154,11 @@ object Defaults extends BuildCommon { inputFileStamper :== sbt.nio.FileStamper.Hash, outputFileStamper :== sbt.nio.FileStamper.LastModified, onChangedBuildSource :== sbt.nio.Keys.WarnOnSourceChanges, - watchTriggeredMessage :== sbt.nio.Watch.defaultOnTriggerMessage, - watchForceTriggerOnAnyChange :== false, - watchPersistFileStamps :== true, - watchTriggers :== Nil, clean := { () }, unmanagedFileStampCache := state.value.get(persistentFileStampCache).getOrElse(new sbt.nio.FileStamp.Cache), managedFileStampCache := new sbt.nio.FileStamp.Cache, - ) ++ globalIvyCore ++ globalJvmCore + ) ++ globalIvyCore ++ globalJvmCore ++ Watch.defaults ) ++ globalSbtCore private[sbt] lazy val globalJvmCore: Seq[Setting[_]] = @@ -344,17 +340,6 @@ object Defaults extends BuildCommon { sys.env.contains("CI") || System.getProperty("sbt.ci", "false") == "true", // watch related settings pollInterval :== Watch.defaultPollInterval, - watchAntiEntropy :== Watch.defaultAntiEntropy, - watchAntiEntropyRetentionPeriod :== Watch.defaultAntiEntropyRetentionPeriod, - watchLogLevel :== Level.Info, - watchOnEnter :== Watch.defaultOnEnter, - watchOnFileInputEvent :== Watch.trigger, - watchDeletionQuarantinePeriod :== Watch.defaultDeletionQuarantinePeriod, - watchService :== Watched.newWatchService, - watchStartMessage :== Watch.defaultStartWatch, - watchTasks := Continuous.continuousTask.evaluated, - aggregate in watchTasks :== false, - watchTriggeredMessage :== Watch.defaultOnTriggerMessage, ) ) diff --git a/main/src/main/scala/sbt/Keys.scala b/main/src/main/scala/sbt/Keys.scala index 0057dd087..de3266bee 100644 --- a/main/src/main/scala/sbt/Keys.scala +++ b/main/src/main/scala/sbt/Keys.scala @@ -125,7 +125,6 @@ object Keys { val managedSources = taskKey[Seq[File]]("Sources generated by the build.").withRank(BTask) val sources = taskKey[Seq[File]]("All sources, both managed and unmanaged.").withRank(BTask) val sourcesInBase = settingKey[Boolean]("If true, sources from the project's base directory are included as main sources.") - val watchTriggers = settingKey[Seq[Glob]]("Describes files that should trigger a new continuous build.") // Filters val includeFilter = settingKey[FileFilter]("Filter for including sources and resources files from default directories.").withRank(CSetting) diff --git a/main/src/main/scala/sbt/ScriptedPlugin.scala b/main/src/main/scala/sbt/ScriptedPlugin.scala index 2bc1b13fe..113fdd114 100644 --- a/main/src/main/scala/sbt/ScriptedPlugin.scala +++ b/main/src/main/scala/sbt/ScriptedPlugin.scala @@ -12,6 +12,7 @@ import java.lang.reflect.Method import sbt.Def._ import sbt.Keys._ +import sbt.nio.Keys._ import sbt.Project._ import sbt.internal.inc.ModuleUtilities import sbt.internal.inc.classpath.ClasspathUtilities diff --git a/main/src/main/scala/sbt/internal/Continuous.scala b/main/src/main/scala/sbt/internal/Continuous.scala index a87060d34..f212e5b64 100644 --- a/main/src/main/scala/sbt/internal/Continuous.scala +++ b/main/src/main/scala/sbt/internal/Continuous.scala @@ -351,22 +351,22 @@ private[sbt] object Continuous extends DeprecatedContinuous { aggregate(configs, logger, in, s, currentCount, isCommand, commands, fileStampCache) val task = () => { currentCount.getAndIncrement() + callbacks.beforeCommand() // abort as soon as one of the tasks fails valid.takeWhile(_._3.apply()) updateLegacyWatchState(s, configs.flatMap(_.inputs().map(_.glob)), currentCount.get()) () } - callbacks.onEnter() - // Here we enter the Watched.watch state machine. We will not return until one of the - // state machine callbacks returns Watched.CancelWatch, Watched.Custom, Watched.HandleError - // or Watched.ReloadException. The task defined above will be run at least once. It will be run - // additional times whenever the state transition callbacks return Watched.Trigger. try { + // Here we enter the Watched.watch state machine. We will not return until one of the + // state machine callbacks returns Watched.CancelWatch, Watched.Custom, Watched.HandleError + // or Watched.ReloadException. The task defined above will be run at least once. It will be run + // additional times whenever the state transition callbacks return Watched.Trigger. val terminationAction = Watch(task, callbacks.onStart, callbacks.nextEvent) terminationAction match { case e: Watch.HandleUnexpectedError => - System.err.println("Caught unexpected error running continuous build:") - e.throwable.printStackTrace(System.err) + logger.error("Caught unexpected error running continuous build:") + e.throwable.getStackTrace.foreach(e => logger.error(e.toString)) case _ => } callbacks.onTermination(terminationAction, command, currentCount.get(), state) @@ -427,7 +427,7 @@ private[sbt] object Continuous extends DeprecatedContinuous { private class Callbacks( val nextEvent: () => Watch.Action, - val onEnter: () => Unit, + val beforeCommand: () => Unit, val onExit: () => Unit, val onStart: () => Watch.Action, val onTermination: (Watch.Action, String, Int, State) => State @@ -466,21 +466,18 @@ private[sbt] object Continuous extends DeprecatedContinuous { )( implicit extracted: Extracted ): Callbacks = { - val project = extracted.currentRef.project + val project = extracted.currentRef val logger = setLevel(rawLogger, configs.map(_.watchSettings.logLevel).min, state) - val onEnter = () => configs.foreach(_.watchSettings.onEnter()) + val beforeCommand = () => configs.foreach(_.watchSettings.beforeCommand()) val onStart: () => Watch.Action = getOnStart(project, commands, configs, rawLogger, count) val nextInputEvent: () => Watch.Action = parseInputEvents(configs, state, inputStream, logger) val (nextFileEvent, cleanupFileMonitor): (() => Option[(Watch.Event, Watch.Action)], () => Unit) = getFileEvents(configs, rawLogger, state, count, commands, fileStampCache) val nextEvent: () => Watch.Action = combineInputAndFileEvents(nextInputEvent, nextFileEvent, logger) - val onExit = () => { - cleanupFileMonitor() - configs.foreach(_.watchSettings.onExit()) - } + val onExit = () => cleanupFileMonitor() val onTermination = getOnTermination(configs, isCommand) - new Callbacks(nextEvent, onEnter, onExit, onStart, onTermination) + new Callbacks(nextEvent, beforeCommand, onExit, onStart, onTermination) } private def getOnTermination( @@ -500,7 +497,7 @@ private[sbt] object Continuous extends DeprecatedContinuous { } private def getOnStart( - project: String, + project: ProjectRef, commands: Seq[String], configs: Seq[Config], logger: Logger, @@ -509,7 +506,7 @@ private[sbt] object Continuous extends DeprecatedContinuous { val f: () => Seq[Watch.Action] = () => { configs.map { params => val ws = params.watchSettings - ws.onIteration.map(_(count.get)).getOrElse { + ws.onIteration.map(_(count.get, project, commands)).getOrElse { if (configs.size == 1) { // Only allow custom start messages for single tasks ws.startMessage match { case Some(Left(sm)) => logger.info(sm(params.watchState(count.get()))) @@ -900,11 +897,11 @@ private[sbt] object Continuous extends DeprecatedContinuous { val inputParser: Parser[Watch.Action] = key.get(watchInputParser).getOrElse(Watch.defaultInputParser) val logLevel: Level.Value = key.get(watchLogLevel).getOrElse(Level.Info) - val onEnter: () => Unit = key.get(watchOnEnter).getOrElse(() => {}) - val onExit: () => Unit = key.get(watchOnExit).getOrElse(() => {}) + val beforeCommand: () => Unit = key.get(watchBeforeCommand).getOrElse(() => {}) val onFileInputEvent: WatchOnEvent = key.get(watchOnFileInputEvent).getOrElse(Watch.trigger) - val onIteration: Option[Int => Watch.Action] = key.get(watchOnIteration) + val onIteration: Option[(Int, ProjectRef, Seq[String]) => Watch.Action] = + key.get(watchOnIteration) val onTermination: Option[(Watch.Action, String, Int, State) => State] = key.get(watchOnTermination) val startMessage: StartMessage = getStartMessage(key) diff --git a/main/src/main/scala/sbt/internal/DeprecatedContinuous.scala b/main/src/main/scala/sbt/internal/DeprecatedContinuous.scala index 1db908859..2bffd0801 100644 --- a/main/src/main/scala/sbt/internal/DeprecatedContinuous.scala +++ b/main/src/main/scala/sbt/internal/DeprecatedContinuous.scala @@ -10,14 +10,14 @@ package sbt.internal import java.nio.file.Path import java.util.concurrent.atomic.AtomicReference -import sbt.{ State, Watched } +import sbt.{ ProjectRef, State, Watched } import sbt.internal.io.{ EventMonitor, Source, WatchState => WS } import sbt.internal.util.AttributeKey import sbt.nio.file.Glob private[internal] trait DeprecatedContinuous { protected type StartMessage = - Option[Either[WS => String, (Int, String, Seq[String]) => Option[String]]] + Option[Either[WS => String, (Int, ProjectRef, Seq[String]) => Option[String]]] protected type TriggerMessage = Either[WS => String, (Int, Path, Seq[String]) => Option[String]] protected type DeprecatedWatchState = WS protected val deprecatedWatchingMessage = sbt.Keys.watchingMessage diff --git a/main/src/main/scala/sbt/nio/Keys.scala b/main/src/main/scala/sbt/nio/Keys.scala index 9d2702a96..a0c452777 100644 --- a/main/src/main/scala/sbt/nio/Keys.scala +++ b/main/src/main/scala/sbt/nio/Keys.scala @@ -18,7 +18,7 @@ import sbt.internal.nio.FileTreeRepository import sbt.internal.util.AttributeKey import sbt.internal.util.complete.Parser import sbt.nio.file.{ ChangedFiles, FileAttributes, FileTreeView, Glob } -import sbt.{ Def, InputKey, State, StateTransform } +import sbt.{ Def, InputKey, ProjectRef, State, StateTransform } import scala.concurrent.duration.FiniteDuration @@ -68,12 +68,12 @@ object Keys { "detected regardless of whether or not the underlying file has actually changed." // watch related keys + val watchBeforeCommand = settingKey[() => Unit]( + "Function to run prior to running a command in a continuous build." + ).withRank(DSetting) val watchForceTriggerOnAnyChange = Def.settingKey[Boolean](forceTriggerOnAnyChangeMessage).withRank(DSetting) - val watchLogLevel = - settingKey[sbt.util.Level.Value]("Transform the default logger in continuous builds.") - .withRank(DSetting) - val watchInputHandler = settingKey[InputStream => Watch.Action]( + private[sbt] val watchInputHandler = settingKey[InputStream => Watch.Action]( "Function that is periodically invoked to determine if the continuous build should be stopped or if a build should be triggered. It will usually read from stdin to respond to user commands. This is only invoked if watchInputStream is set." ).withRank(DSetting) val watchInputStream = taskKey[InputStream]( @@ -82,16 +82,13 @@ object Keys { val watchInputParser = settingKey[Parser[Watch.Action]]( "A parser of user input that can be used to trigger or exit a continuous build" ).withRank(DSetting) - val watchOnEnter = settingKey[() => Unit]( - "Function to run prior to beginning a continuous build. This will run before the continuous task(s) is(are) first evaluated." - ).withRank(DSetting) - val watchOnExit = settingKey[() => Unit]( - "Function to run upon exit of a continuous build. It can be used to cleanup resources used during the watch." - ).withRank(DSetting) + val watchLogLevel = + settingKey[sbt.util.Level.Value]("Transform the default logger in continuous builds.") + .withRank(DSetting) val watchOnFileInputEvent = settingKey[(Int, Watch.Event) => Watch.Action]( "Callback to invoke if an event is triggered in a continuous build by one of the files matching an fileInput glob for the task and its transitive dependencies" ).withRank(DSetting) - val watchOnIteration = settingKey[Int => Watch.Action]( + val watchOnIteration = settingKey[(Int, ProjectRef, Seq[String]) => Watch.Action]( "Function that is invoked before waiting for file system events or user input events." ).withRank(DSetting) val watchOnTermination = settingKey[(Watch.Action, String, Int, State) => State]( @@ -100,7 +97,7 @@ object Keys { val watchPersistFileStamps = settingKey[Boolean]( "Toggles whether or not the continuous build will reuse the file stamps computed in previous runs. Setting this to true decrease watch startup latency but could cause inconsistent results if many source files are concurrently modified." ).withRank(DSetting) - val watchStartMessage = settingKey[(Int, String, Seq[String]) => Option[String]]( + val watchStartMessage = settingKey[(Int, ProjectRef, Seq[String]) => Option[String]]( "The message to show when triggered execution waits for sources to change. The parameters are the current watch iteration count, the current project name and the tasks that are being run with each build." ).withRank(DSetting) // The watchTasks key should really be named watch, but that is already taken by the deprecated watch key. I'd be surprised if there are any plugins that use it so I think we should consider breaking binary compatibility to rename this task. @@ -108,8 +105,10 @@ object Keys { "watch", "Watch a task (or multiple tasks) and rebuild when its file inputs change or user input is received. The semantics are more or less the same as the `~` command except that it cannot transform the state on exit. This means that it cannot be used to reload the build." ).withRank(DSetting) + val watchTriggers = + settingKey[Seq[Glob]]("Describes files that should trigger a new continuous build.") val watchTriggeredMessage = settingKey[(Int, Path, Seq[String]) => Option[String]]( - "The message to show before triggered execution executes an action after sources change. The parameters are the path that triggered the build and the current watch iteration count." + "The message to show before triggered execution executes an action after sources change. The parameters are the current watch iteration count, the path that triggered the build and the names of the commands to run." ).withRank(DSetting) // internal keys diff --git a/main/src/main/scala/sbt/nio/Watch.scala b/main/src/main/scala/sbt/nio/Watch.scala index 5eb4cf344..82bae33f8 100644 --- a/main/src/main/scala/sbt/nio/Watch.scala +++ b/main/src/main/scala/sbt/nio/Watch.scala @@ -15,10 +15,12 @@ import java.util.concurrent.TimeUnit import sbt.BasicCommandStrings.ContinuousExecutePrefix import sbt._ +import sbt.internal.Continuous import sbt.internal.LabeledFunctions._ import sbt.internal.nio.FileEvent import sbt.internal.util.complete.Parser import sbt.internal.util.complete.Parser._ +import sbt.nio.Keys._ import sbt.nio.file.FileAttributes import sbt.util.{ Level, Logger } @@ -244,7 +246,7 @@ object Watch { * Action that indicates that the watch should pause while the build is reloaded. This is used to * automatically reload the project when the build files (e.g. build.sbt) are changed. */ - private[sbt] case object Reload extends CancelWatch + case object Reload extends CancelWatch /** * Action that indicates that we should exit and run the provided command. @@ -399,26 +401,26 @@ object Watch { ) s"Options:\n${opts.mkString(" ", "\n ", "")}" } - private def waitMessage(project: String, commands: Seq[String]): String = { + private def waitMessage(project: ProjectRef, commands: Seq[String]): String = { val plural = if (commands.size > 1) "s" else "" val cmds = commands.mkString("; ") s"Monitoring source files for updates...\n" + - s"Project: $project\nCommand$plural: $cmds\n$options" + s"Project: ${project.project}\nCommand$plural: $cmds\n$options" } /** * A function that prints out the current iteration count and gives instructions for exiting * or triggering the build. */ - val defaultStartWatch: (Int, String, Seq[String]) => Option[String] = { - (count: Int, project: String, commands: Seq[String]) => + val defaultStartWatch: (Int, ProjectRef, Seq[String]) => Option[String] = { + (count: Int, project: ProjectRef, commands: Seq[String]) => Some(s"$count. ${waitMessage(project, commands)}") }.label("Watched.defaultStartWatch") /** * Default no-op callback. */ - val defaultOnEnter: () => Unit = () => {} + val defaultBeforeCommand: () => Unit = () => {} private[sbt] val defaultCommandOnTermination: (Action, String, Int, State) => State = onTerminationImpl(ContinuousExecutePrefix).label("Watched.defaultCommandOnTermination") @@ -471,9 +473,34 @@ object Watch { final val defaultPollInterval: FiniteDuration = 500.milliseconds /** - * A constant function that returns an Option wrapped string that clears the screen when - * written to stdout. + * Clears the console screen when evaluated. */ - final val clearOnTrigger: Int => Option[String] = - ((_: Int) => Some(Watched.clearScreen)).label("Watched.clearOnTrigger") + final val clearScreen: () => Unit = + (() => println("\u001b[2J\u001b[0;0H")).label("Watch.clearScreen") + + /** + * A function that first clears the screen and then returns the default on trigger message. + */ + final val clearScreenOnTrigger: (Int, Path, Seq[String]) => Option[String] = { + (count: Int, path: Path, commands: Seq[String]) => + clearScreen() + defaultOnTriggerMessage(count, path, commands) + }.label("Watch.clearScreenOnTrigger") + + private[sbt] def defaults: Seq[Def.Setting[_]] = Seq( + sbt.Keys.watchAntiEntropy :== Watch.defaultAntiEntropy, + watchAntiEntropyRetentionPeriod :== Watch.defaultAntiEntropyRetentionPeriod, + watchLogLevel :== Level.Info, + watchBeforeCommand :== Watch.defaultBeforeCommand, + watchOnFileInputEvent :== Watch.trigger, + watchDeletionQuarantinePeriod :== Watch.defaultDeletionQuarantinePeriod, + sbt.Keys.watchService :== Watched.newWatchService, + watchStartMessage :== Watch.defaultStartWatch, + watchTasks := Continuous.continuousTask.evaluated, + sbt.Keys.aggregate in watchTasks :== false, + watchTriggeredMessage :== Watch.defaultOnTriggerMessage, + watchForceTriggerOnAnyChange :== false, + watchPersistFileStamps :== true, + watchTriggers :== Nil, + ) } diff --git a/sbt/src/main/scala/sbt/Import.scala b/sbt/src/main/scala/sbt/Import.scala index b7addad35..5d3d72530 100644 --- a/sbt/src/main/scala/sbt/Import.scala +++ b/sbt/src/main/scala/sbt/Import.scala @@ -71,6 +71,7 @@ trait Import { type RelativeGlob = sbt.nio.file.RelativeGlob val RelativeGlob = sbt.nio.file.RelativeGlob val RecursiveGlob = sbt.nio.file.RecursiveGlob + val Watch = sbt.nio.Watch // sbt.util type AbstractLogger = sbt.util.AbstractLogger diff --git a/sbt/src/sbt-test/watch/alias/build.sbt b/sbt/src/sbt-test/watch/alias/build.sbt index 0fab94fd9..f1d0d6c0a 100644 --- a/sbt/src/sbt-test/watch/alias/build.sbt +++ b/sbt/src/sbt-test/watch/alias/build.sbt @@ -1,6 +1,6 @@ val foo = taskKey[Unit]("foo") foo := println("foo") -foo / watchOnIteration := { _ => sbt.nio.Watch.CancelWatch } +foo / watchOnIteration := { (_, _, _) => sbt.nio.Watch.CancelWatch } addCommandAlias("bar", "foo") addCommandAlias("baz", "foo") diff --git a/sbt/src/sbt-test/watch/file-input-aggregation/project/Build.scala b/sbt/src/sbt-test/watch/file-input-aggregation/project/Build.scala index 6702e49a2..32b999320 100644 --- a/sbt/src/sbt-test/watch/file-input-aggregation/project/Build.scala +++ b/sbt/src/sbt-test/watch/file-input-aggregation/project/Build.scala @@ -4,7 +4,6 @@ package input.aggregation import java.nio.file.Paths import sbt.Keys._ import sbt.internal.DynamicInput -import sbt.nio.{ file => _, _ } import sbt.nio.Keys._ /** @@ -41,7 +40,7 @@ object Build { watchOnFileInputEvent := { (_, _) => Watch.CancelWatch }, - Compile / compile / watchOnIteration := { _ => + Compile / compile / watchOnIteration := { (_, _, _) => Watch.CancelWatch }, checkTriggers := { diff --git a/sbt/src/sbt-test/watch/input-parser/project/Build.scala b/sbt/src/sbt-test/watch/input-parser/project/Build.scala index 399f4acde..eb30bc8d8 100644 --- a/sbt/src/sbt-test/watch/input-parser/project/Build.scala +++ b/sbt/src/sbt-test/watch/input-parser/project/Build.scala @@ -6,7 +6,6 @@ import complete.Parser._ import java.io.{ PipedInputStream, PipedOutputStream } import Keys._ -import sbt.nio.Watch import sbt.nio.Keys._ object Build { @@ -26,12 +25,12 @@ object Build { // Note that the order is byeParser | helloParser. In general, we want the higher priority // action to come first because otherwise we would potentially scan past it. val helloOrByeParser: Parser[Watch.Action] = byeParser | helloParser - val alternativeStartMessage: (Int, String, Seq[String]) => Option[String] = { (_, _, _) => + val alternativeStartMessage: (Int, ProjectRef, Seq[String]) => Option[String] = { (_, _, _) => outputStream.write("xybyexyblahxyhelloxy".getBytes) outputStream.flush() Some("alternative start message") } - val otherAlternativeStartMessage: (Int, String, Seq[String]) => Option[String] = { (_, _, _) => + val otherAlternativeStartMessage: (Int, ProjectRef, Seq[String]) => Option[String] = { (_, _, _) => outputStream.write("xyhellobyexyblahx".getBytes) outputStream.flush() Some("other alternative start message") diff --git a/sbt/src/sbt-test/watch/legacy-sources/build.sbt b/sbt/src/sbt-test/watch/legacy-sources/build.sbt index 643a02868..3ee3097d9 100644 --- a/sbt/src/sbt-test/watch/legacy-sources/build.sbt +++ b/sbt/src/sbt-test/watch/legacy-sources/build.sbt @@ -1,5 +1,4 @@ import sbt.legacy.sources.Build._ -import sbt.nio.Watch Global / watchSources += new sbt.internal.io.Source(baseDirectory.value, "global.txt", NothingFilter, false) diff --git a/sbt/src/sbt-test/watch/managed/build.sbt b/sbt/src/sbt-test/watch/managed/build.sbt index 7384c265e..42d425cfe 100644 --- a/sbt/src/sbt-test/watch/managed/build.sbt +++ b/sbt/src/sbt-test/watch/managed/build.sbt @@ -1,7 +1,5 @@ import java.nio.file.Files -import sbt.nio.Watch - import scala.concurrent.duration._ Compile / sourceGenerators += Def.task { diff --git a/sbt/src/sbt-test/watch/on-change/build.sbt b/sbt/src/sbt-test/watch/on-change/build.sbt index 048ca05aa..260e5d1c2 100644 --- a/sbt/src/sbt-test/watch/on-change/build.sbt +++ b/sbt/src/sbt-test/watch/on-change/build.sbt @@ -1,9 +1,6 @@ import java.nio.file._ import java.nio.file.attribute.FileTime -import sbt.nio.Keys._ -import sbt.nio._ - import scala.concurrent.duration._ watchTriggeredMessage := { (i, path: Path, c) => @@ -13,7 +10,7 @@ watchTriggeredMessage := { (i, path: Path, c) => prev(i, path, c) } -watchOnIteration := { i: Int => +watchOnIteration := { (i: Int, _, _) => val base = baseDirectory.value.toPath val src = base.resolve("src").resolve("main").resolve("scala").resolve("sbt").resolve("test") diff --git a/sbt/src/sbt-test/watch/on-start-watch/changes/extra.sbt b/sbt/src/sbt-test/watch/on-start-watch/changes/extra.sbt index 4c4c95a65..85c2f3c85 100644 --- a/sbt/src/sbt-test/watch/on-start-watch/changes/extra.sbt +++ b/sbt/src/sbt-test/watch/on-start-watch/changes/extra.sbt @@ -1,7 +1,7 @@ val checkReloaded = taskKey[Unit]("Asserts that the build was reloaded") checkReloaded := { () } -watchOnIteration := { _ => sbt.nio.Watch.CancelWatch } +watchOnIteration := { (_, _, _) => sbt.nio.Watch.CancelWatch } Compile / compile := { Count.increment() diff --git a/sbt/src/sbt-test/watch/on-start-watch/test b/sbt/src/sbt-test/watch/on-start-watch/test index 905322c07..f796f7a13 100644 --- a/sbt/src/sbt-test/watch/on-start-watch/test +++ b/sbt/src/sbt-test/watch/on-start-watch/test @@ -3,19 +3,19 @@ # verify that the watch terminates when we reach the specified count > resetCount -> set watchOnIteration := { (count: Int) => if (count == 2) sbt.nio.Watch.CancelWatch else sbt.nio.Watch.Ignore } +> set watchOnIteration := { (count: Int, _, _) => if (count == 2) sbt.nio.Watch.CancelWatch else sbt.nio.Watch.Ignore } > ~compile > checkCount 2 # verify that the watch terminates and returns an error when we reach the specified count > resetCount -> set watchOnIteration := { (count: Int) => if (count == 2) new sbt.nio.Watch.HandleError(new Exception("")) else sbt.nio.Watch.Ignore } +> set watchOnIteration := { (count: Int, _, _) => if (count == 2) new sbt.nio.Watch.HandleError(new Exception("")) else sbt.nio.Watch.Ignore } # Returning Watch.HandleError causes the '~' command to fail -> ~compile > checkCount 2 # verify that a re-build is triggered when we reach the specified count > resetCount -> set watchOnIteration := { (count: Int) => if (count == 2) sbt.nio.Watch.Trigger else if (count == 3) sbt.nio.Watch.CancelWatch else sbt.nio.Watch.Ignore } +> set watchOnIteration := { (count: Int, _, _) => if (count == 2) sbt.nio.Watch.Trigger else if (count == 3) sbt.nio.Watch.CancelWatch else sbt.nio.Watch.Ignore } > ~compile > checkCount 3 diff --git a/sbt/src/sbt-test/watch/overlapping/build.sbt b/sbt/src/sbt-test/watch/overlapping/build.sbt index 73eab1fe7..5b3d01204 100644 --- a/sbt/src/sbt-test/watch/overlapping/build.sbt +++ b/sbt/src/sbt-test/watch/overlapping/build.sbt @@ -1,8 +1,6 @@ import java.nio.file.Files import java.nio.file.attribute.FileTime -import sbt.nio.Watch - import scala.concurrent.duration._ val foo = taskKey[Unit]("foo.txt") diff --git a/sbt/src/sbt-test/watch/task/changes/Build.scala b/sbt/src/sbt-test/watch/task/changes/Build.scala index 5478afedf..28a790802 100644 --- a/sbt/src/sbt-test/watch/task/changes/Build.scala +++ b/sbt/src/sbt-test/watch/task/changes/Build.scala @@ -24,6 +24,6 @@ object Build { IO.touch(baseDirectory.value / "foo.txt", true) Some("watching") }, - watchOnIteration := { _ => Watch.CancelWatch } + watchOnIteration := { (_, _, _) => Watch.CancelWatch } ) }