64 个版本 (稳定版)
4.1.0 | 2024年4月28日 |
---|---|
3.0.1 | 2023年11月29日 |
2.3.2 | 2023年11月29日 |
2.3.0 | 2023年3月22日 |
1.5.0 | 2016年11月23日 |
#19 in 文件系统
51,016 每月下载量
用于 46 个 Crates(直接使用21个)
275KB
5.5K SLoC
Watchexec 库
为 Watchexec CLI 和其他工具提供动力的库。
- API 文档.
- 在 Apache 2.0 许可下发布。
- 状态:维护中。
示例
以下是一个完整的示例,展示了该库的一些功能
use miette::{IntoDiagnostic, Result};
use std::{
sync::{Arc, Mutex},
time::Duration,
};
use watchexec::{
command::{Command, Program, Shell},
job::CommandState,
Watchexec,
};
use watchexec_events::{Event, Priority};
use watchexec_signals::Signal;
#[tokio::main]
async fn main() -> Result<()> {
// this is okay to start with, but Watchexec logs a LOT of data,
// even at error level. you will quickly want to filter it down.
tracing_subscriber::fmt()
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
.init();
// initialise Watchexec with a simple initial action handler
let job = Arc::new(Mutex::new(None));
let wx = Watchexec::new({
let outerjob = job.clone();
move |mut action| {
let (_, job) = action.create_job(Arc::new(Command {
program: Program::Shell {
shell: Shell::new("bash"),
command: "
echo 'Hello world'
trap 'echo Not quitting yet!' TERM
read
"
.into(),
args: Vec::new(),
},
options: Default::default(),
}));
// store the job outside this closure too
*outerjob.lock().unwrap() = Some(job.clone());
// block SIGINT
#[cfg(unix)]
job.set_spawn_hook(|cmd, _| {
use nix::sys::signal::{sigprocmask, SigSet, SigmaskHow, Signal};
unsafe {
cmd.command_mut().pre_exec(|| {
let mut newset = SigSet::empty();
newset.add(Signal::SIGINT);
sigprocmask(SigmaskHow::SIG_BLOCK, Some(&newset), None)?;
Ok(())
});
}
});
// start the command
job.start();
action
}
})?;
// start the engine
let main = wx.main();
// send an event to start
wx.send_event(Event::default(), Priority::Urgent)
.await
.unwrap();
// ^ this will cause the action handler we've defined above to run,
// creating and starting our little bash program, and storing it in the mutex
// spin until we've got the job
while job.lock().unwrap().is_none() {
tokio::task::yield_now().await;
}
// watch the job and restart it when it exits
let job = job.lock().unwrap().clone().unwrap();
let auto_restart = tokio::spawn(async move {
loop {
job.to_wait().await;
job.run(|context| {
if let CommandState::Finished {
status,
started,
finished,
} = context.current
{
let duration = *finished - *started;
eprintln!("[Program stopped with {status:?}; ran for {duration:?}]")
}
})
.await;
eprintln!("[Restarting...]");
job.start().await;
}
});
// now we change what the action does:
let auto_restart_abort = auto_restart.abort_handle();
wx.config.on_action(move |mut action| {
// if we get Ctrl-C on the Watchexec instance, we quit
if action.signals().any(|sig| sig == Signal::Interrupt) {
eprintln!("[Quitting...]");
auto_restart_abort.abort();
action.quit_gracefully(Signal::ForceStop, Duration::ZERO);
return action;
}
// if the action was triggered by file events, gracefully stop the program
if action.paths().next().is_some() {
// watchexec can manage ("supervise") more than one program;
// here we only have one but we don't know its Id so we grab it out of the iterator
if let Some(job) = action.list_jobs().next().map(|(_, job)| job.clone()) {
eprintln!("[Asking program to stop...]");
job.stop_with_signal(Signal::Terminate, Duration::from_secs(5));
}
}
action
});
// and watch all files in the current directory:
wx.config.pathset(["."]);
// then keep running until Watchexec quits!
let _ = main.await.into_diagnostic()?;
auto_restart.abort();
Ok(())
}
其他示例
- 仅命令:跳过文件监控,仅使用监督器。
- 仅事件:不启动任何进程,仅打印事件。
- 仅在
cargo build
成功时重启cargo run
大杂烩
虽然这不是其主要用例,但该库公开了其大部分相对独立的组件,可用于创建其他非 Watchexec 形状的工具
过滤器已分割到自己的 crates 中,以便可以独立发展
-
Globset 过滤器实现了基于正则表达式 crate 的忽略机制的默认 Watchexec CLI 过滤。
-
Tagged 过滤器是创建更强大过滤解决方案的实验,它可以使用自定义语法在事件的所有部分上操作,而不仅仅是它们的路径。它不再维护。 -
忽略 过滤器 实现了忽略文件语义,尤其支持 树状 忽略文件。它被用作上述两个主要过滤器中的子过滤器。
还有用于构建 Watchexec 的独立、独立的 crate,您可以使用它们。
-
监控器 是 Watchexec 的进程监控器和命令抽象。
-
清屏 默认以跨平台方式轻松清除终端屏幕,并提供高级选项以适应您的使用场景。
-
命令组 在 Unix 和 Windows 之间增强了 std 和 tokio 的
Command
,支持进程组。 -
事件类型 包含 Watchexec 使用的所有事件类型,包括用于向子进程传递事件数据的 JSON 格式。
-
信号类型 包含 Watchexec 使用的所有信号类型。
-
忽略文件 找到、解析和解释忽略文件。
-
项目起源 找到项目的起源(或根)路径以及它是什么类型的项目。
Rust 版本(MSRV)
由于依赖项更改 MSRV 的不可预测性,此库不再尝试在稳定版本背后保持最小支持的 Rust 版本。相反,假定开发者在所有时间都使用最新稳定的版本。
希望支持低于稳定 Rust 的应用程序(例如,Watchexec CLI 所做的那样)应
- 使用锁文件
- 在从源安装时推荐使用
--locked
- 为非分发用户提供预构建的二进制文件(以及 Binstall 支持)
- 避免使用新功能,直到一段时间过去,以便分发用户赶上
- 考虑建议 distro-Rust 用户在可用时切换到 distro
rustup
依赖项
~17–32MB
~482K SLoC