gitbackup 0.2.6

Backup all your git repositories with a single command
use anyhow::{Context, Result};
use clap::Parser;
use directories::UserDirs;
use serde::{Deserialize, Serialize};
use std::fs;
use std::path::PathBuf;

#[derive(Parser, Debug)]
#[clap(
    name = "gitbackup",
    author = "Adrian Tombu <adrian@otso.fr>",
    version,
    about = "Backup all your git repositories with a single command",
    long_about = None
)]
pub enum Commands {
    /// Initialize the config file
    Init,

    /// Display the config file contents
    Config,

    /// Run the backup
    Run,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct AppConfig {
    pub backup_path: String,
    pub providers: Vec<Provider>,
}

impl AppConfig {
    pub fn get_backup_path(&self) -> Result<PathBuf> {
        let dir = UserDirs::new().context("Unable to retrieve user directory")?;
        let home_dir = dir.home_dir();

        Ok(home_dir.join(&self.backup_path))
    }

    pub fn get_config_file() -> Result<String> {
        let path = Self::get_config_path()?;

        fs::read_to_string(&path).with_context(|| {
            format!(
                "Unable to read config file at {}, please run gitconfig init command to create it",
                path.display()
            )
        })
    }

    pub fn set_config_file(data: &str) -> Result<()> {
        let path = Self::get_config_path()?;

        fs::write(&path, data)
            .with_context(|| format!("Unable to write to config file at {}", path.display()))
    }

    pub fn get_config() -> Result<AppConfig> {
        toml::from_str(&Self::get_config_file().context("Unable to retrieve config file")?)
            .context("Unable to parse config file")
    }

    pub fn get_config_path() -> Result<PathBuf> {
        let dir = UserDirs::new().context("Unable to retrieve user directory")?;
        let home_dir = dir.home_dir();

        Ok(home_dir.join(".gitbackup"))
    }
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "lowercase")]
pub enum EnabledProvider {
    Forgejo,
    Gitea,
    GitHub,
    GitLab,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Provider {
    pub provider: EnabledProvider,
    pub host: String,
    pub exclude: Vec<String>,
    pub username: String,
    pub token: String,
}

pub trait GenericRepository {
    fn full_name(&self) -> String;
    fn default_branch(&self) -> String;
}