Skip to main content

idt/installers/
rio.rs

1use std::path::Path;
2
3use rootcause::prelude::ResultExt as _;
4use ytil_cmd::silent_cmd;
5
6use crate::installers::Installer;
7
8pub struct Rio<'a> {
9    pub dev_tools_dir: &'a Path,
10    pub bin_dir: &'a Path,
11}
12
13impl Installer for Rio<'_> {
14    fn bin_name(&self) -> &'static str {
15        "rio"
16    }
17
18    /// Builds Rio from source, symlinks the binary into `bin_dir`, and
19    /// copies `Rio.app` into `/Applications` (atomic swap).
20    fn install(&self) -> rootcause::Result<()> {
21        let source_dir = self.dev_tools_dir.join(self.bin_name()).join("source");
22
23        silent_cmd("sh")
24            .args([
25                "-c",
26                &format!(
27                    r#"
28                        ([ ! -d "{0}" ] && \
29                            git clone --depth=1 https://github.com/raphamorim/rio.git {0} || true) && \
30                        cd {0} && \
31                        git fetch origin main --depth=1 && \
32                        git checkout origin/main && \
33                        rustup target add aarch64-apple-darwin && \
34                        make release-macos
35                    "#,
36                    source_dir.display(),
37                ),
38            ])
39            .status()
40            .context("failed to spawn build command")?
41            .exit_ok()
42            .context("build failed")
43            .attach_with(|| format!("tool={}", self.bin_name()))
44            .attach_with(|| format!("source_dir={}", source_dir.display()))?;
45
46        let app = source_dir.join("release").join("Rio.app");
47
48        crate::installers::install_macos_app(&app, self.bin_dir, self.bin_name())?;
49
50        Ok(())
51    }
52
53    fn health_check_args(&self) -> Option<&[&str]> {
54        Some(&["--version"])
55    }
56
57    fn should_verify_checksum(&self) -> bool {
58        false
59    }
60}