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}