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::crud_project_read::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(
57 env: Environment,
58 access_token: &str,
59 id: i32,
60) -> Result<(), ConfigError> {
61 let mut spinner: Spinner = Spinner::new(
62 spinners::Spinners::Hamburger,
63 succeed_message("Validate project"),
64 );
65 match get_project(env, access_token.to_string(), id.to_string()).await {
66 Ok(_) => {
67 spinner.stop_and_persist(&succeed_symbol(), succeed_message("Valid project"));
68 Ok(())
69 }
70 Err(_) => {
71 spinner.stop_and_persist(&fail_symbol(), succeed_message("Project is unsynched"));
72 Err(ConfigError::ProjectNotFound)
73 }
74 }
75}
76
77#[derive(Deserialize, Serialize)]
78pub struct Config {
79 pub name: String,
80 pub description: Option<String>,
81 pub project: Project,
82}
83
84impl Config {
85 pub fn credentials(
86 &self,
87 user: User,
88 ) -> impl FnMut(&str, Option<&str>, CredentialType) -> Result<Cred, Error> + '_ {
89 move |_url, _username_from_url, _allowed_types| {
90 Cred::ssh_key("git", None, Path::new(&self.ssh_key_path(user.id)), None)
91 }
92 }
93
94 fn ssh_key_path(&self, user_id: i32) -> String {
95 let home = dirs::home_dir().expect("Could not determine home directory");
97 let key_path = home.join(".ssh").join(format!("id_{}@smbcloud", user_id));
98 let key_path_str = key_path.to_string_lossy().to_string();
99 println!("Use key path: {}", key_path_str);
100 key_path_str
101 }
102}
103
104#[derive(Error, Debug, PartialEq, Eq)]
105pub enum ConfigError {
106 #[error("Missing token. Make sure you are logged in.")]
107 MissingToken,
108 #[error("Missing config file. Please regenerate with 'smb init'.")]
109 MissingConfig,
110 #[error("Missing id in repository. Please regenerate with 'smb init'.")]
111 MissingId,
112 #[error("Could not find project in your list. Make sure you have access to the project.")]
113 ProjectNotFound,
114 #[error("Cancel operation.")]
115 Cancel,
116 #[error("Input error.")]
117 InputError,
118}