Skip to content

Commit a70cdf5

Browse files
committed
Update news and add meta files
1 parent eca8238 commit a70cdf5

File tree

4 files changed

+130
-2
lines changed

4 files changed

+130
-2
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@
1111
^cran-comments\.md$
1212
^[\.]?air\.toml$
1313
^\.vscode$
14+
^\.claude$

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
.RData
44
.Ruserdata
55
install
6-
docs
7-
revdep
6+
/docs/
7+
/revdep/
8+
/.claude/
89
.vscode
910
air.toml

CLAUDE.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# CLAUDE.md
2+
3+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4+
5+
## Overview
6+
7+
`watcher` is an R package that provides R bindings for libfswatch, a cross-platform file system monitoring library. It enables asynchronous background monitoring of filesystem changes using optimal event-driven APIs for each platform (ReadDirectoryChangesW on Windows, FSEvents on macOS, inotify on Linux, kqueue on BSD, File Events Notification on Solaris/Illumos).
8+
9+
## Build and Test Commands
10+
11+
### Package Development
12+
```bash
13+
# Build and check the package
14+
R CMD build .
15+
R CMD check watcher_*.tar.gz
16+
17+
# Install from source (triggers configure script)
18+
R CMD INSTALL .
19+
20+
# Run tests
21+
Rscript -e "testthat::test_dir('tests/testthat')"
22+
23+
# Or interactively in R
24+
R -e "devtools::test()"
25+
```
26+
27+
### Single Test Execution
28+
```r
29+
# In R console
30+
testthat::test_file("tests/testthat/test-watch.R")
31+
```
32+
33+
### Documentation
34+
```bash
35+
# Generate documentation with roxygen2
36+
Rscript -e "roxygen2::roxygenize()"
37+
```
38+
39+
### CI/CD
40+
The package uses GitHub Actions workflows in `.github/workflows/`:
41+
- `R-CMD-check.yaml`: Comprehensive R CMD check across multiple OS/R versions
42+
- `test-coverage.yaml`: Code coverage reporting
43+
- `pkgdown.yaml`: Documentation site generation
44+
45+
## Architecture
46+
47+
### Core Components
48+
49+
**R Layer (`R/watch.R`):**
50+
- `watcher()`: Factory function that creates a `Watcher` R6 object
51+
- `Watcher`: R6 class that wraps the C interface with methods:
52+
- `$start()`: Start background monitoring
53+
- `$stop()`: Stop monitoring
54+
- `$is_running()`: Check monitor status
55+
- `$get_path()`: Get watched path(s)
56+
- The R6 class maintains a reference to the C-level FSW_HANDLE via an external pointer
57+
58+
**C Layer (`src/`):**
59+
- `watcher.c`: Core implementation with three main entry points:
60+
- `watcher_create()`: Initialize fswatch session with paths, callback, and latency
61+
- `watcher_start_monitor()`: Spawn detached pthread running `fsw_start_monitor()`
62+
- `watcher_stop_monitor()`: Stop the monitoring thread
63+
- `init.c`: R package initialization that:
64+
- Initializes libfswatch library
65+
- Obtains `execLaterNative2` from the 'later' package for async callbacks
66+
- Registers C callable methods
67+
- `watcher.h`: Header file defining structures and function signatures
68+
69+
**Callback Mechanism:**
70+
- File events trigger `process_events()` callback in C
71+
- Events are bundled by path and passed to R via the 'later' package's `execLaterNative2`
72+
- R callbacks execute when R is idle or when `later::run_now()` is called
73+
- If no callback is provided, events are printed to stdout
74+
75+
### Build System
76+
77+
**Configure Scripts:**
78+
- `configure` (Linux/macOS): Detects system-installed libfswatch in standard locations (`/usr/local`, `/usr`, homebrew paths). If not found, compiles bundled libfswatch (v1.19.0-dev) using cmake. Handles special cases like ARM atomic operations.
79+
- `configure.win` (Windows non-UCRT): Compiles libfswatch from source for both x64 and i386 architectures
80+
- `configure.ucrt` (Windows UCRT): Simplified version for modern Windows R builds
81+
- All scripts generate `src/Makevars` with appropriate compiler flags
82+
83+
**Key Dependencies:**
84+
- libfswatch (bundled as `src/fswatch-5c443d2p.tar.gz`)
85+
- cmake (required for compiling libfswatch from source)
86+
- pthread (for background monitoring thread)
87+
- 'later' R package (for async callback execution)
88+
89+
### Event Filtering
90+
91+
The package filters filesystem events to only report main event types (Created, Updated, Removed, Renamed) to prevent excessive callbacks. Some platforms generate events for file reads, which are intentionally excluded.
92+
93+
### Threading Model
94+
95+
- File monitoring runs in a detached pthread spawned by `watcher_start_monitor()`
96+
- The thread runs `fsw_start_monitor()` which blocks until stopped
97+
- Events from the monitoring thread are safely passed to R via the 'later' package
98+
- External pointer finalizer ensures proper cleanup when Watcher objects are garbage collected
99+
100+
## Platform-Specific Notes
101+
102+
### Windows
103+
- Uses ReadDirectoryChangesW API (always recursive)
104+
- Windows latency has been specifically addressed (see NEWS.md - patch in v0.1.4.9000)
105+
- Builds require cmake and compile libfswatch from bundled source
106+
107+
### macOS
108+
- Uses FSEvents API (always recursive)
109+
- Can use system libfswatch if installed via homebrew/MacPorts
110+
- MACOSX_DEPLOYMENT_TARGET is automatically extracted from compiler flags
111+
112+
### Linux
113+
- Uses inotify API
114+
- Recursive monitoring is explicitly enabled to match Windows/macOS behavior
115+
- May require -latomic on ARM architectures (Raspberry Pi)
116+
117+
### Testing
118+
Tests in `tests/testthat/test-watch.R` cover:
119+
- Basic start/stop lifecycle
120+
- Multiple watched paths
121+
- Callbacks with rlang-style formulas
122+
- Unicode/international filenames (Japanese, French, Chinese characters)
123+
- Error handling (negative latency)
124+
- Some tests skip on aarch64 unless NOT_CRAN=true

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# watcher (development version)
22

3+
* Fixed issue on Windows where watching with a `latency` < 1 caused high CPU usage (#32, thanks @RichardHooijmaijers).
4+
35
# watcher 0.1.4
46

57
* Watcher can now use a system 'libfswatch' installed in a non-standard location (#28).

0 commit comments

Comments
 (0)