mirror of
https://github.com/watchexec/watchexec.git
synced 2024-11-16 09:08:37 +01:00
Add log, stdout, stderr
This commit is contained in:
parent
497d2db588
commit
b641773473
3 changed files with 129 additions and 25 deletions
|
@ -20,6 +20,7 @@ use watchexec_filterer_globset::GlobsetFilterer;
|
||||||
use crate::args::{Args, FsEvent};
|
use crate::args::{Args, FsEvent};
|
||||||
|
|
||||||
mod dirs;
|
mod dirs;
|
||||||
|
mod proglib;
|
||||||
mod progs;
|
mod progs;
|
||||||
|
|
||||||
/// A custom filterer that combines the library's Globset filterer and a switch for --no-meta
|
/// A custom filterer that combines the library's Globset filterer and a switch for --no-meta
|
||||||
|
|
124
crates/cli/src/filterer/proglib.rs
Normal file
124
crates/cli/src/filterer/proglib.rs
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
use std::iter::once;
|
||||||
|
|
||||||
|
use jaq_core::{CustomFilter, Definitions, Error, Val};
|
||||||
|
use miette::miette;
|
||||||
|
use tracing::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
pub fn load_std_defs() -> miette::Result<Definitions> {
|
||||||
|
debug!("loading jaq core library");
|
||||||
|
let mut defs = Definitions::core();
|
||||||
|
|
||||||
|
debug!("loading jaq standard library");
|
||||||
|
let mut errs = Vec::new();
|
||||||
|
jaq_std::std()
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|def| defs.insert(def, &mut errs));
|
||||||
|
|
||||||
|
if !errs.is_empty() {
|
||||||
|
return Err(miette!("failed to load jaq standard library: {:?}", errs));
|
||||||
|
}
|
||||||
|
Ok(defs)
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! return_err {
|
||||||
|
($err:expr) => {
|
||||||
|
return Box::new(once($err))
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn custom_err<T>(err: impl Into<String>) -> Result<T, Error> {
|
||||||
|
Err(Error::Custom(err.into()))
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! string_arg {
|
||||||
|
($args:expr, $n:expr, $ctx:expr, $val:expr) => {
|
||||||
|
match $args[$n].run(($ctx.clone(), $val.clone())).next() {
|
||||||
|
Some(Ok(Val::Str(v))) => Ok(v.to_string()),
|
||||||
|
Some(Ok(val)) => custom_err(format!("expected string but got {val:?}")),
|
||||||
|
Some(Err(e)) => Err(e),
|
||||||
|
None => custom_err("value expected but none found"),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! log_action {
|
||||||
|
($level:expr, $val:expr) => {
|
||||||
|
match $level.to_ascii_lowercase().as_str() {
|
||||||
|
"trace" => trace!("jaq: {}", $val),
|
||||||
|
"debug" => debug!("jaq: {}", $val),
|
||||||
|
"info" => info!("jaq: {}", $val),
|
||||||
|
"warn" => warn!("jaq: {}", $val),
|
||||||
|
"error" => error!("jaq: {}", $val),
|
||||||
|
_ => return_err!(custom_err("invalid log level")),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_watchexec_defs(defs: &mut Definitions) -> miette::Result<()> {
|
||||||
|
debug!("loading jaq watchexec library");
|
||||||
|
|
||||||
|
trace!("jaq: add log filter");
|
||||||
|
defs.insert_custom(
|
||||||
|
"log",
|
||||||
|
CustomFilter::with_update(
|
||||||
|
1,
|
||||||
|
|args, (ctx, val)| {
|
||||||
|
let level = match string_arg!(args, 0, ctx, val) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => return_err!(Err(e)),
|
||||||
|
};
|
||||||
|
|
||||||
|
log_action!(level, val);
|
||||||
|
|
||||||
|
// passthrough
|
||||||
|
Box::new(once(Ok(val)))
|
||||||
|
},
|
||||||
|
|args, (ctx, val), _| {
|
||||||
|
let level = match string_arg!(args, 0, ctx, val) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => return_err!(Err(e)),
|
||||||
|
};
|
||||||
|
|
||||||
|
log_action!(level, val);
|
||||||
|
|
||||||
|
// passthrough
|
||||||
|
Box::new(once(Ok(val)))
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
trace!("jaq: add stdout filter");
|
||||||
|
defs.insert_custom(
|
||||||
|
"stdout",
|
||||||
|
CustomFilter::with_update(
|
||||||
|
0,
|
||||||
|
|_, (_, val)| {
|
||||||
|
println!("{}", val);
|
||||||
|
Box::new(once(Ok(val)))
|
||||||
|
},
|
||||||
|
|_, (_, val), _| {
|
||||||
|
println!("{}", val);
|
||||||
|
Box::new(once(Ok(val)))
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
trace!("jaq: add stderr filter");
|
||||||
|
defs.insert_custom(
|
||||||
|
"stderr",
|
||||||
|
CustomFilter::with_update(
|
||||||
|
0,
|
||||||
|
|_, (_, val)| {
|
||||||
|
eprintln!("{}", val);
|
||||||
|
Box::new(once(Ok(val)))
|
||||||
|
},
|
||||||
|
|_, (_, val), _| {
|
||||||
|
eprintln!("{}", val);
|
||||||
|
Box::new(once(Ok(val)))
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
use std::{iter, marker::PhantomData};
|
use std::{iter::once, marker::PhantomData};
|
||||||
|
|
||||||
use jaq_core::{
|
use jaq_core::{
|
||||||
parse::{self, filter::Filter, Def},
|
parse::{self, filter::Filter, Def},
|
||||||
|
@ -72,8 +72,8 @@ impl FilterProgs {
|
||||||
let (requester, mut receiver) = Requester::<Event, bool>::new(BUFFER);
|
let (requester, mut receiver) = Requester::<Event, bool>::new(BUFFER);
|
||||||
let task =
|
let task =
|
||||||
spawn_blocking(move || {
|
spawn_blocking(move || {
|
||||||
let mut defs = load_std_defs()?;
|
let mut defs = super::proglib::load_std_defs()?;
|
||||||
load_watchexec_defs(&mut defs)?;
|
super::proglib::load_watchexec_defs(&mut defs)?;
|
||||||
load_user_progs(&mut defs, &progs)?;
|
load_user_progs(&mut defs, &progs)?;
|
||||||
|
|
||||||
'chan: while let Some((event, sender)) = receiver.blocking_recv() {
|
'chan: while let Some((event, sender)) = receiver.blocking_recv() {
|
||||||
|
@ -97,7 +97,7 @@ impl FilterProgs {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let inputs = RcIter::new(iter::once(Ok(val.clone())));
|
let inputs = RcIter::new(once(Ok(val.clone())));
|
||||||
let ctx = Ctx::new(Vec::new(), &inputs);
|
let ctx = Ctx::new(Vec::new(), &inputs);
|
||||||
let mut results = filter.run(ctx, val.clone());
|
let mut results = filter.run(ctx, val.clone());
|
||||||
if let Some(res) = results.next() {
|
if let Some(res) = results.next() {
|
||||||
|
@ -154,27 +154,6 @@ impl FilterProgs {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_std_defs() -> miette::Result<Definitions> {
|
|
||||||
debug!("loading jaq core library");
|
|
||||||
let mut defs = Definitions::core();
|
|
||||||
|
|
||||||
debug!("loading jaq standard library");
|
|
||||||
let mut errs = Vec::new();
|
|
||||||
jaq_std::std()
|
|
||||||
.into_iter()
|
|
||||||
.for_each(|def| defs.insert(def, &mut errs));
|
|
||||||
|
|
||||||
if !errs.is_empty() {
|
|
||||||
return Err(miette!("failed to load jaq standard library: {:?}", errs));
|
|
||||||
}
|
|
||||||
Ok(defs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_watchexec_defs(defs: &mut Definitions) -> miette::Result<()> {
|
|
||||||
debug!("loading jaq watchexec library");
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn load_user_progs(all_defs: &mut Definitions, progs: &[String]) -> miette::Result<()> {
|
fn load_user_progs(all_defs: &mut Definitions, progs: &[String]) -> miette::Result<()> {
|
||||||
debug!("loading jaq programs");
|
debug!("loading jaq programs");
|
||||||
for (n, prog) in progs.iter().enumerate() {
|
for (n, prog) in progs.iter().enumerate() {
|
||||||
|
|
Loading…
Reference in a new issue