flowey_lib_common/
check_needs_relaunch.rs1use flowey::node::prelude::*;
7
8new_simple_flow_node!(struct Node);
9
10#[derive(Serialize, Deserialize)]
11pub enum BinOrEnv {
12 Bin(String),
13 Env(String, String),
14}
15
16flowey_request! {
17 pub struct Params {
18 pub check: ReadVar<Option<BinOrEnv>>,
20 pub done: Vec<WriteVar<SideEffect>>,
21 }
22}
23
24impl SimpleFlowNode for Node {
25 type Request = Params;
26
27 fn imports(_dep: &mut ImportCtx<'_>) {
28 }
30
31 fn process_request(request: Self::Request, ctx: &mut NodeCtx<'_>) -> anyhow::Result<()> {
32 if !matches!(ctx.backend(), FlowBackend::Local) {
33 anyhow::bail!("only supported on the local backend at this time");
34 }
35
36 let Params { check, done } = request;
37
38 if done.is_empty() {
41 return Ok(());
42 }
43
44 let check_install = {
45 move |_: &mut RustRuntimeServices<'_>, bin: &String| {
46 if which::which(bin).is_err() {
47 anyhow::bail!(format!("did not find {} on $PATH", bin));
48 }
49
50 anyhow::Ok(())
51 }
52 };
53
54 let check_env = {
55 move |rt: &mut RustRuntimeServices<'_>, env: &String, expected: &String| {
56 let env = rt.sh.var(env)?;
57
58 if !env.contains(expected) {
59 anyhow::bail!(format!("did not find '{}' in {}", expected, env));
60 }
61
62 anyhow::Ok(())
63 }
64 };
65
66 ctx.emit_rust_step("ensure binaries are available on path", move |ctx| {
67 done.claim(ctx);
68 let check = check.claim(ctx);
69
70 move |rt| {
71 let check = rt.read(check);
72 if check.is_none() {
73 return Ok(());
74 }
75
76 let check = check.unwrap();
77 if match check {
78 BinOrEnv::Bin(bin) => {
79 check_install(rt, &bin)
80 }
81 BinOrEnv::Env(env, expected) => {
82 check_env(rt, &env, &expected)
83 }
84 }.is_err() {
85 let args = std::env::args().collect::<Vec<_>>().join(" ");
86 anyhow::bail!("To ensure installed dependencies are available on your $PATH, please restart your shell, and re-run: `{args}`");
87 }
88 Ok(())
89 }
90 });
91
92 Ok(())
93 }
94}