flowey_lib_common/
check_needs_relaunch.rsuse flowey::node::prelude::*;
new_simple_flow_node!(struct Node);
#[derive(Serialize, Deserialize)]
pub enum BinOrEnv {
Bin(String),
Env(String, String),
}
flowey_request! {
pub struct Params {
pub check: ReadVar<Option<BinOrEnv>>,
pub done: Vec<WriteVar<SideEffect>>,
}
}
impl SimpleFlowNode for Node {
type Request = Params;
fn imports(_dep: &mut ImportCtx<'_>) {
}
fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
if !matches!(ctx.backend(), FlowBackend::Local) {
anyhow::bail!("only supported on the local backend at this time");
}
let Params { check, done } = request;
if done.is_empty() {
return Ok(());
}
let check_install = {
move |_: &mut RustRuntimeServices<'_>, bin: &String| {
if which::which(bin).is_err() {
anyhow::bail!(format!("did not find {} on $PATH", bin));
}
anyhow::Ok(())
}
};
let check_env = {
move |_: &mut RustRuntimeServices<'_>, env: &String, expected: &String| {
let sh = xshell::Shell::new()?;
let env = sh.var(env)?;
if !env.contains(expected) {
anyhow::bail!(format!("did not find '{}' in {}", expected, env));
}
anyhow::Ok(())
}
};
ctx.emit_rust_step("ensure binaries are available on path", move |ctx| {
done.claim(ctx);
let check = check.claim(ctx);
move |rt| {
let check = rt.read(check);
if check.is_none() {
return Ok(());
}
let check = check.unwrap();
if match check {
BinOrEnv::Bin(bin) => {
check_install(rt, &bin)
}
BinOrEnv::Env(env, expected) => {
check_env(rt, &env, &expected)
}
}.is_err() {
let args = std::env::args().collect::<Vec<_>>().join(" ");
anyhow::bail!("To ensure installed dependencies are available on your $PATH, please restart your shell, and re-run: `{args}`");
}
Ok(())
}
});
Ok(())
}
}