waterui_cli/toolchain/
cmake.rs

1//! Toolchain support for `CMake`.
2
3use std::path::PathBuf;
4
5use color_eyre::eyre;
6
7use crate::{
8    brew::Brew,
9    toolchain::{Installation, Toolchain},
10    utils::which,
11};
12
13/// Toolchain for `CMake`
14#[derive(Debug, Clone, Default)]
15pub struct Cmake {}
16
17impl Cmake {
18    /// Get the path to the `cmake` executable.
19    ///
20    /// # Errors
21    /// - If `CMake` is not found in the system PATH.
22    pub async fn path(&self) -> eyre::Result<PathBuf> {
23        which("cmake").await.map_err(|e| eyre::eyre!(e))
24    }
25}
26
27impl Toolchain for Cmake {
28    type Installation = CmakeInstallation;
29
30    async fn check(&self) -> Result<(), crate::toolchain::ToolchainError<Self::Installation>> {
31        // Check if CMake is installed
32        // TODO: Also detect android-cmake toolchain files if needed
33        if which("cmake").await.is_ok() {
34            Ok(())
35        } else {
36            Err(crate::toolchain::ToolchainError::fixable(CmakeInstallation))
37        }
38    }
39}
40
41/// Installation for `CMake`
42#[derive(Debug, Clone)]
43pub struct CmakeInstallation;
44
45/// Errors that can occur during `CMake` installation
46#[derive(Debug, thiserror::Error)]
47pub enum FailToInstallCmake {
48    /// Homebrew not found error
49    #[error("Homebrew not found. Please install Homebrew to proceed.")]
50    BrewNotFound,
51
52    /// Other installation errors
53    #[error("Failed to install CMake via Homebrew: {0}")]
54    Other(eyre::Report),
55
56    /// Unsupported platform error
57    #[error(
58        "Automatic installation of CMake is not supported on this platform. Please install CMake manually."
59    )]
60    UnsupportedPlatform,
61}
62
63impl Installation for CmakeInstallation {
64    type Error = FailToInstallCmake;
65
66    async fn install(&self) -> Result<(), Self::Error> {
67        if cfg!(target_os = "macos") {
68            let brew = Brew::default();
69
70            brew.check()
71                .await
72                .map_err(|_| FailToInstallCmake::BrewNotFound)?;
73            brew.install("cmake")
74                .await
75                .map_err(FailToInstallCmake::Other)?;
76
77            Ok(())
78        } else {
79            Err(FailToInstallCmake::UnsupportedPlatform)
80        }
81    }
82}