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: String =
38        fs::read_to_string(config_path).map_err(|_| ErrorResponse::Error {
39            error_code: ErrorCode::MissingConfig,
40            message: ErrorCode::MissingConfig.message(None).to_string(),
41        })?;
42
43    let config: Config = match toml::from_str(&config_content) {
44        Ok(value) => value,
45        Err(e) => {
46            println!("{}", e);
47            spinner.stop_and_persist(&fail_symbol(), fail_message("Config unsync."));
48            handle_config_error()?
49        }
50    };
51    spinner.stop_and_persist(
52        &succeed_symbol(),
53        succeed_message(&format!("Valid config for {}", config.name)),
54    );
55
56    Ok(config)
57}
58
59fn handle_config_error() -> Result<Config, ErrorResponse> {
60    todo!()
61}
62
63pub(crate) async fn check_project(
64    env: Environment,
65    access_token: &str,
66    id: i32,
67) -> Result<(), ErrorResponse> {
68    let mut spinner: Spinner = Spinner::new(
69        spinners::Spinners::Hamburger,
70        succeed_message("Validate project"),
71    );
72    match get_project(env, access_token.to_string(), id.to_string()).await {
73        Ok(_) => {
74            spinner.stop_and_persist(&succeed_symbol(), succeed_message("Valid project"));
75            Ok(())
76        }
77        Err(_) => {
78            spinner.stop_and_persist(&fail_symbol(), succeed_message("Project is unsynched"));
79            Err(ErrorResponse::Error {
80                error_code: ErrorCode::ProjectNotFound,
81                message: ErrorCode::ProjectNotFound.message(None).to_string(),
82            })
83        }
84    }
85}
86
87#[derive(Deserialize, Serialize)]
88pub struct Config {
89    pub name: String,
90    pub description: Option<String>,
91    pub project: Project,
92}
93
94impl Config {
95    pub fn credentials(
96        &self,
97        user: User,
98    ) -> impl FnMut(&str, Option<&str>, CredentialType) -> Result<Cred, Error> + '_ {
99        move |_url, _username_from_url, _allowed_types| {
100            Cred::ssh_key("git", None, Path::new(&self.ssh_key_path(user.id)), None)
101        }
102    }
103
104    fn ssh_key_path(&self, user_id: i32) -> String {
105        // Use the dirs crate to get the home directory
106        let home = dirs::home_dir().expect("Could not determine home directory");
107        let key_path = home.join(".ssh").join(format!("id_{}@smbcloud", user_id));
108        let key_path_str = key_path.to_string_lossy().to_string();
109        println!("Use key path: {}", key_path_str);
110        key_path_str
111    }
112}