Skip to content
/ watcher Public

Watch the File System for Changes

License

Unknown, MIT licenses found

Licenses found

Unknown
LICENSE
MIT
LICENSE.md
Notifications You must be signed in to change notification settings

r-lib/watcher

Folders and files

NameName
Last commit message
Last commit date

Latest commit

964e253 · Apr 6, 2025

History

50 Commits
Apr 6, 2025
Apr 2, 2025
Apr 2, 2025
Apr 4, 2025
Apr 4, 2025
Jan 31, 2025
Jan 31, 2025
Apr 4, 2025
Jan 31, 2025
Jan 31, 2025
Feb 2, 2025
Apr 4, 2025
Feb 15, 2025
Feb 15, 2025
Feb 15, 2025
Jan 31, 2025
Jan 31, 2025
Jan 31, 2025
Apr 4, 2025
Apr 4, 2025
Apr 5, 2025
Jan 31, 2025

Repository files navigation

watcher

CRAN status R-CMD-check Codecov test coverage

Watch the File System for Changes

R binding for ‘libfswatch’, a file system monitoring library. This uses an optimal event-driven API for each platform:

  • ReadDirectoryChangesW on Windows
  • FSEvents on MacOS
  • inotify on Linux
  • kqueue on BSD
  • File Events Notification on Solaris/Illumos

Watching is done asynchronously in the background, without blocking the session.

  • Watch files, or directories recursively.
  • Log activity, or run an R function every time a change event occurs.

Installation

Install watcher from CRAN with:

install.packages("watcher")

Installation from Source

watcher requires the ‘libfswatch’ library.

  • On Linux / MacOS, an installed version will be used if found in the standard filesystem locations.
  • On Windows, or if not found, the bundled version of ‘libfswatch’ 1.19.0-dev will be compiled from source.
  • Source compilation of the library requires ‘cmake’.

Quick Start

Create a ‘Watcher’ using watcher::watcher().

By default this will watch the current working directory recursively and write events to stdout.

Set the callback argument to run an R function, or rlang-style formula, every time a file changes:

  • Uses the ‘later’ package to execute the callback when R is idle at the top level, or whenever later::run_now() is called, for instance automatically in Shiny’s event loop.
  • Function is called back with a character vector of the paths of all files which have changed.
library(watcher)
dir <- file.path(tempdir(), "watcher-example")
dir.create(dir)

w <- watcher(dir, callback = ~print(.x), latency = 0.5)
w
#> <Watcher>
#>   Public:
#>     get_path: function () 
#>     initialize: function (path, callback, latency) 
#>     is_running: function () 
#>     start: function () 
#>     stop: function () 
#>   Private:
#>     path: /tmp/RtmpR5tJmF/watcher-example
#>     running: FALSE
#>     watch: externalptr
w$start()

file.create(file.path(dir, "newfile"))
#> [1] TRUE
file.create(file.path(dir, "anotherfile"))
#> [1] TRUE
later::run_now(1)
#> [1] "/tmp/RtmpR5tJmF/watcher-example/newfile"
#> [1] "/tmp/RtmpR5tJmF/watcher-example/anotherfile"

newfile <- file(file.path(dir, "newfile"), open = "r+")
cat("hello", file = newfile)
close(newfile)
later::run_now(1)
#> [1] "/tmp/RtmpR5tJmF/watcher-example/newfile"

file.remove(file.path(dir, "newfile"))
#> [1] TRUE
later::run_now(1)
#> [1] "/tmp/RtmpR5tJmF/watcher-example/newfile"

w$stop()
unlink(dir, recursive = TRUE, force = TRUE)

Acknowledgements

Thanks to the authors of ‘libfswatch’, upon which this package is based:

  • Alan Dipert
  • Enrico M. Crisostomo