From 6e9245542f070c39a1975f0d53d88913c4ac667d Mon Sep 17 00:00:00 2001 From: DanConwayDev Date: Sun, 1 Oct 2023 00:00:00 +0100 Subject: feat(prs-create) find commits and create events - identify commits - create pull request event - create patch events --- test_utils/src/git.rs | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 test_utils/src/git.rs (limited to 'test_utils/src/git.rs') diff --git a/test_utils/src/git.rs b/test_utils/src/git.rs new file mode 100644 index 0000000..166693d --- /dev/null +++ b/test_utils/src/git.rs @@ -0,0 +1,123 @@ +//create + +// implement drop? +use std::{env::current_dir, fs, path::PathBuf}; + +use anyhow::Result; +use git2::{Oid, RepositoryInitOptions, Signature, Time}; + +pub struct GitTestRepo { + pub dir: PathBuf, + pub git_repo: git2::Repository, +} + +impl Default for GitTestRepo { + fn default() -> Self { + Self::new("main").unwrap() + } +} +impl GitTestRepo { + pub fn new(main_branch_name: &str) -> Result { + let path = current_dir()?.join(format!("tmpgit-{}", rand::random::())); + let git_repo = git2::Repository::init_opts( + &path, + RepositoryInitOptions::new() + .initial_head(main_branch_name) + .mkpath(true), + )?; + Ok(Self { + dir: path, + git_repo, + }) + } + + pub fn initial_commit(&self) -> Result { + let oid = self.git_repo.index()?.write_tree()?; + let tree = self.git_repo.find_tree(oid)?; + let commit_oid = self.git_repo.commit( + Some("HEAD"), + &joe_signature(), + &joe_signature(), + "Initial commit", + &tree, + &[], + )?; + Ok(commit_oid) + } + + pub fn populate(&self) -> Result { + self.initial_commit()?; + fs::write(self.dir.join("t1.md"), "some content")?; + self.stage_and_commit("add t1.md")?; + fs::write(self.dir.join("t2.md"), "some content1")?; + self.stage_and_commit("add t2.md") + } + + pub fn stage_and_commit(&self, message: &str) -> Result { + let prev_oid = self.git_repo.head().unwrap().peel_to_commit()?; + + let mut index = self.git_repo.index()?; + index.add_all(["."], git2::IndexAddOption::DEFAULT, None)?; + index.write()?; + + let oid = self.git_repo.commit( + Some("HEAD"), + &joe_signature(), + &joe_signature(), + message, + &self.git_repo.find_tree(index.write_tree()?)?, + &[&prev_oid], + )?; + + Ok(oid) + } + + pub fn create_branch(&self, branch_name: &str) -> Result<()> { + self.git_repo + .branch(branch_name, &self.git_repo.head()?.peel_to_commit()?, false)?; + Ok(()) + } + + pub fn checkout(&self, ref_name: &str) -> Result { + let (object, reference) = self.git_repo.revparse_ext(ref_name)?; + + self.git_repo.checkout_tree(&object, None)?; + + match reference { + // gref is an actual reference like branches or tags + Some(gref) => self.git_repo.set_head(gref.name().unwrap()), + // this is a commit, not a reference + None => self.git_repo.set_head_detached(object.id()), + }?; + let oid = self.git_repo.head()?.peel_to_commit()?.id(); + Ok(oid) + } +} + +impl Drop for GitTestRepo { + fn drop(&mut self) { + let _ = fs::remove_dir_all(&self.dir); + } +} +pub fn joe_signature() -> Signature<'static> { + Signature::new("Joe Bloggs", "joe.bloggs@pm.me", &Time::new(0, 0)).unwrap() +} + +#[cfg(test)] +mod tests { + + use super::*; + + #[test] + fn methods_do_not_throw() -> Result<()> { + let repo = GitTestRepo::new("main")?; + + repo.populate()?; + repo.create_branch("feature")?; + repo.checkout("feature")?; + fs::write(repo.dir.join("t3.md"), "some content")?; + repo.stage_and_commit("add t3.md")?; + + Ok(()) + } +} -- cgit v1.2.3