From 9a75617bade8f777c95f3ad8dd60420495c3181a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Patrick=20L=C3=BChne?= Date: Fri, 1 Mar 2019 18:02:52 +0100 Subject: [PATCH] Work in progress --- examples/test-job.sh | 3 + examples/test.rs | 1 + src/lib.rs | 149 ++++++++++++++++++++++++++----------------- 3 files changed, 96 insertions(+), 57 deletions(-) diff --git a/examples/test-job.sh b/examples/test-job.sh index 49c57c5..20efd9c 100755 --- a/examples/test-job.sh +++ b/examples/test-job.sh @@ -7,6 +7,9 @@ tmp_dir=/home/pluehne/tmp +echo "job ID: $JOB_ID" +echo "result repository: $GIT_REMOTE_URL" + mkdir -p "$tmp_dir" dir="$tmp_dir"/"$JOB_BRANCH_NAME" diff --git a/examples/test.rs b/examples/test.rs index f8ef513..b55c43d 100644 --- a/examples/test.rs +++ b/examples/test.rs @@ -50,6 +50,7 @@ fn main() Command::new("sbatch") .args(&["/home/pluehne/test-job.sh"]) .env("GIT_REMOTE_URL", &format!("file://{}", fs::canonicalize(&result_repository).unwrap().display())) + .env("JOB_ID", format!("{}", i)) .output() .expect("Could not execute command"); diff --git a/src/lib.rs b/src/lib.rs index 10f996a..b790258 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,21 +4,16 @@ use log::{info, trace}; use std::path::{Path, PathBuf}; use std::string::String; use std::str; -use std::sync::Arc; use walkdir::WalkDir; -pub struct BenchmarkRepositoryInner -{ - base_path: PathBuf, - repository: Repository, - ssh_user: String, - user_name: String, - user_email: String, -} - pub struct BenchmarkRepository { - inner: Arc + base_path: PathBuf, + repository: Repository, + jobs: u32, + ssh_user: String, + user_name: String, + user_email: String, } pub struct TargetPath @@ -58,10 +53,8 @@ impl BenchmarkRepository fn reset_origin(&self, remote_url: &str) -> &Self { - let inner = self.inner.clone(); - - if let Err(error) = inner.repository.find_remote("origin") - .or_else(|_| inner.repository.remote("origin", remote_url)) + if let Err(error) = self.repository.find_remote("origin") + .or_else(|_| self.repository.remote("origin", remote_url)) { panic!("Could not reset remote “origin”: {}", error); } @@ -73,8 +66,6 @@ impl BenchmarkRepository fn fetch_branch(&self, branch_name: &str) -> &Self { - let inner = self.inner.clone(); - let mut progress_bar = ProgressBar::new(0); progress_bar.set_style(BenchmarkRepository::progress_bar_style()); @@ -83,10 +74,10 @@ impl BenchmarkRepository remote_callbacks.credentials( |_, _, _| { - match Cred::ssh_key_from_agent(&inner.ssh_user) + match Cred::ssh_key_from_agent(&self.ssh_user) { Ok(credentials) => Ok(credentials), - Err(error) => panic!("could not retrieve key pair for SSH authentication as user “{}”: {}", inner.ssh_user, error), + Err(error) => panic!("could not retrieve key pair for SSH authentication as user “{}”: {}", self.ssh_user, error), } }); @@ -96,7 +87,7 @@ impl BenchmarkRepository let mut fetch_options = FetchOptions::new(); fetch_options.remote_callbacks(remote_callbacks); - let mut origin = inner.repository.find_remote("origin").expect("could not find remote “origin”"); + let mut origin = self.repository.find_remote("origin").expect("could not find remote “origin”"); info!("Updating branch “{}”", branch_name); @@ -141,20 +132,15 @@ impl BenchmarkRepository Err(_) => BenchmarkRepository::init(&base_path), }; - let benchmark_repository_inner = - BenchmarkRepositoryInner - { - base_path: base_path, - repository: repository, - ssh_user: ssh_user.to_string(), - user_name: user_name.to_string(), - user_email: user_email.to_string(), - }; - let benchmark_repository = BenchmarkRepository { - inner: Arc::new(benchmark_repository_inner), + base_path: base_path, + repository: repository, + jobs: 0, + ssh_user: ssh_user.to_string(), + user_name: user_name.to_string(), + user_email: user_email.to_string(), }; benchmark_repository @@ -166,10 +152,10 @@ impl BenchmarkRepository benchmark_repository } - pub fn read_file_as_index_entry(inner: &BenchmarkRepositoryInner, file_path: &Path, result_file_path: &Path) -> IndexEntry + pub 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 inner.repository.blob_path(file_path) + 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), @@ -194,7 +180,7 @@ impl BenchmarkRepository } } - pub fn commit_directory(inner: &BenchmarkRepositoryInner, directory_path: &TargetPath, branch_name: &str) + pub fn commit_directory(&self, directory_path: &TargetPath, branch_name: &str) { let mut file_paths = vec![]; @@ -214,13 +200,13 @@ impl BenchmarkRepository file_paths.push(TargetPath{source: entry.path().to_owned(), destination: directory_path.destination.join(&relative_path)}); } - BenchmarkRepository::commit_files(&inner, &file_paths, branch_name); + self.commit_files(&file_paths, branch_name); } - pub fn commit_files(inner: &BenchmarkRepositoryInner, file_paths: &[TargetPath], branch_name: &str) + pub fn commit_files(&self, file_paths: &[TargetPath], branch_name: &str) { let tip_reference_name = format!("refs/remotes/origin/{}", branch_name); - let tip_reference = match inner.repository.find_reference(&tip_reference_name) + let tip_reference = match self.repository.find_reference(&tip_reference_name) { Ok(value) => value, Err(error) => panic!("Could not find reference “{}”: {}", tip_reference_name, error), @@ -246,7 +232,7 @@ impl BenchmarkRepository for target_path in file_paths { - let index_entry = BenchmarkRepository::read_file_as_index_entry(inner, &target_path.source, &target_path.destination); + let index_entry = self.read_file_as_index_entry(&target_path.source, &target_path.destination); if let Err(error) = index.add(&index_entry) { @@ -254,13 +240,13 @@ impl BenchmarkRepository } } - let tree_object_id = match index.write_tree_to(&inner.repository) + let tree_object_id = match index.write_tree_to(&self.repository) { Ok(value) => value, Err(error) => panic!("Could not write index to tree: {}", error), }; - let tree = match inner.repository.find_tree(tree_object_id) + let tree = match self.repository.find_tree(tree_object_id) { Ok(value) => value, Err(error) => panic!("Could obtain tree: {}", error), @@ -268,7 +254,7 @@ impl BenchmarkRepository info!("Created tree object “{}”", tree_object_id); - let signature = Signature::now(&inner.user_name, &inner.user_email).expect("Could not create signature"); + let signature = Signature::now(&self.user_name, &self.user_email).expect("Could not create signature"); let message = format!("Add files"); let parent = match tip_reference.peel_to_commit() @@ -277,7 +263,7 @@ impl BenchmarkRepository Err(error) => panic!("Could not peel reference: {}", error), }; - let commit_id = match inner.repository.commit(Some(&tip_reference_name), &signature, &signature, &message, &tree, &[&parent]) + let commit_id = match self.repository.commit(Some(&tip_reference_name), &signature, &signature, &message, &tree, &[&parent]) { Ok(value) => value, Err(error) => panic!("Could not write commit: {}", error), @@ -291,10 +277,10 @@ impl BenchmarkRepository remote_callbacks.credentials( |_, _, _| { - match Cred::ssh_key_from_agent(&inner.ssh_user) + 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 “{}”: {}", inner.ssh_user, error), + Err(error) => panic!("could not retrieve key pair for SSH authentication as user “{}”: {}", self.ssh_user, error), } }); @@ -304,16 +290,14 @@ impl BenchmarkRepository let mut push_options = PushOptions::new(); push_options.remote_callbacks(remote_callbacks); - let mut remote = inner.repository.find_remote("origin").expect(""); + 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 { - let inner = self.inner.clone(); - let tip_reference_name = format!("refs/remotes/origin/{}", branch_name); - let tip_reference = match inner.repository.find_reference(&tip_reference_name) + let tip_reference = match self.repository.find_reference(&tip_reference_name) { Ok(value) => value, Err(error) => panic!("Could not find reference “{}”: {}", tip_reference_name, error), @@ -331,7 +315,7 @@ impl BenchmarkRepository Err(_) => return false, }; - if let Err(_) = inner.repository.find_blob(object_id) + if let Err(_) = self.repository.find_blob(object_id) { return false; } @@ -341,10 +325,8 @@ impl BenchmarkRepository pub fn read_file(&self, file_path: &Path, branch_name: &str) -> Option { - let inner = self.inner.clone(); - let tip_reference_name = format!("refs/remotes/origin/{}", branch_name); - let tip_reference = match inner.repository.find_reference(&tip_reference_name) + let tip_reference = match self.repository.find_reference(&tip_reference_name) { Ok(value) => value, Err(error) => panic!("Could not find reference “{}”: {}", tip_reference_name, error), @@ -362,7 +344,7 @@ impl BenchmarkRepository Err(_) => return None, }; - let blob = match inner.repository.find_blob(object_id) + let blob = match self.repository.find_blob(object_id) { Ok(blob) => blob, Err(_) => return None, @@ -377,11 +359,12 @@ impl BenchmarkRepository Some(content.to_owned()) } - pub fn create_result_repository_for_job(&self, job_id: u32) -> PathBuf + pub fn create_result_repository(&mut self) -> PathBuf { - let inner = self.inner.clone(); + let job_id = self.jobs; + self.jobs += 1; - let repository_path = inner.base_path.join(format!("job-{}", job_id)); + let repository_path = self.base_path.join(format!("job-{}", job_id)); if repository_path.exists() { @@ -405,11 +388,63 @@ impl BenchmarkRepository pub fn join(&self) { + let mut Vec job_commit_ids; + loop { + for job_id in 0..self.jobs + { + let repository_path = self.base_path.join(format!("job-{}", job_id)); + + let repository = match Repository::open(&repository_path) + { + Ok(repository) => repository, + Err(error) => panic!("cannot access result repository for job {}: {}", job_id, error), + }; + + let tip_reference_name = "refs/remotes/origin/master"; + let tip_reference = match self.repository.find_reference(&tip_reference_name) + { + Ok(value) => value, + Err(error) => panic!("error reading result repository for job {}: {}", job_id, error), + }; + + let commit = match tip_reference.peel_to_commit() + { + Ok(value) => value, + Err(error) => panic!("error reading result repository for job {}: {}", job_id, error), + }; + + let tree = match tip_reference.peel_to_tree() + { + Ok(value) => value, + Err(error) => panic!("Could not peel reference to tree: {}", error), + }; + + let object_id = match tree.get_path(file_path) + { + Ok(tree_entry) => tree_entry.id(), + Err(_) => return None, + }; + + let blob = match self.repository.find_blob(object_id) + { + Ok(blob) => blob, + Err(_) => return None, + }; + + let content = match std::str::from_utf8(blob.content()) + { + Ok(content) => content, + Err(error) => panic!("Could not interpret file “{}” as UTF-8: {}", file_path.display(), error), + }; + + Some(content.to_owned()) + } + //let origin = self.inner.repository.find_remote("origin").expect("could not find remote “origin”"); - for reference in self.inner.repository.references().unwrap().names() + for reference in self.repository.references().unwrap().names() { println!("{}", reference.unwrap()); }