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}