Add initial implementation for UpdateHook

This commit is contained in:
Matthias Beyer 2016-09-07 21:13:40 +02:00
parent 6ef6262e54
commit 513a99fca7

View file

@ -1,14 +1,26 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::fmt::{Debug, Formatter, Error as FmtError};
use std::result::Result as RResult;
use toml::Value; use toml::Value;
use libimagstore::storeid::StoreId; use libimagerror::into::IntoError;
use libimagerror::trace::trace_error;
use libimagstore::hook::Hook; use libimagstore::hook::Hook;
use libimagstore::hook::result::HookResult;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::accessor::StoreIdAccessor; use libimagstore::hook::accessor::StoreIdAccessor;
use libimagstore::hook::accessor::{HookDataAccessor, HookDataAccessorProvider};
use libimagstore::hook::error::HookError as HE;
use libimagstore::hook::error::HookErrorKind as HEK;
use libimagstore::hook::position::HookPosition;
use libimagstore::hook::result::HookResult;
use libimagstore::storeid::StoreId;
use libimagutil::debug_result::*;
use vcs::git::error::GitHookError as GHE;
use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::error::MapIntoHookError;
use vcs::git::result::Result;
use vcs::git::runtime::Runtime as GRuntime; use vcs::git::runtime::Runtime as GRuntime;
pub struct UpdateHook { pub struct UpdateHook {
@ -64,9 +76,87 @@ impl HookDataAccessorProvider for UpdateHook {
impl StoreIdAccessor for UpdateHook { impl StoreIdAccessor for UpdateHook {
/// The implementation of the UpdateHook
///
/// # Scope
///
/// This hook takes the git index and commits it either interactively or with a default message,
/// if there is no configuration for an interactive commit.
///
fn access(&self, id: &StoreId) -> HookResult<()> { fn access(&self, id: &StoreId) -> HookResult<()> {
use vcs::git::action::StoreAction;
use vcs::git::config::commit_message;
use vcs::git::error::MapIntoHookError;
debug!("[GIT UPDATE HOOK]: {:?}", id); debug!("[GIT UPDATE HOOK]: {:?}", id);
Ok(())
let cfg = try!(
self.runtime
.config_value_or_err()
.map_dbg_err_str("[GIT UPDATE HOOK]: Couldn't get Value object from config")
);
debug!("[GIT UPDATE HOOK]: Getting repository");
let repo = try!(
self.runtime
.repository()
.map_dbg_err_str("[GIT UPDATE HOOK]: Couldn't fetch Repository")
.map_err_into(GHEK::RepositoryError)
.map_into_hook_error()
);
debug!("[GIT UPDATE HOOK]: Repository object fetched");
let mut index = try!(
repo
.index()
.map_err_into(GHEK::RepositoryIndexFetchingError)
.map_into_hook_error()
);
let tree_id = try!(
index.write_tree()
.map_err_into(GHEK::RepositoryIndexWritingError)
.map_into_hook_error()
);
let signature = try!(
repo.signature()
.map_err_into(GHEK::MkSignature)
.map_into_hook_error()
);
let head = try!(
repo.head()
.map_err_into(GHEK::HeadFetchError)
.map_into_hook_error()
);
let mut parents = Vec::new();
{
let commit = try!(
repo.find_commit(head.target().unwrap())
.map_err_into(GHEK::RepositoryParentFetchingError)
.map_into_hook_error()
);
parents.push(commit);
}
// for converting from Vec<Commit> to Vec<&Commit>
let parents = parents.iter().collect::<Vec<_>>();
let tree = try!(
repo.find_tree(tree_id)
.map_err_into(GHEK::RepositoryParentFetchingError)
.map_into_hook_error()
);
let message = try!(commit_message(cfg, StoreAction::Update));
repo.commit(Some("HEAD"), &signature, &signature, &message, &tree, &parents)
.map_err_into(GHEK::RepositoryCommittingError)
.map_into_hook_error()
.map(|_| ())
} }
} }