smbcloud_cli/deploy/
config.rs

1use crate::{
2    deploy::setup::setup_project,
3    ui::{fail_message, fail_symbol, succeed_message, succeed_symbol},
4};
5use git2::{Cred, CredentialType, Error};
6use serde::{Deserialize, Serialize};
7use smbcloud_model::{
8    account::User,
9    error_codes::{ErrorCode, ErrorResponse},
10    project::Project,
11};
12use smbcloud_networking::environment::Environment;
13use smbcloud_networking_project::crud_project_read::get_project;
14use spinners::Spinner;
15use std::{fs, path::Path};
16
17pub(crate) async fn check_config(env: Environment) -> Result<Config, ErrorResponse> {
18    let mut spinner: Spinner = Spinner::new(
19        spinners::Spinners::SimpleDotsScrolling,
20        succeed_message("Checking config"),
21    );
22
23    // Check .smb directory
24
25    // Get .smb/config.toml file path in the current directory
26    let config_path = Path::new(".smb/config.toml");
27    if !config_path.exists() {
28        spinner.stop_and_persist(&succeed_symbol(), succeed_message("Setting up deployment"));
29        setup_project(env).await?;
30        spinner = Spinner::new(
31            spinners::Spinners::SimpleDotsScrolling,
32            succeed_message("Checking config"),
33        );
34    }
35
36    // Parse toml file
37    let config_content = fs::read_to_string(config_path).map_err(|_| ErrorResponse::Error {
38        error_code: ErrorCode::MissingConfig,
39        message: ErrorCode::MissingConfig.message(None).to_string(),
40    })?;
41
42    let config: Config = match toml::from_str(&config_content) {
43        Ok(value) => value,
44        Err(e) => {
45            println!("{}", e);
46            spinner.stop_and_persist(&fail_symbol(), fail_message("Config unsync."));
47            handle_config_error()?
48        }
49    };
50    spinner.stop_and_persist(
51        &succeed_symbol(),
52        succeed_message(&format!("Valid config for {}", config.name)),
53    );
54
55    Ok(config)
56}
57
58fn handle_config_error() -> Result<Config, ErrorResponse> {
59    todo!()
60}
61
62pub(crate) async fn check_project(
63    env: Environment,
64    access_token: &str,
65    id: i32,
66) -> Result<(), ErrorResponse> {
67    let mut spinner: Spinner = Spinner::new(
68        spinners::Spinners::Hamburger,
69        succeed_message("Validate project"),
70    );
71    match get_project(env, access_token.to_string(), id.to_string()).await {
72        Ok(_) => {
73            spinner.stop_and_persist(&succeed_symbol(), succeed_message("Valid project"));
74            Ok(())
75        }
76        Err(_) => {
77            spinner.stop_and_persist(&fail_symbol(), succeed_message("Project is unsynched"));
78            Err(ErrorResponse::Error {
79                error_code: ErrorCode::ProjectNotFound,
80                message: ErrorCode::ProjectNotFound.message(None).to_string(),
81            })
82        }
83    }
84}
85
86#[derive(Deserialize, Serialize)]
87pub struct Config {
88    pub name: String,
89    pub description: Option<String>,
90    pub project: Project,
91}
92
93impl Config {
94    pub fn credentials(
95        &self,
96        user: User,
97    ) -> impl FnMut(&str, Option<&str>, CredentialType) -> Result<Cred, Error> + '_ {
98        move |_url, _username_from_url, _allowed_types| {
99            Cred::ssh_key("git", None, Path::new(&self.ssh_key_path(user.id)), None)
100        }
101    }
102
103    fn ssh_key_path(&self, user_id: i32) -> String {
104        // Use the dirs crate to get the home directory
105        let home = dirs::home_dir().expect("Could not determine home directory");
106        let key_path = home.join(".ssh").join(format!("id_{}@smbcloud", user_id));
107        let key_path_str = key_path.to_string_lossy().to_string();
108        println!("Use key path: {}", key_path_str);
109        key_path_str
110    }
111}