dfmn/
setup.rs

1use crate::error::{CommandError, ExecutionError};
2use crate::git::GitCommandExecuterBuilder;
3use crate::utils;
4use std::fs;
5use std::path::Path;
6use std::process::{Command, Stdio};
7use thiserror::Error;
8
9#[derive(Debug, Error)]
10pub enum Error {
11    #[error("You need to have git installed to use dfmn")]
12    NeedGit,
13}
14
15impl From<Error> for CommandError {
16    fn from(err: Error) -> Self {
17        CommandError::Usage(err.to_string())
18    }
19}
20
21fn check_if_git_is_installed() -> Result<(), CommandError> {
22    let status = match Command::new("git")
23        .stdout(Stdio::null())
24        .stderr(Stdio::null())
25        .status()
26    {
27        Ok(status) => status,
28        Err(err) => {
29            return Err(ExecutionError::GitCommand {
30                command: "git",
31                err: err.to_string(),
32            }
33            .into());
34        }
35    };
36
37    let Some(command_code) = status.code() else {
38        return Err(ExecutionError::Unknown { err: "process terminated by signal".to_string(), trying_to: "get git status code" }.into());
39    };
40
41    if command_code != 1 {
42        return Err(Error::NeedGit.into());
43    }
44
45    Ok(())
46}
47
48pub fn execute_git_commands(git_storage_folder_path: &Path) -> Result<(), ExecutionError> {
49    GitCommandExecuterBuilder::new(git_storage_folder_path)
50        .run_init()
51        .build()
52        .run()?;
53
54    Ok(())
55}
56
57pub fn setup() -> Result<(), CommandError> {
58    check_if_git_is_installed()?;
59
60    let git_storage_folder_path = match utils::get_git_storage_folder_path() {
61        Ok(path) => path,
62        Err(err) => {
63            return Err(ExecutionError::GetStorageFolderPath(err.to_string()).into());
64        }
65    };
66
67    if git_storage_folder_path.is_dir() {
68        return Ok(());
69    }
70
71    if let Err(err) = fs::create_dir_all(&git_storage_folder_path) {
72        return Err(ExecutionError::CreateStorageFolder(err.to_string()).into());
73    }
74
75    let git_storage_folder_path = match git_storage_folder_path.canonicalize() {
76        Ok(path) => path,
77        Err(err) => {
78            return Err(ExecutionError::CanonicalizePath(err.to_string()).into());
79        }
80    };
81
82    GitCommandExecuterBuilder::new(&git_storage_folder_path)
83        .run_init()
84        .build()
85        .run()?;
86
87    Ok(())
88}