1use std::{
2 env,
3 process::{Command, ExitStatus, Stdio},
4 sync::mpsc::Sender,
5};
6
7use crate::{exec, Extension};
8use anyhow::Error;
9use fluentci_types::Output;
10
11#[derive(Default)]
12pub struct Mise {}
13
14impl Mise {
15 pub fn trust(&self) -> Result<ExitStatus, Error> {
16 self.setup()?;
17
18 let mut child = Command::new("bash")
19 .arg("-c")
20 .arg("mise trust")
21 .stdin(Stdio::inherit())
22 .stdout(Stdio::inherit())
23 .stderr(Stdio::inherit())
24 .spawn()?;
25 child.wait().map_err(Error::from)
26 }
27}
28
29impl Extension for Mise {
30 fn exec(
31 &mut self,
32 cmd: &str,
33 tx: Sender<String>,
34 out: Output,
35 last_cmd: bool,
36 work_dir: &str,
37 ) -> Result<ExitStatus, Error> {
38 self.setup()?;
39
40 if cmd.is_empty() {
41 return Ok(ExitStatus::default());
42 }
43
44 let mut child = Command::new("bash")
45 .arg("-c")
46 .arg("mise install")
47 .current_dir(work_dir)
48 .stdin(Stdio::inherit())
49 .stdout(Stdio::inherit())
50 .stderr(Stdio::inherit())
51 .spawn()?;
52 child.wait()?;
53
54 let cmd = format!(
55 "eval \"$(~/.local/bin/mise activate bash)\" && mise x -- {}",
56 cmd
57 );
58 exec(&cmd, tx, out, last_cmd, work_dir)
59 }
60
61 fn setup(&self) -> Result<(), Error> {
62 let path = format!(
63 "{}:{}",
64 env::var("PATH")?,
65 format!("{}/.local/bin", env::var("HOME")?)
66 );
67 env::set_var("PATH", &path);
68 let mut child = Command::new("sh")
69 .arg("-c")
70 .arg("type mise > /dev/null || curl https://mise.run | sh")
71 .stdin(Stdio::inherit())
72 .stdout(Stdio::inherit())
73 .stderr(Stdio::inherit())
74 .spawn()?;
75 child.wait()?;
76
77 Ok(())
78 }
79
80 fn format_command(&self, cmd: &str) -> String {
81 format!(
82 "mise install ; eval \"$(~/.local/bin/mise activate bash)\" && mise x -- {}",
83 cmd
84 )
85 }
86}