waterui_cli/
brew.rs

1//! Brew toolchain manager for `WaterUI` CLI
2
3use color_eyre::eyre;
4
5use crate::{
6    toolchain::{Installation, Toolchain, ToolchainError},
7    utils::{run_command, which},
8};
9
10/// Homebrew toolchain manager
11#[derive(Debug, Default)]
12pub struct Brew {}
13
14impl Brew {
15    /// Install a formula via Homebrew
16    ///
17    /// # Arguments
18    /// * `name` - The name of the formula to install
19    ///
20    /// # Errors
21    ///
22    /// Returns an `eyre::Result` indicating success or failure of the installation.
23    pub async fn install(&self, name: &str) -> eyre::Result<()> {
24        run_command("brew", ["install", name]).await?;
25        Ok(())
26    }
27
28    /// Install a cask via Homebrew
29    ///
30    /// # Arguments
31    /// * `name` - The name of the cask to install
32    /// * `cask` - The cask identifier
33    ///
34    /// # Errors
35    ///
36    /// Returns an `eyre::Result` indicating success or failure of the installation.
37    pub async fn install_with_cask(&self, name: &str, cask: &str) -> eyre::Result<()> {
38        run_command("brew", ["install", "--cask", name, cask]).await?;
39        Ok(())
40    }
41}
42
43impl Toolchain for Brew {
44    type Installation = BrewInstallation;
45    async fn check(&self) -> Result<(), crate::toolchain::ToolchainError<Self::Installation>> {
46        if which("brew").await.is_ok() {
47            Ok(())
48        } else if cfg!(target_os = "macos") {
49            Err(ToolchainError::fixable(BrewInstallation))
50        } else {
51            Err(ToolchainError::unfixable(
52                "Homebrew is only supported on macOS",
53                "Why did you try to use Homebrew on a non-macOS system?",
54            ))
55        }
56    }
57}
58
59/// Installation procedure for Homebrew
60///
61/// This will run the official Homebrew installation script.
62#[derive(Debug)]
63pub struct BrewInstallation;
64
65impl Installation for BrewInstallation {
66    type Error = eyre::Report;
67
68    async fn install(&self) -> Result<(), Self::Error> {
69        run_command(
70            "sh",
71            [
72                "-c",
73                "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)",
74            ],
75        )
76        .await?;
77        Ok(())
78    }
79}