mirror of https://github.com/sbt/sbt.git
Fix watch command parser
I discovered that when I ran multi-commands with '~' that if there was a space between the ';' and the command, then the parsing of the command would fail and the watch would abort. To fix this, I refactor Watched.watch to use the multi command parser and, if that parser fails, we fallback on a single command.
This commit is contained in:
parent
4281972f1a
commit
05e3a8609b
|
|
@ -21,7 +21,7 @@ import sbt.internal.LegacyWatched
|
|||
import sbt.internal.inc.Stamper
|
||||
import sbt.internal.io.{ EventMonitor, Source, WatchState }
|
||||
import sbt.internal.util.Types.const
|
||||
import sbt.internal.util.complete.DefaultParsers
|
||||
import sbt.internal.util.complete.{ DefaultParsers, Parser }
|
||||
import sbt.internal.util.{ AttributeKey, JLine }
|
||||
import sbt.io.FileEventMonitor.{ Creation, Deletion, Event, Update }
|
||||
import sbt.io._
|
||||
|
|
@ -279,9 +279,9 @@ object Watched {
|
|||
onFailure = Some(Exec(failureCommandName, None)),
|
||||
definedCommands = s0.definedCommands :+ onFail
|
||||
)
|
||||
val commands = command.split(";") match {
|
||||
case Array("", rest @ _*) => rest
|
||||
case Array(cmd) => Seq(cmd)
|
||||
val commands = Parser.parse(command, BasicCommands.multiParserImpl(Some(s))) match {
|
||||
case Left(_) => command :: Nil
|
||||
case Right(c) => c
|
||||
}
|
||||
val parser = Command.combine(s.definedCommands)(s)
|
||||
val tasks = commands.foldLeft(Nil: Seq[Either[String, () => Either[Exception, Boolean]]]) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
import Build._
|
||||
|
||||
organization := "sbt"
|
||||
|
||||
name := "scripted-watch-parser"
|
||||
|
||||
setStringValue := setStringValueImpl.evaluated
|
||||
|
||||
checkStringValue := checkStringValueImpl.evaluated
|
||||
|
||||
watchSources += file("string.txt")
|
||||
|
||||
watchOnEvent := { _ => Watched.CancelWatch }
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import sbt._
|
||||
|
||||
object Build {
|
||||
private[this] var string: String = ""
|
||||
private[this] val stringFile = file("string.txt")
|
||||
val setStringValue = inputKey[Unit]("set a global string to a value")
|
||||
val checkStringValue = inputKey[Unit]("check the value of a global")
|
||||
def setStringValueImpl: Def.Initialize[InputTask[Unit]] = Def.inputTask {
|
||||
string = Def.spaceDelimited().parsed.mkString(" ").trim
|
||||
IO.write(stringFile, string)
|
||||
}
|
||||
def checkStringValueImpl: Def.Initialize[InputTask[Unit]] = Def.inputTask {
|
||||
assert(string == Def.spaceDelimited().parsed.mkString(" ").trim)
|
||||
assert(IO.read(stringFile) == string)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
> ~; setStringValue foo; setStringValue bar
|
||||
|
||||
> checkStringValue bar
|
||||
|
||||
> ~;setStringValue foo;setStringValue bar; checkStringValue bar
|
||||
|
||||
> ~; setStringValue foo;setStringValue bar; checkStringValue bar
|
||||
|
||||
> ~; setStringValue foo; setStringValue bar; checkStringValue bar
|
||||
|
||||
> ~ setStringValue foo
|
||||
|
||||
> checkStringValue foo
|
||||
|
||||
# All of the other tests have involved input tasks, so include commands with regular tasks as well.
|
||||
> ~; compile; setStringValue baz; checkStringValue baz
|
||||
# No trailing semicolons are allowed
|
||||
-> ~; compile; setStringValue baz; checkStringValue baz;
|
||||
Loading…
Reference in New Issue