Skip to content

Commit

Permalink
Merge pull request #150 from eatkins/linux-watch-fix
Browse files Browse the repository at this point in the history
Fix file watching for unix
  • Loading branch information
dwijnand authored May 14, 2018
2 parents 6e6e2cb + 70b4c74 commit 49e8c80
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
7 changes: 5 additions & 2 deletions io/src/main/scala/sbt/internal/io/EventMonitor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,11 @@ private[sbt] object EventMonitor {
def getFilesForKey(key: WatchKey): collection.Seq[Path] = key match {
case null => Nil
case k =>
val allEvents = k.pollEvents.asScala
.map(e => k.watchable.asInstanceOf[Path].resolve(e.context.asInstanceOf[Path]))
val rawEvents = k.pollEvents
k.reset()
val allEvents = rawEvents.asScala.flatMap { e =>
Option(e.context).map(c => k.watchable.asInstanceOf[Path].resolve(c.asInstanceOf[Path]))
}
logger.debug(s"Received events:\n${allEvents.mkString("\n")}")
val (exist, notExist) = allEvents.partition(Files.exists(_))
val (updatedDirectories, updatedFiles) = exist.partition(Files.isDirectory(_))
Expand Down
2 changes: 1 addition & 1 deletion io/src/main/scala/sbt/io/MacOSXWatchService.scala
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ private class MacOSXWatchKey(val watchable: JPath, queueSize: Int, kinds: WatchE
Collections.unmodifiableList(result)
}

override def reset(): Boolean = { events.clear(); true }
override def reset(): Boolean = true

override def toString = s"MacOSXWatchKey($watchable)"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,30 @@ abstract class SourceModificationWatchSpec(
} finally monitor.close()
}

it should "reset keys" in IO.withTemporaryDirectory { dir =>
val parentDir = dir / "src" / "watchme"
val file = parentDir / "Foo.scala"

writeNewFile(file, "foo")
// Longer timeout because there are many file system operations
val deadline = 5.seconds.fromNow
val monitor = defaultMonitor(getService, parentDir, tc = () => deadline.isOverdue)
try {
val n = 1000
val triggered0 = watchTest(monitor) {
(0 to n).foreach(i => IO.write(parentDir / s"Foo$i.scala", s"foo$i"))
}
assert(triggered0)
assert(IO.read(file) == s"foo")

val triggered1 = watchTest(monitor) {
IO.write(file, "baz")
}
assert(triggered1)
assert(IO.read(file) == "baz")
} finally monitor.close()
}

"WatchService.poll" should "throw a `ClosedWatchServiceException` if used after `close`" in {
val service = getService
service.close()
Expand Down

0 comments on commit 49e8c80

Please sign in to comment.