watchexec/crates/lib
2022-06-16 10:48:29 +00:00
..
examples Split into more crates (#307) 2022-06-15 03:25:05 +00:00
src Split into more crates (#307) 2022-06-15 03:25:05 +00:00
tests Split into more crates (#307) 2022-06-15 03:25:05 +00:00
Cargo.toml release: project-origins v1.0.0 (#314) 2022-06-16 09:01:22 +00:00
CHANGELOG.md Import changelog for the library to a file (#316) 2022-06-16 10:48:29 +00:00
README.md Split into more crates (#307) 2022-06-15 03:25:05 +00:00
release.toml Split into more crates (#307) 2022-06-15 03:25:05 +00:00

Crates.io page API Docs Crate license: Apache 2.0 MSRV: 1.58.0 (minor) CI status

Watchexec library

The library which powers Watchexec CLI and other tools.

  • API documentation.
  • Licensed under Apache 2.0.
  • Minimum Supported Rust Version: 1.58.0 (incurs a minor semver bump).
  • Status: maintained.

Quick start

use miette::{IntoDiagnostic, Result};
use watchexec::{
    Watchexec,
    action::{Action, Outcome},
    config::{InitConfig, RuntimeConfig},
    handler::PrintDebug,
};

#[tokio::main]
async fn main() -> Result<()> {
    let mut init = InitConfig::default();
    init.on_error(PrintDebug(std::io::stderr()));

    let mut runtime = RuntimeConfig::default();
    runtime.pathset(["watchexec.conf"]);

    let conf = YourConfigFormat::load_from_file("watchexec.conf").await.into_diagnostic()?;
    conf.apply(&mut runtime);

    let we = Watchexec::new(init, runtime.clone())?;
    let w = we.clone();

    let c = runtime.clone();
    runtime.on_action(move |action: Action| {
        let mut c = c.clone();
        let w = w.clone();
        async move {
            for event in action.events.iter() {
                if event.paths().any(|(p, _)| p.ends_with("/watchexec.conf")) {
                    let conf = YourConfigFormat::load_from_file("watchexec.conf").await?;

                    conf.apply(&mut c);
                    let _ = w.reconfigure(c.clone());
                    // tada! self-reconfiguring watchexec on config file change!

                    break;
                }
            }

            action.outcome(Outcome::if_running(
                Outcome::DoNothing,
                Outcome::both(Outcome::Clear, Outcome::Start),
            ));

            Ok::<(), std::io::Error>(())
        }
    });

    let _ = we.main().await.into_diagnostic()?;
    Ok(())
}

Kitchen sink

The library also exposes a number of components which are available to make your own tool, or to make anything else you may want:

  • Command handling, to build a command with an arbitrary shell, deal with grouped and ungrouped processes the same way, and supervise a process while also listening for & acting on interventions such as sending signals.

  • Event sources: Filesystem, Signals, (more to come).

  • Finding a common prefix of a set of paths.

  • And more!

Filterers are split into their own crates, so they can be evolved independently:

  • The Globset filterer implements the default Watchexec filter, and mimics the pre-1.18 behaviour as much as possible.

  • The Tagged filterer is an experiment in creating a more powerful filtering solution, which can operate on every part of events, not just their paths.

  • The Ignore filterer implements ignore-file semantics, and especially supports trees of ignore files. It is used as a subfilterer in both of the main filterers above.

There are also separate, standalone crates used to build Watchexec which you can tap into:

  • ClearScreen makes clearing the terminal screen in a cross-platform way easy by default, and provides advanced options to fit your usecase.

  • Command Group augments the std and tokio Command with support for process groups, portable between Unix and Windows.

  • Ignore files finds, parses, and interprets ignore files.

  • Project Origins finds the origin (or root) path of a project, and what kind of project it is.