Merge pull request #4861 from eatkins/reload-multi-commands

Reload multi commands
This commit is contained in:
eugene yokota 2019-07-13 20:11:23 -04:00 committed by GitHub
commit e2921e70d2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 29 deletions

View File

@ -211,25 +211,23 @@ object BasicCommands {
// then we directly evaluate the `() => State` returned by the parser. Otherwise, we // then we directly evaluate the `() => State` returned by the parser. Otherwise, we
// fall back to prefixing the multi commands to the state. // fall back to prefixing the multi commands to the state.
// //
state.nonMultiCommands.view.flatMap { state.nonMultiCommands.view.flatMap { command =>
case command => command.nameOption match {
command.nameOption match { case Some(commandName) if first.startsWith(commandName) =>
case Some(commandName) if first.startsWith(commandName) => // A lot of commands expect leading semicolons in their parsers. In order to
// A lot of commands expect leading semicolons in their parsers. In order to // ensure that they are multi-command capable, we strip off any leading spaces.
// ensure that they are multi-command capable, we strip off any leading spaces. // Without doing this, we could run simple commands like `set` with the full
// Without doing this, we could run simple commands like `set` with the full // input. This would likely fail because `set` doesn't know how to handle
// input. This would likely fail because `set` doesn't know how to handle // semicolons. This is a bit of a hack that is specifically there
// semicolons. This is a bit of a hack that is specifically there // to handle `~` which doesn't require a space before its argument. Any command
// to handle `~` which doesn't require a space before its argument. Any command // whose parser accepts multi commands without a leading space should be accepted.
// whose parser accepts multi commands without a leading space should be accepted. // All other commands should be rejected. Note that `alias` is also handled by
// All other commands should be rejected. Note that `alias` is also handled by // this case.
// this case. val commandArgs =
val commandArgs = (first.drop(commandName.length).trim :: Nil ::: tail).mkString(";")
(first.drop(commandName.length).trim :: Nil ::: tail).mkString(";") parse(commandArgs, command.parser(state)).toOption
parse(commandArgs, command.parser(state)).toOption case _ => None
case _ => None }
}
case _ => None
}.headOption match { }.headOption match {
case Some(s) => s() case Some(s) => s()
case _ => commands ::: state case _ => commands ::: state

View File

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

View File

@ -1,4 +1,13 @@
val foo = taskKey[Unit]("working task") val foo = inputKey[Unit]("working task")
foo := { println("foo") } 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 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") } 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 Global / onChangedBuildSource := ReloadOnSourceChanges

View File

@ -1,4 +1,13 @@
val foo = taskKey[Unit]("working task") val foo = inputKey[Unit]("working task")
foo := { println("foo") } 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 Global / onChangedBuildSource := ReloadOnSourceChanges

View File

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