smbcloud_cli/deploy/
config.rs1use 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::{account::User, project::Project};
8use smbcloud_networking::environment::Environment;
9use smbcloud_networking_project::get_project;
10use spinners::Spinner;
11use std::{fs, path::Path};
12use thiserror::Error;
13
14pub(crate) async fn check_config(env: Environment) -> Result<Config, ConfigError> {
15 let mut spinner: Spinner = Spinner::new(
16 spinners::Spinners::SimpleDotsScrolling,
17 succeed_message("Checking config"),
18 );
19
20 let config_path = Path::new(".smb/config.toml");
24 if !config_path.exists() {
25 spinner.stop_and_persist(&succeed_symbol(), succeed_message("Setting up deployment"));
26 setup_project(env).await?;
27 spinner = Spinner::new(
28 spinners::Spinners::SimpleDotsScrolling,
29 succeed_message("Checking config"),
30 );
31 }
32
33 let config_content = fs::read_to_string(config_path).map_err(|_| ConfigError::MissingConfig)?;
35
36 let config: Config = match toml::from_str(&config_content) {
37 Ok(value) => value,
38 Err(e) => {
39 println!("{}", e);
40 spinner.stop_and_persist(&fail_symbol(), fail_message("Config unsync."));
41 handle_config_error()?
42 }
43 };
44 spinner.stop_and_persist(
45 &succeed_symbol(),
46 succeed_message(&format!("Valid config for {}", config.name)),
47 );
48
49 Ok(config)
50}
51
52fn handle_config_error() -> Result<Config, ConfigError> {
53 todo!()
54}
55
56pub(crate) async fn check_project(env: Environment, id: i32) -> Result<(), ConfigError> {
57 let mut spinner: Spinner = Spinner::new(
58 spinners::Spinners::Hamburger,
59 succeed_message("Validate project"),
60 );
61 match get_project(env, id.to_string()).await {
62 Ok(_) => {
63 spinner.stop_and_persist(&succeed_symbol(), succeed_message("Valid project"));
64 Ok(())
65 }
66 Err(_) => {
67 spinner.stop_and_persist(&fail_symbol(), succeed_message("Project is unsynched"));
68 Err(ConfigError::ProjectNotFound)
69 }
70 }
71}
72
73#[derive(Deserialize, Serialize)]
74pub struct Config {
75 pub name: String,
76 pub description: Option<String>,
77 pub project: Project,
78}
79
80impl Config {
81 pub fn credentials(
82 &self,
83 user: User,
84 ) -> impl FnMut(&str, Option<&str>, CredentialType) -> Result<Cred, Error> + '_ {
85 move |_url, _username_from_url, _allowed_types| {
86 Cred::ssh_key("git", None, Path::new(&self.ssh_key_path(user.id)), None)
87 }
88 }
89
90 fn ssh_key_path(&self, user_id: i32) -> String {
91 let home = dirs::home_dir().expect("Could not determine home directory");
93 let key_path = home
94 .join(".ssh")
95 .join(format!("id_{}@smbcloud", user_id));
96 let key_path_str = key_path.to_string_lossy().to_string();
97 println!("Use key path: {}", key_path_str);
98 key_path_str
99 }
100}
101
102#[derive(Error, Debug, PartialEq, Eq)]
103pub enum ConfigError {
104 #[error("Missing config file. Please regenerate with 'smb init'.")]
105 MissingConfig,
106 #[error("Missing id in repository. Please regenerate with 'smb init'.")]
107 MissingId,
108 #[error("Could not find project in your list. Make sure you have access to the project.")]
109 ProjectNotFound,
110 #[error("Cancel operation.")]
111 Cancel,
112 #[error("Input error.")]
113 InputError,
114}