mirror of https://github.com/sbt/sbt.git
This commit reworks Watched to be more testable and extensible. It also adds some small features. The previous implementation presented a number of challenges: 1) It relied on external side effects to terminate the watch, which was difficult to test 2) It exposed irrelevant implementation details to the user in the methods that exposed the WatchState as a parameter. 3) It spun up two worker threads. One was to monitor System.in for user input. The other was to poll the watch service for events and write them to a queue. The user input thread actually broke '~console' because nearly every console session will hit the <enter> key, which would eventually cause the watch to stop when the user exited the console. To address (1), I add the shouldTerminate method to WatchConfig. This takes the current watch iteration is input and if the function returns true, the watch will stop. To address (2), I replace the triggeredMessage and watchingMessage keys with watchTriggeredMessage and watchStartMessage. The latter two keys are functions that do not take the WatchState as parameters. Both functions take the current iteration count as a parameter and the watchTriggeredMessage also has a parameter for the path that triggered the build. To address (3), I stop using the sbt.internal.io.EventMonitor and instead use the sbt.io.FileEventMonitor. The latter class is similar to the former except that it's polling method accepts a duration, which may be finite or infinite) and returns all of the events that occurred since it was last polled. By adding the ability to poll for a finite amount of time, we can interleave polling for events with polling System.in for user input, all on the main thread. This eliminates the two extraneous threads and fixes the '~console' use case I described before. I also let the user configure the function that reads from System.in via the watchHandleInput method. In fact, this method need not read from System.in at all since it's just () => Watched.Action. The reason that it isn't () => Boolean is that I'd like to leave open the option for the ability to trigger a build via user input, not just terminating the watch. My initial idea was to add the ability to type 'r' to re-build in addition to <enter> to exit. This doesn't work without integrating jline though because the input is buffered. Regardless, for testing purposes, it gives us the ability to add a timeout to the watch by making handleInput return true when a deadline expires. The tests are a bit wonky because I still need to rely on side effects in the logging methods to orchestrate the sequence of file events that I'd like to test. While I could move some of this logic into a background thread, there still needs to be coordination between the state of the watch and the background thread. I think it's easier to reason about when all of the work occurs on the same thread, even if it makes these user provided functions impure. I deprecated all of the previous watch related keys that are no longer used with the new infrastructure. To avoid breaking existing builds, I make the watchConfig task use the deprecated logging methods if they are defined in the user's builds, but sbt will not longer set the default values. For the vast majority of users, it should be straightforward to migrate their builds to use the new keys. My hunch is that the of the deprecated keys, only triggeredMessage is widely used (in conjunction with the clear screen method) and it is dead simple to replace it with watchTriggeredMessage. Note: The FileTreeViewConfig class is not really necessary for this commit. It will become more important in a subsequent commit which introduces an optional global file system cache. |
||
|---|---|---|
| .github | ||
| core-macros/src/main/scala/sbt/internal/util/appmacro | ||
| internal | ||
| launch | ||
| licenses | ||
| main | ||
| main-actions/src | ||
| main-command/src | ||
| main-settings/src | ||
| notes | ||
| project | ||
| protocol/src/main | ||
| run | ||
| sbt/src | ||
| scripted-plugin/src/main/scala/sbt | ||
| scripted-sbt-old/src/main/scala/sbt/test | ||
| scripted-sbt-redux | ||
| src/main/conscript | ||
| tasks | ||
| tasks-standard | ||
| testing | ||
| vscode-sbt-scala | ||
| .appveyor.yml | ||
| .gitattributes | ||
| .gitignore | ||
| .java-version | ||
| .sbtopts | ||
| .scalafmt.conf | ||
| .travis.yml | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| NOTICE | ||
| PROFILING.md | ||
| README.md | ||
| SUPPORT.md | ||
| build.sbt | ||
| reset.sh | ||
| sbt-allsources.sh | ||
| server.md | ||
README.md
sbt
sbt is a build tool for Scala, Java, and more.
For general documentation, see http://www.scala-sbt.org/.
sbt 1.x
This is the 1.x series of sbt. The source code of sbt is split across several Github repositories, including this one.
- sbt/io hosts
sbt.iomodule. - sbt/util hosts a collection of internally used modules.
- sbt/librarymanagement hosts
sbt.librarymanagementmodule that wraps Ivy. - sbt/zinc hosts Zinc, an incremental compiler for Scala.
- sbt/sbt, this repository hosts modules that implements the build tool.
Other links
- Setup: Describes getting started with the latest binary release.
- FAQ: Explains how to get help and more.
- sbt/sbt-zero-seven: hosts sbt 0.7.7 and earlier versions
Issues and Pull Requests
Please read CONTRIBUTING carefully before opening a GitHub Issue.
The short version: try searching or asking on StackOverflow.
license
See LICENSE.