use toml::Value;
use libimagerror::into::IntoError;
use libimagstore::storeid::StoreId;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::result::Result;
use vcs::git::action::StoreAction;
use git2::Repository;
pub fn commit_interactive(config: &Value, action: &StoreAction) -> bool {
match config.lookup("commit.interactive") {
Some(&Value::Boolean(b)) => b,
Some(_) => {
warn!("Configuration error, 'store.hooks.stdhook_git_{}.commit.interactive' must be a Boolean.",
action);
warn!("Defaulting to commit.interactive = false");
false
}
None => {
warn!("Unavailable configuration for");
warn!("\t'store.hooks.stdhook_git_{}.commit.interactive'", action);
warn!("Defaulting to false");
false
}
}
}
fn commit_with_editor(config: &Value, action: &StoreAction) -> bool {
match config.lookup("commit.interactive_editor") {
Some(&Value::Boolean(b)) => b,
Some(_) => {
warn!("Configuration error, 'store.hooks.stdhook_git_{}.commit.interactive_editor' must be a Boolean.",
action);
warn!("Defaulting to commit.interactive_editor = false");
false
}
None => {
warn!("Unavailable configuration for");
warn!("\t'store.hooks.stdhook_git_{}.commit.interactive_editor'", action);
warn!("Defaulting to false");
false
}
}
}
fn commit_default_msg<'a>(config: &'a Value, action: &'a StoreAction) -> &'a str {
match config.lookup("commit.message") {
Some(&Value::String(ref b)) => b,
Some(_) => {
warn!("Configuration error, 'store.hooks.stdhook_git_{}.commit.message' must be a String.",
action);
warn!("Defaulting to commit.message = '{}'", action.as_commit_message());
action.as_commit_message()
}
None => {
warn!("Unavailable configuration for");
warn!("\t'store.hooks.stdhook_git_{}.commit.message'", action);
warn!("Defaulting to commit.message = '{}'", action.as_commit_message());
action.as_commit_message()
}
}
}
fn commit_template(action: &StoreAction, id: &StoreId) -> String {
format!(r#"
# Please commit your changes and remove these lines.
#
# You're about to commit changes via the {action} Hook
#
# Altered file: {id}
#
"#,
action = action,
id = id.local().display())
}
pub fn commit_message(repo: &Repository, config: &Value, action: StoreAction, id: &StoreId) -> Result<String> {
use libimaginteraction::ask::ask_string;
use libimagutil::edit::edit_in_tmpfile_with_command;
use std::process::Command;
if commit_interactive(config, &action) {
if commit_with_editor(config, &action) {
repo.config()
.map_err_into(GHEK::GitConfigFetchError)
.and_then(|c| c.get_string("core.editor").map_err_into(GHEK::GitConfigEditorFetchError))
.map_err_into(GHEK::ConfigError)
.map(Command::new)
.and_then(|cmd| {
let mut s = commit_template(&action, id);
edit_in_tmpfile_with_command(cmd, &mut s).map(|_| s)
.map_err_into(GHEK::EditorError)
})
} else {
Ok(ask_string("Commit Message", None, false, false, None, "> "))
}
} else {
Ok(String::from(commit_default_msg(config, &action)))
}
}
pub fn abort_on_repo_init_err(cfg: &Value) -> bool {
get_bool_cfg(Some(cfg), "abort_on_repo_init_failure", true, true)
}
pub fn ensure_branch(cfg: Option<&Value>) -> Result<Option<String>> {
match cfg {
Some(cfg) => {
match cfg.lookup("ensure_branch") {
Some(&Value::String(ref s)) => Ok(Some(s.clone())),
Some(_) => {
warn!("Configuration error, 'ensure_branch' must be a String.");
Err(GHEK::ConfigTypeError.into_error())
.map_err_into(GHEK::ConfigTypeError)
},
None => {
debug!("No key `ensure_branch'");
Ok(None)
},
}
},
None => Ok(None),
}
}
pub fn do_checkout_ensure_branch(cfg: Option<&Value>) -> bool {
get_bool_cfg(cfg, "try_checkout_ensure_branch", true, true)
}
fn get_bool_cfg(cfg: Option<&Value>, name: &str, on_fail: bool, on_unavail: bool) -> bool {
cfg.map(|cfg| {
match cfg.lookup(name) {
Some(&Value::Boolean(b)) => b,
Some(_) => {
warn!("Configuration error, '{}' must be a Boolean (true|false).", name);
warn!("Assuming '{}' now.", on_fail);
on_fail
},
None => {
warn!("No key '{}' - Assuming '{}'", name, on_unavail);
on_unavail
},
}
})
.unwrap_or_else(|| {
warn!("No configuration to fetch {} from, assuming {}", name, on_unavail);
on_unavail
})
}
pub fn is_enabled(cfg: &Value) -> bool {
get_bool_cfg(Some(cfg), "enabled", true, true)
}
pub fn committing_is_enabled(cfg: &Value) -> Result<bool> {
match cfg.lookup("commit.enabled") {
Some(&Value::Boolean(b)) => Ok(b),
Some(_) => {
warn!("Config setting whether committing is enabled or not has wrong type.");
warn!("Expected Boolean");
Err(GHEK::ConfigTypeError.into_error())
},
None => {
warn!("No config setting whether committing is enabled or not.");
Err(GHEK::NoConfigError.into_error())
},
}
.map_err_into(GHEK::ConfigError)
}
pub fn add_wt_changes_before_committing(cfg: &Value) -> bool {
get_bool_cfg(Some(cfg), "commit.add_wt_changes", true, true)
}