diff --git a/examples/test.rs b/examples/test.rs index d10329c..558471f 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -14,7 +14,7 @@ fn main() { pretty_env_logger::init(); - let mut benchmark_repository = BenchmarkRepository::new("gitea@git.luehne.de:patrick/tplp-planning-benchmark.git", Path::new("cache").to_path_buf(), "gitea", "Potassco Bot", "bot@potassco.org"); + let mut benchmark_repository = BenchmarkRepository::new("gitea@git.luehne.de:patrick/tplp-planning-benchmark.git", Path::new("cache").to_path_buf(), "gitea"); let content = benchmark_repository.read_file(Path::new("configurations.yml"), "config").unwrap(); let configurations = &YamlLoader::load_from_str(&content).unwrap()[0]["configurations"]; diff --git a/src/lib.rs b/src/lib.rs index 401a49d..9403130 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,11 @@ -use git2::{Cred, Error, FetchOptions, Index, IndexEntry, IndexTime, Oid, Progress, PushOptions, RemoteCallbacks, Repository, Signature}; +use git2::{Cred, Error, FetchOptions, Index, IndexEntry, IndexTime, Oid, Progress, PushOptions, RemoteCallbacks, Repository}; use indicatif::{ProgressBar, ProgressStyle}; use log::{info, trace}; use std::collections::{HashMap, HashSet}; use std::path::{Path, PathBuf}; use std::string::String; use std::str; -use walkdir::WalkDir; +//use walkdir::WalkDir; pub struct Job { @@ -20,8 +20,6 @@ pub struct BenchmarkRepository repository: Repository, jobs: HashMap, ssh_user: String, - user_name: String, - user_email: String, } pub struct TargetPath @@ -127,7 +125,7 @@ impl BenchmarkRepository repository } - pub fn new(remote_url: &str, base_path: PathBuf, ssh_user: &str, user_name: &str, user_email: &str) -> BenchmarkRepository + pub fn new(remote_url: &str, base_path: PathBuf, ssh_user: &str) -> BenchmarkRepository { let repository = match Repository::open(&base_path) { @@ -147,8 +145,6 @@ impl BenchmarkRepository repository: repository, jobs: HashMap::new(), ssh_user: ssh_user.to_string(), - user_name: user_name.to_string(), - user_email: user_email.to_string(), }; benchmark_repository @@ -160,17 +156,8 @@ impl BenchmarkRepository benchmark_repository } - pub fn read_file_as_index_entry(&self, file_path: &Path, result_file_path: &Path) -> IndexEntry + /*fn create_file_index_entry(&self, object_id: Oid, result_file_path: &Path) -> IndexEntry { - // create a new blob with the file contents - let object_id = match self.repository.blob_path(file_path) - { - Ok(object_id) => object_id, - Err(error) => panic!("Could not write blob for “{}”: {}", file_path.display(), error), - }; - - info!("Created object “{}” from “{}”", object_id, file_path.display()); - IndexEntry { ctime: IndexTime::new(0, 0), @@ -186,6 +173,39 @@ impl BenchmarkRepository flags_extended: 0, path: result_file_path.to_string_lossy().as_bytes().to_owned(), } + }*/ + + fn create_directory_index_entry(&self, object_id: Oid, result_file_path: &Path) -> IndexEntry + { + IndexEntry + { + ctime: IndexTime::new(0, 0), + mtime: IndexTime::new(0, 0), + dev: 0, + ino: 0, + mode: 0o100755, + uid: 0, + gid: 0, + file_size: 0, + id: object_id, + flags: 0, + flags_extended: 0, + path: result_file_path.to_string_lossy().as_bytes().to_owned(), + } + } + + /*fn read_file_as_index_entry(&self, file_path: &Path, result_file_path: &Path) -> IndexEntry + { + // create a new blob with the file contents + let object_id = match self.repository.blob_path(file_path) + { + Ok(object_id) => object_id, + Err(error) => panic!("Could not write blob for “{}”: {}", file_path.display(), error), + }; + + info!("Created object “{}” from “{}”", object_id, file_path.display()); + + self.create_file_index_entry(object_id, result_file_path) } pub fn commit_directory(&self, directory_path: &TargetPath, branch_name: &str) @@ -300,7 +320,7 @@ impl BenchmarkRepository let mut remote = self.repository.find_remote("origin").expect(""); remote.push(&[&push_refspec], Some(&mut push_options)).expect("couldn’t push"); - } + }*/ pub fn file_exists(&self, file_path: &Path, branch_name: &str) -> bool { @@ -418,6 +438,8 @@ impl BenchmarkRepository info!("waiting for jobs to finish"); std::thread::sleep(std::time::Duration::from_secs(2)); + let mut changed = false; + active_job_ids.retain ( |job_id| @@ -444,6 +466,88 @@ impl BenchmarkRepository Err(error) => panic!("could not access tip commit of “results” branch: {}", error), }; + let remote_tree = match remote_commit.tree() + { + Ok(value) => value, + Err(error) => panic!("could not access tip commit tree of “results” branch: {}", error), + }; + + let job_tree = match job_commit.tree() + { + Ok(value) => value, + Err(error) => panic!("cannot read results of job {}: {}", job_id, error), + }; + + let mut index = match Index::new() + { + Ok(value) => value, + Err(error) => panic!("could not create index: {}", error), + }; + + match index.read_tree(&remote_tree) + { + Ok(value) => value, + Err(error) => panic!("could not read tree into index: {}", error), + }; + + let result_path = Path::new(&job.key); + match index.add(&self.create_directory_index_entry(job_tree.id(), &result_path)) + { + Ok(_) => (), + Err(error) => panic!("could not add results to index: {}", error), + }; + + let new_tree_object_id = match index.write_tree_to(&self.repository) + { + Ok(value) => value, + Err(error) => panic!("could not write index to tree: {}", error), + }; + + let new_tree = match self.repository.find_tree(new_tree_object_id) + { + Ok(value) => value, + Err(error) => panic!("could obtain tree: {}", error), + }; + + trace!("Created tree object “{}”", new_tree_object_id); + + let author = job_commit.author(); + let committer = job_commit.committer(); + let message = job_commit.message().unwrap_or(""); + + let tip_reference_name = "refs/remotes/origin/results"; + let commit_id = match self.repository.commit(Some(&tip_reference_name), &author, &committer, &message, &new_tree, &[&remote_commit]) + { + Ok(value) => value, + Err(error) => panic!("could not write commit: {}", error), + }; + + let push_refspec = format!("refs/remotes/origin/results:refs/heads/results"); + + trace!("Created commit “{}”, using refspec “{}”", commit_id, push_refspec); + + let mut remote_callbacks = RemoteCallbacks::new(); + remote_callbacks.credentials( + |_, _, _| + { + match Cred::ssh_key_from_agent(&self.ssh_user) + { + Ok(value) => Ok(value), + Err(error) => panic!("could not retrieve key pair for SSH authentication as user “{}”: {}", self.ssh_user, error), + } + }); + + remote_callbacks.push_update_reference( + |reference, status| BenchmarkRepository::push_update_reference_callback(reference, status)); + + let mut push_options = PushOptions::new(); + push_options.remote_callbacks(remote_callbacks); + + let mut remote = self.repository.find_remote("origin").expect(""); + remote.push(&[&push_refspec], Some(&mut push_options)).expect("couldn’t push"); + + changed = true; + false } );