From d4f16e6f5ecb9d8ac4ae8c1c27aab25ee433ce46 Mon Sep 17 00:00:00 2001 From: Paul Campbell Date: Fri, 13 Sep 2024 19:39:17 +0100 Subject: [PATCH] feat: should fetch repo on startup when not cloning We already have a copy of the repo, so we don't clone, but we should perform a `git fetch` to make sure it is up-to-date. --- .../cli/src/repo/tests/handlers/clone_repo.rs | 29 +++++++++++++------ crates/core/src/git/repository/mod.rs | 8 ++++- crates/core/src/git/repository/open/oreal.rs | 7 +++++ 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/crates/cli/src/repo/tests/handlers/clone_repo.rs b/crates/cli/src/repo/tests/handlers/clone_repo.rs index c953ae6..94f6aa2 100644 --- a/crates/cli/src/repo/tests/handlers/clone_repo.rs +++ b/crates/cli/src/repo/tests/handlers/clone_repo.rs @@ -43,6 +43,10 @@ async fn should_open() -> TestResult { //given let fs = given::a_filesystem(); let (mut open_repository, repo_details) = given::an_open_repository(&fs); + open_repository + .expect_fetch() + .times(1) + .return_once(|| Ok(())); given::has_all_valid_remote_defaults(&mut open_repository, &repo_details); // factory opens a repository let mut repository_factory = MockRepositoryFactory::new(); @@ -79,6 +83,10 @@ async fn when_server_has_no_repo_config_should_send_load_from_repo() -> TestResu //given let fs = given::a_filesystem(); let (mut open_repository, mut repo_details) = given::an_open_repository(&fs); + open_repository + .expect_fetch() + .times(1) + .return_once(|| Ok(())); #[allow(clippy::unwrap_used)] let _repo_config = repo_details.repo_config.take().unwrap(); @@ -106,6 +114,10 @@ async fn when_server_has_repo_config_should_send_register_webhook() -> TestResul //given let fs = given::a_filesystem(); let (mut open_repository, repo_details) = given::an_open_repository(&fs); + open_repository + .expect_fetch() + .times(1) + .return_once(|| Ok(())); #[allow(clippy::unwrap_used)] given::has_all_valid_remote_defaults(&mut open_repository, &repo_details); @@ -129,6 +141,10 @@ async fn opened_repo_with_no_default_push_should_not_proceed() -> TestResult { //given let fs = given::a_filesystem(); let (mut open_repository, repo_details) = given::an_open_repository(&fs); + open_repository + .expect_fetch() + .times(1) + .return_once(|| Ok(())); given::has_remote_defaults( &mut open_repository, @@ -158,15 +174,10 @@ async fn opened_repo_with_no_default_fetch_should_not_proceed() -> TestResult { //given let fs = given::a_filesystem(); let (mut open_repository, repo_details) = given::an_open_repository(&fs); - - given::has_remote_defaults( - &mut open_repository, - HashMap::from([ - (Direction::Push, repo_details.remote_url()), - (Direction::Fetch, None), - ]), - ); - + open_repository + .expect_fetch() + .times(1) + .return_once(|| Err(git::fetch::Error::NoFetchRemoteFound)); let mut repository_factory = MockRepositoryFactory::new(); expect::open_repository(&mut repository_factory, open_repository); fs.dir_create(&repo_details.gitdir)?; diff --git a/crates/core/src/git/repository/mod.rs b/crates/core/src/git/repository/mod.rs index fd038f2..c93ab81 100644 --- a/crates/core/src/git/repository/mod.rs +++ b/crates/core/src/git/repository/mod.rs @@ -1,6 +1,7 @@ // use crate::{ git::{ + self, repository::{ open::{OpenRepository, OpenRepositoryLike}, test::TestRepository, @@ -47,7 +48,9 @@ pub fn open( ) -> Result> { let open_repository = if repo_details.gitdir.exists() { info!("Local copy found - opening..."); - repository_factory.open(repo_details)? + let repo = repository_factory.open(repo_details)?; + repo.fetch()?; + repo } else { info!("Local copy not found - cloning..."); repository_factory.git_clone(repo_details)? @@ -117,6 +120,9 @@ pub enum Error { #[error("git clone: {0}")] Clone(String), + #[error("git fetch: {0}")] + FetchError(#[from] git::fetch::Error), + #[error("open: {0}")] Open(String), diff --git a/crates/core/src/git/repository/open/oreal.rs b/crates/core/src/git/repository/open/oreal.rs index dd8e584..578f159 100644 --- a/crates/core/src/git/repository/open/oreal.rs +++ b/crates/core/src/git/repository/open/oreal.rs @@ -67,6 +67,13 @@ impl super::OpenRepositoryLike for RealOpenRepository { #[tracing::instrument(skip_all)] #[cfg(not(tarpaulin_include))] // would require writing to external service fn fetch(&self) -> Result<(), git::fetch::Error> { + if self + .find_default_remote(git::repository::Direction::Fetch) + .is_none() + { + return Err(git::fetch::Error::NoFetchRemoteFound); + } + info!("Fetching"); gix::command::prepare("/usr/bin/git fetch --prune") .with_context(gix::diff::command::Context { git_dir: Some(