Handle multi-command with reload correctly

@olegych reported that sbt would silently swallow the 'compile' command
in the multi-command, 'run;compile;reload'. I tracked this down to the
build source check. When the build has
Global / onChangedBuildSource := ReloadOnSourceChanges, the check build
sources command return a new state with "reload" prefixed. To actually
perform the reload, I returned this modified state with the prefixed
reload command.

There were two problems with this:
1) In the auto-reload case, the current command was not run after the
   reload
2) If the multi-command contained reload, the auto-reload check would
   have a false positive which triggered the bug in (1)

To fix this, I clear out the remaining commands before I run the check
command. That way, we know that if the remaining commands has a reload,
then it is an auto-reload. We then prefix the state with both the reload
and the current command.

I updated the scripted test for auto-reload to handle multi commands
containing reload.
This commit is contained in:
Ethan Atkins 2019-07-13 11:02:47 -07:00
parent 1b0159c547
commit a071ce8224
5 changed files with 44 additions and 10 deletions

View File

@ -214,12 +214,12 @@ object MainLoop {
}
Parser.parse(
checkCommand,
state.put(Aggregation.suppressShow, true).combinedParser
state.copy(remainingCommands = Nil).put(Aggregation.suppressShow, true).combinedParser
) match {
case Right(cmd) =>
cmd() match {
case s if s.remainingCommands.headOption.map(_.commandLine).contains("reload") =>
s.remove(Aggregation.suppressShow)
Exec("reload", None, None) +: exec +: state
case _ => process()
}
case Left(_) => process()

View File

@ -1,4 +1,13 @@
val foo = taskKey[Unit]("working task")
foo := { println("foo") }
val foo = inputKey[Unit]("working task")
foo := {
val filename = Def.spaceDelimited("").parsed.head
IO.touch(baseDirectory.value / filename)
}
val exists = inputKey[Unit]("check that the file was written")
exists := {
val filename = Def.spaceDelimited("").parsed.head
assert((baseDirectory.value / filename).exists)
}
Global / onChangedBuildSource := ReloadOnSourceChanges

View File

@ -1,4 +1,10 @@
val foo = taskKey[Unit]("broken task")
val foo = inputKey[Unit]("broken task")
foo := { throw new IllegalStateException("foo") }
val exists = inputKey[Unit]("check that the file was written")
exists := {
val filename = Def.spaceDelimited("").parsed.head
assert((baseDirectory.value / filename).exists)
}
Global / onChangedBuildSource := ReloadOnSourceChanges

View File

@ -1,4 +1,13 @@
val foo = taskKey[Unit]("working task")
foo := { println("foo") }
val foo = inputKey[Unit]("working task")
foo := {
val filename = Def.spaceDelimited("").parsed.head
IO.touch(baseDirectory.value / filename)
}
val exists = inputKey[Unit]("check that the file was written")
exists := {
val filename = Def.spaceDelimited("").parsed.head
assert((baseDirectory.value / filename).exists)
}
Global / onChangedBuildSource := ReloadOnSourceChanges

View File

@ -1,9 +1,19 @@
> foo
> foo bar
> exists bar
$ copy-file changes/broken.sbt build.sbt
-> foo
-> foo baz
-> exists baz
$ copy-file changes/working.sbt build.sbt
> foo
> foo baz
> exists baz
> foo foo; reload
> exists foo