| Crates.io | include-exclude-watcher |
| lib.rs | include-exclude-watcher |
| version | 0.2.0 |
| created_at | 2025-11-26 11:53:31.243512+00 |
| updated_at | 2026-01-04 19:19:15.171961+00 |
| description | Async file watcher with glob-based include/exclude patterns and built-in debouncing |
| homepage | |
| repository | https://github.com/vanviegen/include-exclude-watcher.rs |
| max_upload_size | |
| id | 1951312 |
| size | 83,876 |
Async file watcher with glob-based include/exclude patterns. Linux only (inotify).
Most file watchers (like notify) give you all events and let you filter afterwards. This works fine for small directories, but wastes resources on large trees when you only care about specific patterns.
This crate:
Tradeoffs:
[dependencies]
include-exclude-watcher = "0.1"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
use include_exclude_watcher::{WatchBuilder, WatchEvent};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
WatchBuilder::new()
.add_include("**/*.rs")
.add_exclude("**/target/**")
.run(|event, path| {
println!("{:?}: {}", event, path.display());
})
.await
}
This uses the current working directory as its base directory.
use include_exclude_watcher::WatchBuilder;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
WatchBuilder::new()
.set_base_dir("./src")
.add_include("**/*.rs")
.run_debounced(500, || {
println!("Files changed, rebuilding...");
})
.await
}
use include_exclude_watcher::WatchBuilder;
#[tokio::main]
async fn main() -> anyhow::Result<()> {
WatchBuilder::new()
.set_base_dir("/project")
.add_include("**/*")
.add_ignore_file(".gitignore")
.add_ignore_file(".watchignore")
.run(|event, path| {
println!("{:?}: {}", event, path.display());
})
.await
}
Pattern files use gitignore syntax:
# are comments! negation patterns are not supported (excludes always take precedence over includes)* matches any characters except /** matches any characters including /? matches any single character except /[abc] matches any character in the set/ match anywhere (like gitignore)Examples:
*.rs → matches foo.rs and src/bar.rssrc/*.rs → matches src/main.rs but not src/sub/lib.rs**/test_*.rs → matches test files anywheretarget/** → excludes everything under targetcargo install include-exclude-watcher --features cli
iow ./src -i "**/*.rs" -e "**/target/**"
Options:
-i, --include <PATTERN> — Include pattern (can be repeated)-e, --exclude <PATTERN> — Exclude pattern (can be repeated)-p, --pattern-file <FILE> — Load patterns from file-r, --run <COMMAND> — Run shell command on each event (sets $IOW_FILE and $IOW_EVENT)-c, --combine <MS> — Debounce and output "CHANGES" after quiet period-x, --exit — Exit after first change-f, --format <FORMAT> — Output format: default, path, silent-q, --quiet — Suppress status messagesLinux only for now. Uses inotify directly. PRs for other platforms welcome.
| Feature | include-exclude-watcher | notify | watchexec |
|---|---|---|---|
| Pattern-aware watching | ✓ | ✗ | ✗ |
| Built-in debouncing | ✓ | separate crate | ✓ |
| Cross-platform | ✗ | ✓ | ✓ |
| Async | ✓ | ✓ | ✓ |
| Gitignore file support | ✓ | ✗ | ✓ |
MIT