fluentci_ext/
flox.rs

1use std::{
2    env::consts::OS,
3    process::{Command, ExitStatus, Stdio},
4    sync::mpsc::Sender,
5};
6
7use crate::{exec, nix::Nix, Extension};
8use anyhow::Error;
9use fluentci_types::Output;
10
11#[derive(Default)]
12pub struct Flox {}
13
14impl Extension for Flox {
15    fn exec(
16        &mut self,
17        cmd: &str,
18        tx: Sender<String>,
19        out: Output,
20        last_cmd: bool,
21        work_dir: &str,
22    ) -> Result<ExitStatus, Error> {
23        self.setup()?;
24
25        if cmd.is_empty() {
26            return Ok(ExitStatus::default());
27        }
28
29        Command::new("bash")
30            .arg("-c")
31            .arg("[ -d .flox ] || flox init")
32            .current_dir(work_dir)
33            .stdout(Stdio::inherit())
34            .stderr(Stdio::inherit())
35            .spawn()?
36            .wait()?;
37
38        let cmd = format!("flox activate -- {}", cmd);
39        exec(&cmd, tx, out, last_cmd, work_dir)
40    }
41
42    fn setup(&self) -> Result<(), Error> {
43        Nix::default().setup()?;
44
45        let status = Command::new("sh")
46            .arg("-c")
47            .arg("type flox > /dev/null")
48            .spawn()?
49            .wait()?;
50
51        if status.success() {
52            return Ok(());
53        }
54
55        let sudo = Command::new("sh")
56            .arg("-c")
57            .arg("type sudo > /dev/null")
58            .spawn()?
59            .wait()?;
60
61        let sudo = if sudo.success() { "sudo" } else { "" };
62
63        Command::new("sh")
64            .arg("-c")
65            .arg(&format!(
66                "echo \"trusted-users = root $USER\" | {} tee -a /etc/nix/nix.conf",
67                sudo
68            ))
69            .stdin(Stdio::inherit())
70            .stdout(Stdio::inherit())
71            .stderr(Stdio::inherit())
72            .spawn()?
73            .wait()?;
74
75        Command::new("sh")
76            .arg("-c")
77            .arg(&format!("echo 'extra-trusted-substituters = https://cache.floxdev.com' | {} tee -a /etc/nix/nix.conf && echo 'extra-trusted-public-keys = flox-cache-public-1:7F4OyH7ZCnFhcze3fJdfyXYLQw/aV7GEed86nQ7IsOs=' | {} tee -a /etc/nix/nix.conf", sudo, sudo))
78            .stdin(Stdio::inherit())
79            .stdout(Stdio::inherit())
80            .stderr(Stdio::inherit())
81            .spawn()?
82            .wait()?;
83
84        let sudo = if OS == "macos" { "sudo" } else { "" };
85
86        Command::new("sh")
87            .arg("-c")
88            .arg(&format!(
89                "{} nix profile install --impure \
90                --experimental-features 'nix-command flakes' \
91                --accept-flake-config \
92                github:flox/flox",
93                sudo
94            ))
95            .stdin(Stdio::inherit())
96            .stdout(Stdio::inherit())
97            .stderr(Stdio::inherit())
98            .spawn()?
99            .wait()?;
100
101        Ok(())
102    }
103
104    fn format_command(&self, cmd: &str) -> String {
105        format!("[ -d .flox ] || flox init ; flox activate -- {}", cmd)
106    }
107}