Rewrite hook implementation
This commit is contained in:
parent
2929b77248
commit
132d0d2698
1 changed files with 50 additions and 76 deletions
|
@ -1,9 +1,11 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::path::Path;
|
||||||
use std::fmt::{Debug, Formatter, Error as FmtError};
|
use std::fmt::{Debug, Formatter, Error as FmtError};
|
||||||
use std::result::Result as RResult;
|
use std::result::Result as RResult;
|
||||||
|
|
||||||
use toml::Value;
|
use toml::Value;
|
||||||
use git2::{Reference as GitReference, Repository, Error as Git2Error};
|
use git2::{Reference as GitReference, Repository, Error as Git2Error};
|
||||||
|
use git2::{ADD_DEFAULT, STATUS_WT_NEW, STATUS_WT_MODIFIED, IndexMatchedPath};
|
||||||
|
|
||||||
use libimagstore::storeid::StoreId;
|
use libimagstore::storeid::StoreId;
|
||||||
use libimagstore::hook::Hook;
|
use libimagstore::hook::Hook;
|
||||||
|
@ -78,12 +80,27 @@ impl HookDataAccessorProvider for CreateHook {
|
||||||
|
|
||||||
impl StoreIdAccessor for CreateHook {
|
impl StoreIdAccessor for CreateHook {
|
||||||
|
|
||||||
|
/// The implementation of the CreateHook
|
||||||
|
///
|
||||||
|
/// # Scope
|
||||||
|
///
|
||||||
|
/// What this function has to do is _adding_ the new entry to the git index.
|
||||||
|
/// After that, the UpdateHook will take care of committing the changes or new file.
|
||||||
|
///
|
||||||
fn access(&self, id: &StoreId) -> HookResult<()> {
|
fn access(&self, id: &StoreId) -> HookResult<()> {
|
||||||
use vcs::git::action::StoreAction;
|
use vcs::git::action::StoreAction;
|
||||||
use vcs::git::config::commit_message;
|
use vcs::git::config::commit_message;
|
||||||
|
|
||||||
debug!("[GIT CREATE HOOK]: {:?}", id);
|
debug!("[GIT CREATE HOOK]: {:?}", id);
|
||||||
|
|
||||||
|
let path = try!(id.into_pathbuf().map_err_into(GHEK::StoreIdHandlingError));
|
||||||
|
|
||||||
|
let cfg = try!(
|
||||||
|
self.runtime
|
||||||
|
.config_value_or_err()
|
||||||
|
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't get Value object from config")
|
||||||
|
);
|
||||||
|
|
||||||
debug!("[GIT CREATE HOOK]: Ensuring branch checkout");
|
debug!("[GIT CREATE HOOK]: Ensuring branch checkout");
|
||||||
try!(self
|
try!(self
|
||||||
.runtime
|
.runtime
|
||||||
|
@ -92,83 +109,40 @@ impl StoreIdAccessor for CreateHook {
|
||||||
.map_err(|e| HEK::HookExecutionError.into_error_with_cause(e)));
|
.map_err(|e| HEK::HookExecutionError.into_error_with_cause(e)));
|
||||||
debug!("[GIT CREATE HOOK]: Branch checked out");
|
debug!("[GIT CREATE HOOK]: Branch checked out");
|
||||||
|
|
||||||
self.runtime
|
|
||||||
.config_value_or_err()
|
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't get Value object from config")
|
|
||||||
.and_then(|cfg| {
|
|
||||||
debug!("[GIT CREATE HOOK]: Getting repository");
|
debug!("[GIT CREATE HOOK]: Getting repository");
|
||||||
|
let repo = try!(
|
||||||
self.runtime
|
self.runtime
|
||||||
.repository()
|
.repository()
|
||||||
.map(|r| (r, cfg))
|
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch Repository")
|
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch Repository")
|
||||||
.map_err_into(GHEK::RepositoryError)
|
.map_err_into(GHEK::RepositoryError)
|
||||||
.map_err(|e| e.into())
|
.map_err(|e| e.into())
|
||||||
})
|
);
|
||||||
.and_then(|(repo, cfg)| {
|
debug!("[GIT CREATE HOOK]: Repository object fetched");
|
||||||
repo.signature()
|
|
||||||
.map(|s| (repo, cfg, s))
|
let index = try!(repo.index().map_err_into(GHEK::RepositoryIndexFetchingError));
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch Signature")
|
|
||||||
.map_err_into(GHEK::RepositorySignatureFetchingError)
|
let file_status = try!(
|
||||||
.map_err_into(GHEK::RepositoryError)
|
repo.status_file(&path).map_err_into(GHEK::RepositoryFileStatusError)
|
||||||
.map_err(|e| e.into())
|
);
|
||||||
})
|
|
||||||
.and_then(|(repo, cfg, sig)| {
|
let cb = &mut |path: &Path, _matched_spec: &[u8]| -> i32 {
|
||||||
repo.index()
|
if file_status.contains(STATUS_WT_MODIFIED) ||
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch Index")
|
file_status.contains(STATUS_WT_NEW) {
|
||||||
.and_then(|mut idx| idx.write_tree().map(|t| (idx, t)))
|
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't write Tree")
|
debug!("[GIT CREATE HOOK]: File is new or modified: {}", path.display());
|
||||||
.and_then(|(idx, tree_id)| repo.find_tree(tree_id).map(|t| (idx, t)))
|
0
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't find Tree")
|
} else {
|
||||||
.map(|(idx, tree)| (repo, cfg, sig, idx, tree))
|
debug!("[GIT CREATE HOOK]: Ignoring file: {}", path.display());
|
||||||
.map_err_into(GHEK::RepositoryIndexFetchingError)
|
1
|
||||||
.map_err_into(GHEK::RepositoryError)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
})
|
|
||||||
.and_then(|(repo, cfg, sig, mut idx, tree)| {
|
|
||||||
idx.add_path(id)
|
|
||||||
.map(|_| (repo, cfg, sig, idx, tree))
|
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't add Path")
|
|
||||||
.map_dbg_err(|_| format!("\tpath = {:?}", id))
|
|
||||||
.map_dbg_err(|e| format!("\terr = {:?}", e))
|
|
||||||
.map_err_into(GHEK::RepositoryPathAddingError)
|
|
||||||
.map_err_into(GHEK::RepositoryError)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
})
|
|
||||||
.and_then(|(repo, cfg, sig, idx, tree)| {
|
|
||||||
repo.head()
|
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't fetch HEAD")
|
|
||||||
.map_err_into(GHEK::RepositoryHeadFetchingError)
|
|
||||||
.map(|h| h.target())
|
|
||||||
.and_then(|oid| {
|
|
||||||
match oid {
|
|
||||||
Some(oid) => {
|
|
||||||
repo.find_commit(oid)
|
|
||||||
.map(|c| Some(c))
|
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't find commit")
|
|
||||||
.map_dbg_err(|_| format!("\toid = {:?}", oid))
|
|
||||||
.map_err_into(GHEK::RepositoryCommitFindingError)
|
|
||||||
},
|
|
||||||
None => Ok(None),
|
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.map_err_into(GHEK::RepositoryError)
|
|
||||||
.map_err(|e| e.into())
|
|
||||||
.map(|parent| (repo, cfg, sig, idx, tree, parent))
|
|
||||||
})
|
|
||||||
.and_then(|(repo, cfg, sig, idx, tree, opt_parent)| {
|
|
||||||
let (msg, parents) = match opt_parent {
|
|
||||||
None => (String::from("Initial commit"), vec![]),
|
|
||||||
Some(p) => (commit_message(&cfg, StoreAction::Create), vec![p]),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let parents = parents.iter().collect::<Vec<_>>();
|
try!(
|
||||||
repo.commit(Some("HEAD"), &sig, &sig, &msg[..], &tree, &parents)
|
index.add_all(&[path], ADD_DEFAULT, Some(cb as &mut IndexMatchedPath))
|
||||||
.map_dbg_err_str("[GIT CREATE HOOK]: Couldn't commit")
|
.map_err_into(GHEK::RepositoryPathAddingError)
|
||||||
.map_err_into(GHEK::RepositoryCommittingError)
|
);
|
||||||
.map_err_into(GHEK::RepositoryError)
|
|
||||||
.map_err(|e| e.into())
|
index.write().map_err_into(GHEK::RepositoryIndexWritingError).map_err(|e| e.into())
|
||||||
})
|
|
||||||
.map(|_| ())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue