From 18719057a9901be9de560cd3ee78b39bd60d9d4b Mon Sep 17 00:00:00 2001 From: Dan Davison Date: Fri, 8 Jan 2021 10:56:23 -0500 Subject: Reorganize git_config module --- src/git_config/git_config.rs | 194 ----------------------------------------- src/git_config/mod.rs | 202 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 197 insertions(+), 199 deletions(-) delete mode 100644 src/git_config/git_config.rs diff --git a/src/git_config/git_config.rs b/src/git_config/git_config.rs deleted file mode 100644 index d95a6b1a..00000000 --- a/src/git_config/git_config.rs +++ /dev/null @@ -1,194 +0,0 @@ -use regex::Regex; -use std::collections::HashMap; -use std::env; -#[cfg(test)] -use std::path::Path; -use std::process; - -use lazy_static::lazy_static; - -pub struct GitConfig { - config: git2::Config, - config_from_env_var: HashMap, - pub enabled: bool, - pub repo: Option, -} - -impl GitConfig { - pub fn try_create() -> Option { - let repo = match std::env::current_dir() { - Ok(dir) => git2::Repository::discover(dir).ok(), - _ => None, - }; - let config = match &repo { - Some(repo) => repo.config().ok(), - None => git2::Config::open_default().ok(), - }; - match config { - Some(mut config) => { - let config = config.snapshot().unwrap_or_else(|err| { - eprintln!("Failed to read git config: {}", err); - process::exit(1) - }); - Some(Self { - config, - config_from_env_var: parse_config_from_env_var(), - repo, - enabled: true, - }) - } - None => None, - } - } - - #[cfg(test)] - pub fn from_path(path: &Path, honor_env_var: bool) -> Self { - Self { - config: git2::Config::open(path).unwrap(), - config_from_env_var: if honor_env_var { - parse_config_from_env_var() - } else { - HashMap::new() - }, - repo: None, - enabled: true, - } - } - - pub fn get(&self, key: &str) -> Option - where - T: GitConfigGet, - { - if self.enabled { - T::git_config_get(key, self) - } else { - None - } - } -} - -fn parse_config_from_env_var() -> HashMap { - if let Ok(s) = env::var("GIT_CONFIG_PARAMETERS") { - parse_config_from_env_var_value(&s) - } else { - HashMap::new() - } -} - -lazy_static! { - static ref GIT_CONFIG_PARAMETERS_REGEX: Regex = - Regex::new(r"'(delta\.[a-z-]+)=([^']+)'").unwrap(); -} - -fn parse_config_from_env_var_value(s: &str) -> HashMap { - GIT_CONFIG_PARAMETERS_REGEX - .captures_iter(s) - .map(|captures| (captures[1].to_string(), captures[2].to_string())) - .collect() -} - -pub trait GitConfigGet { - fn git_config_get(key: &str, git_config: &GitConfig) -> Option - where - Self: Sized; -} - -impl GitConfigGet for String { - fn git_config_get(key: &str, git_config: &GitConfig) -> Option { - match git_config.config_from_env_var.get(key) { - Some(val) => Some(val.to_string()), - None => git_config.config.get_string(key).ok(), - } - } -} - -impl GitConfigGet for Option { - fn git_config_get(key: &str, git_config: &GitConfig) -> Option { - match git_config.config_from_env_var.get(key) { - Some(val) => Some(Some(val.to_string())), - None => match git_config.config.get_string(key) { - Ok(val) => Some(Some(val)), - _ => None, - }, - } - } -} - -impl GitConfigGet for bool { - fn git_config_get(key: &str, git_config: &GitConfig) -> Option { - match git_config.config_from_env_var.get(key).map(|s| s.as_str()) { - Some("true") => Some(true), - Some("false") => Some(false), - _ => git_config.config.get_bool(key).ok(), - } - } -} - -impl GitConfigGet for usize { - fn git_config_get(key: &str, git_config: &GitConfig) -> Option { - if let Some(s) = git_config.config_from_env_var.get(key) { - if let Ok(n) = s.parse::() { - return Some(n); - } - } - match git_config.config.get_i64(key) { - Ok(value) => Some(value as usize), - _ => None, - } - } -} - -impl GitConfigGet for f64 { - fn git_config_get(key: &str, git_config: &GitConfig) -> Option { - if let Some(s) = git_config.config_from_env_var.get(key) { - if let Ok(n) = s.parse::() { - return Some(n); - } - } - match git_config.config.get_string(key) { - Ok(value) => value.parse::().ok(), - _ => None, - } - } -} - -#[cfg(test)] -mod tests { - - use super::parse_config_from_env_var_value; - - #[test] - fn test_parse_config_from_env_var_value() { - // To generate test cases, use git -c ... with - // [core] - // pager = env | grep GIT_CONFIG_PARAMETERS - - let config = parse_config_from_env_var_value("'user.name=xxx'"); - assert!(config.is_empty()); - - let config = parse_config_from_env_var_value("'delta.plus-style=green'"); - assert_eq!(config["delta.plus-style"], "green"); - - let config = parse_config_from_env_var_value( - r##"'user.name=xxx' 'delta.hunk-header-line-number-style=red "#067a00"'"##, - ); - assert_eq!( - config["delta.hunk-header-line-number-style"], - r##"red "#067a00""## - ); - - let config = - parse_config_from_env_var_value(r##"'user.name=xxx' 'delta.side-by-side=false'"##); - assert_eq!(config["delta.side-by-side"], "false"); - - let config = parse_config_from_env_var_value( - r##"'delta.plus-style=green' 'delta.side-by-side=false' 'delta.hunk-header-line-number-style=red "#067a00"'"##, - ); - assert_eq!(config["delta.plus-style"], "green"); - assert_eq!(config["delta.side-by-side"], "false"); - assert_eq!( - config["delta.hunk-header-line-number-style"], - r##"red "#067a00""## - ); - } -} diff --git a/src/git_config/mod.rs b/src/git_config/mod.rs index 9c7b2212..827446e1 100644 --- a/src/git_config/mod.rs +++ b/src/git_config/mod.rs @@ -1,6 +1,198 @@ -pub mod git_config; -pub mod git_config_entry; +mod git_config_entry; -pub use crate::git_config::git_config::{GitConfig, GitConfigGet}; -pub use crate::git_config::git_config_entry::GitConfigEntry; -pub use crate::git_config::git_config_entry::GitRemoteRepo; +pub use git_config_entry::{GitConfigEntry, GitRemoteRepo}; + +use regex::Regex; +use std::collections::HashMap; +use std::env; +#[cfg(test)] +use std::path::Path; +use std::process; + +use lazy_static::lazy_static; + +pub struct GitConfig { + config: git2::Config, + config_from_env_var: HashMap, + pub enabled: bool, + pub repo: Option, +} + +impl GitConfig { + pub fn try_create() -> Option { + let repo = match std::env::current_dir() { + Ok(dir) => git2::Repository::discover(dir).ok(), + _ => None, + }; + let config = match &repo { + Some(repo) => repo.config().ok(), + None => git2::Config::open_default().ok(), + }; + match config { + Some(mut config) => { + let config = config.snapshot().unwrap_or_else(|err| { + eprintln!("Failed to read git config: {}", err); + process::exit(1) + }); + Some(Self { + config, + config_from_env_var: parse_config_from_env_var(), + repo, + enabled: true, + }) + } + None => None, + } + } + + #[cfg(test)] + pub fn from_path(path: &Path, honor_env_var: bool) -> Self { + Self { + config: git2::Config::open(path).unwrap(), + config_from_env_var: if honor_env_var { + parse_config_from_env_var() + } else { + HashMap::new() + }, + repo: None, + enabled: true, + } + } + + pub fn get(&self, key: &str) -> Option + where + T: GitConfigGet, + { + if self.enabled { + T::git_config_get(key, self) + } else { + None + } + } +} + +fn parse_config_from_env_var() -> HashMap { + if let Ok(s) = env::var("GIT_CONFIG_PARAMETERS") { + parse_config_from_env_var_value(&s) + } else { + HashMap::new() + } +} + +lazy_static! { + static ref GIT_CONFIG_PARAMETERS_REGEX: Regex = + Regex::new(r"'(delta\.[a-z-]+)=([^']+)'").unwrap(); +} + +fn parse_config_from_env_var_value(s: &str) -> HashMap { + GIT_CONFIG_PARAMETERS_REGEX + .captures_iter(s) + .map(|captures| (captures[1].to_string(), captures[2].to_string())) + .collect() +} + +pub trait GitConfigGet { + fn git_config_get(key: &str, git_config: &GitConfig) -> Option + where + Self: Sized; +} + +impl GitConfigGet for String { + fn git_config_get(key: &str, git_config: &GitConfig) -> Option { + match git_config.config_from_env_var.get(key) { + Some(val) => Some(val.to_string()), + None => git_config.config.get_string(key).ok(), + } + } +} + +impl GitConfigGet for Option { + fn git_config_get(key: &str, git_config: &GitConfig) -> Option { + match git_config.config_from_env_var.get(key) { + Some(val) => Some(Some(val.to_string())), + None => match git_config.config.get_string(key) { + Ok(val) => Some(Some(val)), + _ => None, + }, + } + } +} + +impl GitConfigGet for bool { + fn git_config_get(key: &str, git_config: &GitConfig) -> Option { + match git_config.config_from_env_var.get(key).map(|s| s.as_str()) { + Some("true") => Some(true), + Some("false") => Some(false), + _ => git_config.config.get_bool(key).ok(), + } + } +} + +impl GitConfigGet for usize { + fn git_config_get(key: &str, git_config: &GitConfig) -> Option { + if let Some(s) = git_config.config_from_env_var.get(key) { + if let Ok(n) = s.parse::() { + return Some(n); + } + } + match git_config.config.get_i64(key) { + Ok(value) => Some(value as usize), + _ => None, + } + } +} + +impl GitConfigGet for f64 { + fn git_config_get(key: &str, git_config: &GitConfig) -> Option { + if let Some(s) = git_config.config_from_env_var.get(key) { + if let Ok(n) = s.parse::() { + return Some(n); + } + } + match git_config.config.get_string(key) { + Ok(value) => value.parse::().ok(), + _ => None, + } + } +} + +#[cfg(test)] +mod tests { + + use super::parse_config_from_env_var_value; + + #[test] + fn test_parse_config_from_env_var_value() { + // To generate test cases, use git -c ... with + // [core] + // pager = env | grep GIT_CONFIG_PARAMETERS + + let config = parse_config_from_env_var_value("'user.name=xxx'"); + assert!(config.is_empty()); + + let config = parse_config_from_env_var_value("'delta.plus-style=green'"); + assert_eq!(config["delta.plus-style"], "green"); + + let config = parse_config_from_env_var_value( + r##"'user.name=xxx' 'delta.hunk-header-line-number-style=red "#067a00"'"##, + ); + assert_eq!( + config["delta.hunk-header-line-number-style"], + r##"red "#067a00""## + ); + + let config = + parse_config_from_env_var_value(r##"'user.name=xxx' 'delta.side-by-side=false'"##); + assert_eq!(config["delta.side-by-side"], "false"); + + let config = parse_config_from_env_var_value( + r##"'delta.plus-style=green' 'delta.side-by-side=false' 'delta.hunk-header-line-number-style=red "#067a00"'"##, + ); + assert_eq!(config["delta.plus-style"], "green"); + assert_eq!(config["delta.side-by-side"], "false"); + assert_eq!( + config["delta.hunk-header-line-number-style"], + r##"red "#067a00""## + ); + } +} -- cgit v1.2.3