diff --git a/src/configt.rs b/src/configt.rs index 37ce9182d2c2d2768186fc9358e30a39ee67e130..5d9d75a6af9186bb8302d506bfdd0a7bc90f03bb 100644 --- a/src/configt.rs +++ b/src/configt.rs @@ -2,6 +2,7 @@ use crate::commit; use crate::prune::{new_prune, prune_launcher}; use clap::Args; use colored::Colorize; +use home; use regex::Regex; use serde_derive::{Deserialize, Serialize}; use std::{path::PathBuf, process::exit}; @@ -51,7 +52,7 @@ pub(crate) struct PartialPrune { /// Structure containing the global definition of the borg config file #[derive(Debug, Deserialize, Serialize, Clone)] pub struct Config { - repository: Repository, + repository: Option<Repository>, gblk_prune: Option<GblkConfig>, } @@ -139,16 +140,60 @@ fn get_borgconfig() -> PathBuf { config_path } -fn parse_toml() -> Config { - let config_file = get_borgconfig(); +/// Get the global configuration for gblk +/// # Return +/// - The path where the global location of the gblk configuration should be set +fn get_global_config() -> PathBuf { + let mut global_config = match home::home_dir() { + Some(path) => path, + None => { + eprintln!("{} global config not found!", "error:".red()); + exit(1); + } + }; + global_config.push(".gblkconfig"); + global_config +} + +/// Get the configuration file of interest +/// # Argument +/// - global: A bolean indicating whether to get the global configuration or +/// only the local one +/// # Return +/// The path containing the local of global configuration +fn get_config(global: bool) -> PathBuf { + if global { + get_global_config() + } else { + get_borgconfig() + } +} + +/// Return the parsed config of interest +/// # Arguments +/// - global: A bolean indicating whether to get the global configuration or +/// only the local one +/// # Return +/// The parsed toml file +fn parse_toml(global: bool) -> Config { + let config_file = get_config(global); let rcontent = std::fs::read_to_string(&config_file); let content = match rcontent { - Err(e) => { - eprintln!("Unable to read {} - {}", &config_file.to_str().unwrap(), e); - exit(101); - } + Err(e) => match e.raw_os_error() { + Some(2) => String::from(""), + _ => { + eprintln!("Unable to read {} - {}", &config_file.to_str().unwrap(), e); + exit(101); + } + }, Ok(s) => s, }; + if content.is_empty() { + return Config { + repository: None, + gblk_prune: None, + }; + } let re = Regex::new("id = (?P<first>[0-9a-z]+)\\W").unwrap(); let nc = re.replace(&content, "id = '$first'"); let config_str: Config = toml::from_str(&nc).unwrap(); @@ -156,13 +201,22 @@ fn parse_toml() -> Config { } /// Function that show the current gblk config of the borg folder -pub fn show() -> () { - let config = parse_toml(); +/// # Arguments +/// - global: A bolean indicating if we whant to show the config of the current +/// profile or the global configuration +pub fn show(global: bool) -> () { + let config = parse_toml(global); + let kind = if global { "global" } else { "local" }; let gblk_config: GblkConfig = match config.gblk_prune { Some(data) => data, None => { - println!("{}", "No configuration defined for this project".yellow()); - exit(0) + println!( + "{} {} {}", + "No".yellow(), + kind.green(), + "configuration defined".yellow() + ); + exit(0); } }; let gblk_str = toml::to_string_pretty(&gblk_config).unwrap(); @@ -347,19 +401,23 @@ fn toml_to_string(config: &Config) -> String { /// # Arguments /// - `key` : The key to update /// - `value`: The value of the key to update -pub fn update_config(key: &str, value: &str) -> () { - let mut config = parse_toml(); +/// - `global: A bolean indicating whether to update the global or the local configuration +pub fn update_config(key: &str, value: &str, global: bool) -> () { + let mut config = parse_toml(global); let mut gblk_config: GblkConfig = get_gblkconfig(&config); update_val(&mut gblk_config, key, value); config.gblk_prune = Some(gblk_config); let gblk_str = toml_to_string(&config); - let config_file = get_borgconfig(); + let config_file = get_config(global); + let kind = if global { "global" } else { "local" }; match std::fs::write(&config_file, gblk_str) { Err(_) => { eprintln!( - "{} {} {} {}", + "{} {} {} {} {} {}", "error:".red(), - "Unable to write the config file", + "Unable to write the", + kind.green(), + "config file", config_file.to_str().unwrap(), "!" ); @@ -373,8 +431,10 @@ pub fn update_config(key: &str, value: &str) -> () { /// for a given arguments /// # Arguments /// - `key` : The key to update -pub fn remove_config(key: &str) -> () { - let mut config = parse_toml(); +/// - `global`: A bolean indicating whether to remove a global or a local +/// configuration file +pub fn remove_config(key: &str, global: bool) -> () { + let mut config = parse_toml(global); let mut gblk_config: GblkConfig = get_gblkconfig(&config); remove_val(&mut gblk_config, key); config.gblk_prune = if gblk_config.empty() { @@ -383,13 +443,16 @@ pub fn remove_config(key: &str) -> () { Some(gblk_config) }; let gblk_str = toml_to_string(&config); - let config_file = get_borgconfig(); + let config_file = get_config(global); + let kind = if global { "global" } else { "local" }; match std::fs::write(&config_file, gblk_str) { Err(_) => { eprintln!( - "{} {} {} {}", + "{} {} {} {} {} {}", "error:".red(), - "Unable to write the config file", + "Unable to write the", + kind.green(), + "config file", config_file.to_str().unwrap(), "!" ); @@ -399,16 +462,31 @@ pub fn remove_config(key: &str) -> () { }; } +/// Function that recover the local or global gblk config +/// # Description +/// This function return the parsed local gblk config file if it exists. If +/// this config is not defined, then it will return tje global gblk config file +fn parse_local_or_global_config() -> GblkConfig { + let config = parse_toml(false); + let gblk_config: GblkConfig = get_gblkconfig(&config); + if gblk_config.empty() { + let config = parse_toml(true); + let gblk_config: GblkConfig = get_gblkconfig(&config); + return gblk_config; + } + gblk_config +} + /// Execute a prune based on gblk configuration /// # Arguments -/// - config_prune: contains partial configuration for prune that cannot be +/// - `config_prune`: contains partial configuration for prune that cannot be /// used in the configuration file +/// - `global`: a boolean indicating whether to prune using pub(crate) fn launch_config_prune(config_prune: PartialPrune) { - let config = parse_toml(); - let gblk_config: GblkConfig = get_gblkconfig(&config); + let gblk_config = parse_local_or_global_config(); if gblk_config.empty() { eprintln!( - "{} No configuration defined for pruning!", + "{} No global and local configuration defined for pruning!", "error:".red() ); exit(104); diff --git a/src/main.rs b/src/main.rs index 607a990d5f265ee88dae82e1304e03ab088e015b..936a4e4bf06a079d6bd50f63b26bd6eaea932490 100644 --- a/src/main.rs +++ b/src/main.rs @@ -220,7 +220,7 @@ enum Config { /// prune some commits Add(Add), /// Display the current gblk configuration - Show, + Show(Show), /// Remove the configuration of a given key in prune Rm(Rm), /// Prune using the project configuration @@ -233,12 +233,29 @@ struct Add { key: String, /// The value of the argument to add in the configuration file value: String, + /// Use this flag if you wan to add an argument in the global gblk + /// configuration file + #[clap(short, long, takes_value = false)] + global: bool, } #[derive(Debug, Args)] struct Rm { /// The name of the argument to remove, see optional arguments of the prune subcommands key: String, + /// Use this flag if you wan to remove an argument in the global gblk + /// configuration file + #[clap(short, long, takes_value = false)] + global: bool, +} + + +#[derive(Debug, Args)] +struct Show { + /// Use this flag if you wan to remove an argument in the global gblk + /// configuration file + #[clap(short, long, takes_value = false)] + global: bool, } fn main() { @@ -309,9 +326,9 @@ fn main() { compact::launch_compact(my_compact); } Commands::Config(conf) => match conf { - Config::Add(e) => configt::update_config(&e.key, &e.value), - Config::Show => configt::show(), - Config::Rm(e) => configt::remove_config(&e.key), + Config::Add(e) => configt::update_config(&e.key, &e.value, e.global), + Config::Show(e) => configt::show(e.global), + Config::Rm(e) => configt::remove_config(&e.key, e.global), Config::Prune(pp) => configt::launch_config_prune(pp), }, }