Merge pull request #736 from matthiasbeyer/libimagstorestdhook/git-docu
libimagstorestdhook/git docu
This commit is contained in:
commit
db218cb3ee
4 changed files with 55 additions and 0 deletions
|
@ -1,5 +1,6 @@
|
||||||
use std::fmt::{Display, Formatter, Error};
|
use std::fmt::{Display, Formatter, Error};
|
||||||
|
|
||||||
|
/// Utility type to specify which kind of store action is running
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum StoreAction {
|
pub enum StoreAction {
|
||||||
Create,
|
Create,
|
||||||
|
|
|
@ -10,6 +10,7 @@ use vcs::git::action::StoreAction;
|
||||||
|
|
||||||
use git2::Repository;
|
use git2::Repository;
|
||||||
|
|
||||||
|
/// Check the configuration whether we should commit interactively
|
||||||
pub fn commit_interactive(config: &Value) -> bool {
|
pub fn commit_interactive(config: &Value) -> bool {
|
||||||
match config.lookup("commit.interactive") {
|
match config.lookup("commit.interactive") {
|
||||||
Some(&Value::Boolean(b)) => b,
|
Some(&Value::Boolean(b)) => b,
|
||||||
|
@ -27,6 +28,7 @@ pub fn commit_interactive(config: &Value) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check the configuration whether we should commit with the editor
|
||||||
fn commit_with_editor(config: &Value) -> bool {
|
fn commit_with_editor(config: &Value) -> bool {
|
||||||
match config.lookup("commit.interactive_editor") {
|
match config.lookup("commit.interactive_editor") {
|
||||||
Some(&Value::Boolean(b)) => b,
|
Some(&Value::Boolean(b)) => b,
|
||||||
|
@ -44,6 +46,7 @@ fn commit_with_editor(config: &Value) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the commit default message
|
||||||
fn commit_default_msg<'a>(config: &'a Value) -> &'a str {
|
fn commit_default_msg<'a>(config: &'a Value) -> &'a str {
|
||||||
match config.lookup("commit.message") {
|
match config.lookup("commit.message") {
|
||||||
Some(&Value::String(ref b)) => b,
|
Some(&Value::String(ref b)) => b,
|
||||||
|
@ -61,10 +64,18 @@ fn commit_default_msg<'a>(config: &'a Value) -> &'a str {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the commit template
|
||||||
|
///
|
||||||
|
/// TODO: Implement good template string
|
||||||
fn commit_template() -> &'static str {
|
fn commit_template() -> &'static str {
|
||||||
"Commit template"
|
"Commit template"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate a commit message
|
||||||
|
///
|
||||||
|
/// Uses the functions `commit_interactive()` and `commit_with_editor()`
|
||||||
|
/// or reads one from the commandline or uses the `commit_default_msg()` string to create a commit
|
||||||
|
/// message.
|
||||||
pub fn commit_message(repo: &Repository, config: &Value, action: StoreAction) -> Result<String> {
|
pub fn commit_message(repo: &Repository, config: &Value, action: StoreAction) -> Result<String> {
|
||||||
use libimaginteraction::ask::ask_string;
|
use libimaginteraction::ask::ask_string;
|
||||||
use libimagutil::edit::edit_in_tmpfile_with_command;
|
use libimagutil::edit::edit_in_tmpfile_with_command;
|
||||||
|
@ -90,10 +101,15 @@ pub fn commit_message(repo: &Repository, config: &Value, action: StoreAction) ->
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether the hook should abort if the repository cannot be initialized
|
||||||
pub fn abort_on_repo_init_err(cfg: Option<&Value>) -> bool {
|
pub fn abort_on_repo_init_err(cfg: Option<&Value>) -> bool {
|
||||||
get_bool_cfg(cfg, "abort_on_repo_init_failure", true, true)
|
get_bool_cfg(cfg, "abort_on_repo_init_failure", true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the branch which must be checked out before running the hook (if any).
|
||||||
|
///
|
||||||
|
/// If there is no configuration for this, this is `Ok(None)`, otherwise we try to find the
|
||||||
|
/// configuration `String`.
|
||||||
pub fn ensure_branch(cfg: Option<&Value>) -> Result<Option<String>> {
|
pub fn ensure_branch(cfg: Option<&Value>) -> Result<Option<String>> {
|
||||||
match cfg {
|
match cfg {
|
||||||
Some(cfg) => {
|
Some(cfg) => {
|
||||||
|
@ -114,10 +130,12 @@ pub fn ensure_branch(cfg: Option<&Value>) -> Result<Option<String>> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether we should check out a branch before committing.
|
||||||
pub fn do_checkout_ensure_branch(cfg: Option<&Value>) -> bool {
|
pub fn do_checkout_ensure_branch(cfg: Option<&Value>) -> bool {
|
||||||
get_bool_cfg(cfg, "try_checkout_ensure_branch", true, true)
|
get_bool_cfg(cfg, "try_checkout_ensure_branch", true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper to get a boolean value from the configuration.
|
||||||
fn get_bool_cfg(cfg: Option<&Value>, name: &str, on_fail: bool, on_unavail: bool) -> bool {
|
fn get_bool_cfg(cfg: Option<&Value>, name: &str, on_fail: bool, on_unavail: bool) -> bool {
|
||||||
cfg.map(|cfg| {
|
cfg.map(|cfg| {
|
||||||
match cfg.lookup(name) {
|
match cfg.lookup(name) {
|
||||||
|
|
|
@ -14,6 +14,9 @@ use vcs::git::action::StoreAction;
|
||||||
use vcs::git::result::Result;
|
use vcs::git::result::Result;
|
||||||
use vcs::git::error::{MapErrInto, GitHookErrorKind as GHEK};
|
use vcs::git::error::{MapErrInto, GitHookErrorKind as GHEK};
|
||||||
|
|
||||||
|
/// Runtime object for git hook implementations.
|
||||||
|
///
|
||||||
|
/// Contains some utility functionality to hold the repository and the configuration for the hooks.
|
||||||
pub struct Runtime {
|
pub struct Runtime {
|
||||||
repository: Option<Repository>,
|
repository: Option<Repository>,
|
||||||
config: Option<Value>,
|
config: Option<Value>,
|
||||||
|
@ -21,6 +24,11 @@ pub struct Runtime {
|
||||||
|
|
||||||
impl Runtime {
|
impl Runtime {
|
||||||
|
|
||||||
|
/// Build a `Runtime` object, pass the store path to build the `Repository` instance the
|
||||||
|
/// `Runtime` has to contain.
|
||||||
|
///
|
||||||
|
/// If the building of the `Repository` fails, this function `trace_error()`s the error and
|
||||||
|
/// returns a `Runtime` object that does _not_ contain a `Repository`.
|
||||||
pub fn new(storepath: &PathBuf) -> Runtime {
|
pub fn new(storepath: &PathBuf) -> Runtime {
|
||||||
Runtime {
|
Runtime {
|
||||||
repository: match Repository::open(storepath) {
|
repository: match Repository::open(storepath) {
|
||||||
|
@ -35,19 +43,27 @@ impl Runtime {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the configuration for the `Runtime`. Always returns `Ok(())`.
|
||||||
pub fn set_config(&mut self, cfg: &Value) -> Result<()> {
|
pub fn set_config(&mut self, cfg: &Value) -> Result<()> {
|
||||||
self.config = Some(cfg.clone());
|
self.config = Some(cfg.clone());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether the `Runtime` has a `Repository`
|
||||||
pub fn has_repository(&self) -> bool {
|
pub fn has_repository(&self) -> bool {
|
||||||
self.repository.is_some()
|
self.repository.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check whether the `Runtime` has a configuration
|
||||||
pub fn has_config(&self) -> bool {
|
pub fn has_config(&self) -> bool {
|
||||||
self.config.is_some()
|
self.config.is_some()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the the config value by reference or get an `Err()` which can be returned to the callee
|
||||||
|
/// of the Hook.
|
||||||
|
///
|
||||||
|
/// The `action` Argument is required in case of `Err()` so the error message can be build
|
||||||
|
/// correctly.
|
||||||
pub fn config_value_or_err(&self, action: &StoreAction) -> HookResult<&Value> {
|
pub fn config_value_or_err(&self, action: &StoreAction) -> HookResult<&Value> {
|
||||||
self.config
|
self.config
|
||||||
.as_ref()
|
.as_ref()
|
||||||
|
@ -61,6 +77,11 @@ impl Runtime {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the `Repository` object from the `Runtime` or an `Err()` that can be returned to the
|
||||||
|
/// callee of the Hook.
|
||||||
|
///
|
||||||
|
/// The `action` Argument is required in case of `Err()` so the error message can be build
|
||||||
|
/// correctly.
|
||||||
pub fn repository(&self, action: &StoreAction) -> HookResult<&Repository> {
|
pub fn repository(&self, action: &StoreAction) -> HookResult<&Repository> {
|
||||||
use vcs::git::error::MapIntoHookError;
|
use vcs::git::error::MapIntoHookError;
|
||||||
|
|
||||||
|
@ -74,6 +95,7 @@ impl Runtime {
|
||||||
.map_dbg(|_| format!("[GIT {} HOOK]: Repository object fetched", action.uppercase()))
|
.map_dbg(|_| format!("[GIT {} HOOK]: Repository object fetched", action.uppercase()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Ensure that the branch that is put in the configuration file is checked out, if any.
|
||||||
pub fn ensure_cfg_branch_is_checked_out(&self, action: &StoreAction) -> HookResult<()> {
|
pub fn ensure_cfg_branch_is_checked_out(&self, action: &StoreAction) -> HookResult<()> {
|
||||||
use vcs::git::config::ensure_branch;
|
use vcs::git::config::ensure_branch;
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,14 @@ use vcs::git::error::GitHookErrorKind as GHEK;
|
||||||
use vcs::git::error::MapErrInto;
|
use vcs::git::error::MapErrInto;
|
||||||
use vcs::git::runtime::Runtime as GRuntime;
|
use vcs::git::runtime::Runtime as GRuntime;
|
||||||
|
|
||||||
|
/// The `UpdateHook` type
|
||||||
|
///
|
||||||
|
/// Represents a hook which is executed whenever a entry in the store is updated (written to disk).
|
||||||
|
///
|
||||||
|
/// # Time of execution
|
||||||
|
///
|
||||||
|
/// This hook is executed _after_ the store operation succeeded, so _after_ the file is written to
|
||||||
|
/// disk.
|
||||||
pub struct UpdateHook {
|
pub struct UpdateHook {
|
||||||
storepath: PathBuf,
|
storepath: PathBuf,
|
||||||
|
|
||||||
|
@ -54,6 +62,12 @@ impl Hook for UpdateHook {
|
||||||
"stdhook_git_update"
|
"stdhook_git_update"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the configuration of the hook. See
|
||||||
|
/// `libimagstorestdhook::vcs::git::runtime::Runtime::set_config()`.
|
||||||
|
///
|
||||||
|
/// This function traces the error (using `trace_error()`) that
|
||||||
|
/// `libimagstorestdhook::vcs::git::runtime::Runtime::set_config()`
|
||||||
|
/// returns, if any.
|
||||||
fn set_config(&mut self, config: &Value) {
|
fn set_config(&mut self, config: &Value) {
|
||||||
if let Err(e) = self.runtime.set_config(config) {
|
if let Err(e) = self.runtime.set_config(config) {
|
||||||
trace_error(&e);
|
trace_error(&e);
|
||||||
|
|
Loading…
Reference in a new issue