bigbrother 0.4.0

Git-aware file tracker (list & watch) for async Rust apps
Documentation

Big Borther

bigbrother crate is an async Git-aware file tracker for Rust that watches a working directory and reports files that are currently trackable by ignore rules.

  • High-level API.
  • Git-aware file watching.
  • .gitignore and .ignore support across hierarchy, including parent directories.
  • Global Git ignore support (core.excludesFile).
  • Per-file transitions when ignore rules change.
  • Async API via tokio channel.
  • Optional source-only mode (source-filter feature) that only tracks source files based on tokei language definitions.

It combines:

  • notify for filesystem watching.
  • ignore for fast parallel file discovery.
  • ignore-files for discovering and compiling ignore files (.gitignore, .ignore, global git excludes).
  • Optional tokei support for source-only filtering

Installation

To add bigbrother to your project, install it with cargo add:

cargo add bigbrother

To enable source-only filtering (only_source option), use the source-filter feature:

cargo add bigbrother --features source-filter

How it works

Here's a high-level overview of how Big Brother works:

  • Resolves cwd and (if present) containing git repo root.
  • If cwd is inside a repo, watches the repo root to catch parent ignore changes.
  • Builds ignore state from local + global ignore sources.
  • Performs an initial parallel scan, then emits InitialTracked events.
  • Processes live filesystem events (Created, Changed, Removed, Moved) for tracked files.
  • On ignore-file updates, rescans and diffs tracked state to emit Tracked/Untracked.

Usage

Basic usage:

use bigbrother::{
    FileTracker, TrackEvent, TrackEventError, TrackEventFile, TrackEventFileMove, WatchOptions,
};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let (tracker, mut rx) = FileTracker::start(".").await?;

    while let Some(event) = rx.recv().await {
        match event {
            TrackEvent::InitialTracked(TrackEventFile { path }) => println!("initial: {}", path.display()),
            TrackEvent::Tracked(TrackEventFile { path }) => println!("tracked: {}", path.display()),
            TrackEvent::Untracked(TrackEventFile { path }) => println!("untracked: {}", path.display()),
            TrackEvent::Created(TrackEventFile { path }) => println!("created: {}", path.display()),
            TrackEvent::Changed(TrackEventFile { path }) => println!("changed: {}", path.display()),
            TrackEvent::Removed(TrackEventFile { path }) => println!("removed: {}", path.display()),
            TrackEvent::Moved(TrackEventFileMove { from, to }) => {
                println!("moved: {} -> {}", from.display(), to.display())
            }
            TrackEvent::Error(TrackEventError { message }) => eprintln!("error: {message}"),
        }
    }

    tracker.stop().await?;

    Ok(())
}

If you only care about source files, enable the source-filter feature and set the only_source option:

use bigbrother::{FileTracker, WatchOptions};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let options = WatchOptions {
        only_source: true,
        ..WatchOptions::default()
    };
    let (tracker, mut rx) = FileTracker::start_with_options(".", options).await?;

    // ...

    Ok(())
}

Changelog

See the changelog.

License

MIT © Sasha Koss