use anyhow::{Error, Result}; use git2::BranchType; use crate::config::RepoConfig; pub fn pull_or_clone_and_build_and_push(repo: &RepoConfig) -> Result<(), BuildError> { let git_repo = pull_or_clone(repo)?; build(&git_repo)?; push(&git_repo)?; Ok(()) } fn pull_or_clone(repo: &RepoConfig) -> Result { match git2::Repository::open(&repo.local_git_repo) { Ok(git_repo) => { pull(&git_repo).map_err(|err| BuildError::FailedToPull(err))?; Ok(git_repo) }, Err(open_err) => match git2::Repository::clone(&repo.remote_git_repo, &repo.local_git_repo) { Ok(git_repo) => Ok(git_repo), Err(clone_err) => Err(BuildError::FailedToOpenOrClone(open_err.into(), clone_err.into())), } } } fn build(git_repo: &git2::Repository) -> Result<(), BuildError> { todo!() } fn push(git_repo: &git2::Repository) -> Result<(), BuildError> { todo!() } fn pull(git_repo: &git2::Repository) -> Result<()> { let mut origin = git_repo.find_remote("origin")?; let (main_branch, main_branch_name) = git_repo.find_branch("main", BranchType::Local).map(|b| (b, "main")) .or_else(|_| git_repo.find_branch("master", BranchType::Local).map(|b| (b, "master")))?; let upstream_main_branch = main_branch.upstream()?; git_repo.set_head(main_branch_name)?; origin.fetch(&[main_branch_name], None, None)?; let upstream_commit = git_repo.reference_to_annotated_commit(&upstream_main_branch.into_reference())?; git_repo.merge(&[&upstream_commit], None, None)?; Ok(()) } pub enum BuildError { FailedToOpenOrClone(Error, Error), FailedToPull(Error), }