refactor: extract git::repository::factory module

This commit is contained in:
Paul Campbell 2024-07-05 20:31:16 +01:00
parent 5ab075c181
commit 4e60be61f7
10 changed files with 76 additions and 76 deletions

View file

@ -0,0 +1,51 @@
use super::RepoDetails;
use super::Result;
pub use crate::repository::open::OpenRepositoryLike;
use crate::repository::RealOpenRepository;
use derive_more::Deref as _;
use git_next_config::GitDir;
use std::sync::{atomic::AtomicBool, Arc, RwLock};
#[mockall::automock]
pub trait RepositoryFactory: std::fmt::Debug + Sync + Send {
fn duplicate(&self) -> Box<dyn RepositoryFactory>;
fn open(&self, gitdir: &GitDir) -> Result<Box<dyn OpenRepositoryLike>>;
fn git_clone(&self, repo_details: &RepoDetails) -> Result<Box<dyn OpenRepositoryLike>>;
}
pub fn real() -> Box<dyn RepositoryFactory> {
Box::new(RealRepositoryFactory)
}
pub fn mock() -> Box<MockRepositoryFactory> {
Box::new(MockRepositoryFactory::new())
}
#[derive(Debug, Clone)]
struct RealRepositoryFactory;
#[cfg(not(tarpaulin_include))] // requires network access to either clone new and/or fetch.
impl RepositoryFactory for RealRepositoryFactory {
fn open(&self, gitdir: &GitDir) -> Result<Box<dyn OpenRepositoryLike>> {
let gix_repo = gix::ThreadSafeRepository::open(gitdir.to_path_buf())?.to_thread_local();
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo.into())));
Ok(Box::new(repo))
}
fn git_clone(&self, repo_details: &RepoDetails) -> Result<Box<dyn OpenRepositoryLike>> {
tracing::info!("creating");
use secrecy::ExposeSecret;
let (gix_repo, _outcome) = gix::prepare_clone_bare(
repo_details.origin().expose_secret().as_str(),
repo_details.gitdir.deref(),
)?
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?;
tracing::info!("created");
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo.into())));
Ok(Box::new(repo))
}
fn duplicate(&self) -> Box<dyn RepositoryFactory> {
Box::new(self.clone())
}
}

View file

@ -1,30 +1,23 @@
//
use std::sync::{atomic::AtomicBool, Arc, RwLock};
use derive_more::Deref as _;
pub mod open;
// mod real;
mod test;
#[cfg(test)]
mod tests;
use super::RepoDetails;
use crate::repository::test::TestRepository;
use crate::validation::remotes::validate_default_remotes;
pub use factory::RepositoryFactory;
use git_next_config as config;
use git_next_config::GitDir;
pub use open::otest::OnFetch;
pub use open::otest::OnPush;
pub use open::OpenRepository;
pub use open::OpenRepositoryLike;
pub use open::RealOpenRepository;
use tracing::info;
use crate::repository::test::TestRepository;
use crate::validation::remotes::validate_default_remotes;
pub mod factory;
pub mod open;
mod test;
use super::RepoDetails;
#[cfg(test)]
mod tests;
#[derive(Clone, Debug)]
#[allow(clippy::large_enum_variant)]
@ -41,7 +34,7 @@ pub const fn test(fs: kxio::fs::FileSystem) -> TestRepository {
#[tracing::instrument(skip_all)]
#[cfg(not(tarpaulin_include))] // requires network access to either clone new and/or fetch.
pub fn open(
repository_factory: &dyn RepositoryFactory,
repository_factory: &dyn factory::RepositoryFactory,
repo_details: &RepoDetails,
gitdir: config::GitDir,
) -> Result<Box<dyn OpenRepositoryLike>> {
@ -58,50 +51,6 @@ pub fn open(
Ok(open_repository)
}
#[mockall::automock]
pub trait RepositoryFactory: std::fmt::Debug + Sync + Send {
fn duplicate(&self) -> Box<dyn RepositoryFactory>;
fn open(&self, gitdir: &GitDir) -> Result<Box<dyn OpenRepositoryLike>>;
fn git_clone(&self, repo_details: &RepoDetails) -> Result<Box<dyn OpenRepositoryLike>>;
}
pub fn real() -> Box<dyn RepositoryFactory> {
Box::new(RealRepositoryFactory)
}
pub fn mock() -> Box<MockRepositoryFactory> {
Box::new(MockRepositoryFactory::new())
}
#[derive(Debug, Clone)]
struct RealRepositoryFactory;
#[cfg(not(tarpaulin_include))] // requires network access to either clone new and/or fetch.
impl RepositoryFactory for RealRepositoryFactory {
fn open(&self, gitdir: &GitDir) -> Result<Box<dyn OpenRepositoryLike>> {
let gix_repo = gix::ThreadSafeRepository::open(gitdir.to_path_buf())?.to_thread_local();
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo.into())));
Ok(Box::new(repo))
}
fn git_clone(&self, repo_details: &RepoDetails) -> Result<Box<dyn OpenRepositoryLike>> {
tracing::info!("creating");
use secrecy::ExposeSecret;
let (gix_repo, _outcome) = gix::prepare_clone_bare(
repo_details.origin().expose_secret().as_str(),
repo_details.gitdir.deref(),
)?
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?;
tracing::info!("created");
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo.into())));
Ok(Box::new(repo))
}
fn duplicate(&self) -> Box<dyn RepositoryFactory> {
Box::new(self.clone())
}
}
pub trait RepositoryLike {
fn open(&self, gitdir: &GitDir) -> Result<OpenRepository>;
fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository>;

View file

@ -6,6 +6,6 @@ fn should_fetch_from_repo() {
// uses the current repo and fetches from the remote server
let_assert!(Ok(cwd) = std::env::current_dir());
let gitdir = GitDir::from(cwd.join("../.."));
let_assert!(Ok(repo) = crate::repository::real().open(&gitdir));
let_assert!(Ok(repo) = crate::repository::factory::real().open(&gitdir));
let_assert!(Ok(_) = repo.fetch());
}

View file

@ -5,7 +5,7 @@ fn should_find_default_push_remote() {
// uses the current repo
let_assert!(Ok(cwd) = std::env::current_dir());
let gitdir = config::GitDir::from(cwd.join("../..")); // from ./crate/git directory to the project rook
let_assert!(Ok(repo) = crate::repository::real().open(&gitdir));
let_assert!(Ok(repo) = git::repository::factory::real().open(&gitdir));
let_assert!(Some(remote) = repo.find_default_remote(crate::repository::Direction::Push));
assert_eq!(
remote,

View file

@ -23,7 +23,7 @@ mod repos {
.expect_find_default_remote()
.with(mockall::predicate::eq(Direction::Push))
.return_once(|_| None);
let mut repository_factory = git::repository::mock();
let mut repository_factory = git::repository::factory::mock();
repository_factory
.expect_open()
.return_once(move |_| Ok(mock_open_repository));
@ -63,7 +63,7 @@ mod positions {
mock_open_repository
.expect_fetch()
.return_once(|| Err(git::fetch::Error::TestFailureExpected));
let mut repository_factory = git::repository::mock();
let mut repository_factory = git::repository::factory::mock();
repository_factory
.expect_open()
.return_once(move |_| Ok(mock_open_repository));
@ -104,7 +104,7 @@ mod positions {
Ok(vec![])
}
});
let mut repository_factory = git::repository::mock();
let mut repository_factory = git::repository::factory::mock();
repository_factory
.expect_open()
.return_once(move |_| Ok(mock_open_repository));
@ -143,7 +143,7 @@ mod positions {
Ok(vec![given::a_commit()])
}
});
let mut repository_factory = git::repository::mock();
let mut repository_factory = git::repository::factory::mock();
repository_factory
.expect_open()
.return_once(move |_| Ok(mock_open_repository));
@ -182,7 +182,7 @@ mod positions {
Ok(vec![given::a_commit()])
}
});
let mut repository_factory = git::repository::mock();
let mut repository_factory = git::repository::factory::mock();
repository_factory
.expect_open()
.return_once(move |_| Ok(mock_open_repository));

View file

@ -1,7 +1,7 @@
//
use super::*;
use git::repository::MockRepositoryFactory;
use git::repository::factory::MockRepositoryFactory;
use git_next_git::repository::open::MockOpenRepositoryLike;
pub fn fetch_ok(open_repository: &mut MockOpenRepositoryLike) {

View file

@ -290,7 +290,7 @@ async fn should_accept_message_with_current_token() -> TestResult {
//when
let (actor, log) = given::a_repo_actor(
repo_details,
git::repository::mock(),
git::repository::factory::mock(),
given::a_forge(),
given::a_network().into(),
);
@ -314,7 +314,7 @@ async fn should_accept_message_with_new_token() -> TestResult {
//when
let (actor, log) = given::a_repo_actor(
repo_details,
git::repository::mock(),
git::repository::factory::mock(),
given::a_forge(),
given::a_network().into(),
);
@ -338,7 +338,7 @@ async fn should_reject_message_with_expired_token() -> TestResult {
//when
let (actor, log) = given::a_repo_actor(
repo_details,
git::repository::mock(),
git::repository::factory::mock(),
given::a_forge(),
given::a_network().into(),
);

View file

@ -13,7 +13,7 @@ use config::{
RepoAlias, RepoBranches, RepoConfig, ServerRepoConfig, WebhookAuth, WebhookId,
};
use git::{
repository::{open::MockOpenRepositoryLike, Direction, MockRepositoryFactory},
repository::{factory::MockRepositoryFactory, open::MockOpenRepositoryLike, Direction},
Generation, GitRemote, MockForgeLike, RepoDetails,
};
use git_next_actor_macros::message;

View file

@ -4,7 +4,7 @@ use git::repository::OpenRepositoryLike;
use super::*;
pub fn start_actor(
repository_factory: git::repository::MockRepositoryFactory,
repository_factory: git::repository::factory::MockRepositoryFactory,
repo_details: git::RepoDetails,
forge: Box<dyn git::ForgeLike>,
) -> (actix::Addr<RepoActor>, RepoActorLog) {
@ -24,7 +24,7 @@ pub fn start_actor_with_open_repository(
) -> (actix::Addr<RepoActor>, RepoActorLog) {
let (actor, log) = given::a_repo_actor(
repo_details,
git::repository::mock(),
git::repository::factory::mock(),
forge,
given::a_network().into(),
);

View file

@ -13,7 +13,7 @@ use std::path::PathBuf;
use tracing::{error, info, warn};
use webhook::{AddWebhookRecipient, ShutdownWebhook, WebhookActor, WebhookRouter};
pub use git_next_git::repository::{real as repository_factory, RepositoryFactory};
pub use git_next_git::repository::{factory::real as repository_factory, RepositoryFactory};
message!(ReceiveServerConfig: ServerConfig: "Notification of newly loaded server configuration.