refactor: extract git::repository::factory module
This commit is contained in:
parent
5ab075c181
commit
4e60be61f7
10 changed files with 76 additions and 76 deletions
51
crates/git/src/repository/factory.rs
Normal file
51
crates/git/src/repository/factory.rs
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,30 +1,23 @@
|
||||||
//
|
//
|
||||||
use std::sync::{atomic::AtomicBool, Arc, RwLock};
|
use super::RepoDetails;
|
||||||
|
use crate::repository::test::TestRepository;
|
||||||
use derive_more::Deref as _;
|
use crate::validation::remotes::validate_default_remotes;
|
||||||
|
pub use factory::RepositoryFactory;
|
||||||
pub mod open;
|
|
||||||
// mod real;
|
|
||||||
mod test;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests;
|
|
||||||
|
|
||||||
use git_next_config as config;
|
use git_next_config as config;
|
||||||
use git_next_config::GitDir;
|
use git_next_config::GitDir;
|
||||||
|
|
||||||
pub use open::otest::OnFetch;
|
pub use open::otest::OnFetch;
|
||||||
pub use open::otest::OnPush;
|
pub use open::otest::OnPush;
|
||||||
|
|
||||||
pub use open::OpenRepository;
|
pub use open::OpenRepository;
|
||||||
pub use open::OpenRepositoryLike;
|
pub use open::OpenRepositoryLike;
|
||||||
pub use open::RealOpenRepository;
|
pub use open::RealOpenRepository;
|
||||||
use tracing::info;
|
use tracing::info;
|
||||||
|
|
||||||
use crate::repository::test::TestRepository;
|
pub mod factory;
|
||||||
use crate::validation::remotes::validate_default_remotes;
|
pub mod open;
|
||||||
|
mod test;
|
||||||
|
|
||||||
use super::RepoDetails;
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
@ -41,7 +34,7 @@ pub const fn test(fs: kxio::fs::FileSystem) -> TestRepository {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
#[cfg(not(tarpaulin_include))] // requires network access to either clone new and/or fetch.
|
#[cfg(not(tarpaulin_include))] // requires network access to either clone new and/or fetch.
|
||||||
pub fn open(
|
pub fn open(
|
||||||
repository_factory: &dyn RepositoryFactory,
|
repository_factory: &dyn factory::RepositoryFactory,
|
||||||
repo_details: &RepoDetails,
|
repo_details: &RepoDetails,
|
||||||
gitdir: config::GitDir,
|
gitdir: config::GitDir,
|
||||||
) -> Result<Box<dyn OpenRepositoryLike>> {
|
) -> Result<Box<dyn OpenRepositoryLike>> {
|
||||||
|
@ -58,50 +51,6 @@ pub fn open(
|
||||||
Ok(open_repository)
|
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 {
|
pub trait RepositoryLike {
|
||||||
fn open(&self, gitdir: &GitDir) -> Result<OpenRepository>;
|
fn open(&self, gitdir: &GitDir) -> Result<OpenRepository>;
|
||||||
fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository>;
|
fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository>;
|
||||||
|
|
|
@ -6,6 +6,6 @@ fn should_fetch_from_repo() {
|
||||||
// uses the current repo and fetches from the remote server
|
// uses the current repo and fetches from the remote server
|
||||||
let_assert!(Ok(cwd) = std::env::current_dir());
|
let_assert!(Ok(cwd) = std::env::current_dir());
|
||||||
let gitdir = GitDir::from(cwd.join("../.."));
|
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());
|
let_assert!(Ok(_) = repo.fetch());
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ fn should_find_default_push_remote() {
|
||||||
// uses the current repo
|
// uses the current repo
|
||||||
let_assert!(Ok(cwd) = std::env::current_dir());
|
let_assert!(Ok(cwd) = std::env::current_dir());
|
||||||
let gitdir = config::GitDir::from(cwd.join("../..")); // from ./crate/git directory to the project rook
|
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));
|
let_assert!(Some(remote) = repo.find_default_remote(crate::repository::Direction::Push));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
remote,
|
remote,
|
||||||
|
|
|
@ -23,7 +23,7 @@ mod repos {
|
||||||
.expect_find_default_remote()
|
.expect_find_default_remote()
|
||||||
.with(mockall::predicate::eq(Direction::Push))
|
.with(mockall::predicate::eq(Direction::Push))
|
||||||
.return_once(|_| None);
|
.return_once(|_| None);
|
||||||
let mut repository_factory = git::repository::mock();
|
let mut repository_factory = git::repository::factory::mock();
|
||||||
repository_factory
|
repository_factory
|
||||||
.expect_open()
|
.expect_open()
|
||||||
.return_once(move |_| Ok(mock_open_repository));
|
.return_once(move |_| Ok(mock_open_repository));
|
||||||
|
@ -63,7 +63,7 @@ mod positions {
|
||||||
mock_open_repository
|
mock_open_repository
|
||||||
.expect_fetch()
|
.expect_fetch()
|
||||||
.return_once(|| Err(git::fetch::Error::TestFailureExpected));
|
.return_once(|| Err(git::fetch::Error::TestFailureExpected));
|
||||||
let mut repository_factory = git::repository::mock();
|
let mut repository_factory = git::repository::factory::mock();
|
||||||
repository_factory
|
repository_factory
|
||||||
.expect_open()
|
.expect_open()
|
||||||
.return_once(move |_| Ok(mock_open_repository));
|
.return_once(move |_| Ok(mock_open_repository));
|
||||||
|
@ -104,7 +104,7 @@ mod positions {
|
||||||
Ok(vec![])
|
Ok(vec![])
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let mut repository_factory = git::repository::mock();
|
let mut repository_factory = git::repository::factory::mock();
|
||||||
repository_factory
|
repository_factory
|
||||||
.expect_open()
|
.expect_open()
|
||||||
.return_once(move |_| Ok(mock_open_repository));
|
.return_once(move |_| Ok(mock_open_repository));
|
||||||
|
@ -143,7 +143,7 @@ mod positions {
|
||||||
Ok(vec![given::a_commit()])
|
Ok(vec![given::a_commit()])
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let mut repository_factory = git::repository::mock();
|
let mut repository_factory = git::repository::factory::mock();
|
||||||
repository_factory
|
repository_factory
|
||||||
.expect_open()
|
.expect_open()
|
||||||
.return_once(move |_| Ok(mock_open_repository));
|
.return_once(move |_| Ok(mock_open_repository));
|
||||||
|
@ -182,7 +182,7 @@ mod positions {
|
||||||
Ok(vec![given::a_commit()])
|
Ok(vec![given::a_commit()])
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
let mut repository_factory = git::repository::mock();
|
let mut repository_factory = git::repository::factory::mock();
|
||||||
repository_factory
|
repository_factory
|
||||||
.expect_open()
|
.expect_open()
|
||||||
.return_once(move |_| Ok(mock_open_repository));
|
.return_once(move |_| Ok(mock_open_repository));
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//
|
//
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use git::repository::MockRepositoryFactory;
|
use git::repository::factory::MockRepositoryFactory;
|
||||||
use git_next_git::repository::open::MockOpenRepositoryLike;
|
use git_next_git::repository::open::MockOpenRepositoryLike;
|
||||||
|
|
||||||
pub fn fetch_ok(open_repository: &mut MockOpenRepositoryLike) {
|
pub fn fetch_ok(open_repository: &mut MockOpenRepositoryLike) {
|
||||||
|
|
|
@ -290,7 +290,7 @@ async fn should_accept_message_with_current_token() -> TestResult {
|
||||||
//when
|
//when
|
||||||
let (actor, log) = given::a_repo_actor(
|
let (actor, log) = given::a_repo_actor(
|
||||||
repo_details,
|
repo_details,
|
||||||
git::repository::mock(),
|
git::repository::factory::mock(),
|
||||||
given::a_forge(),
|
given::a_forge(),
|
||||||
given::a_network().into(),
|
given::a_network().into(),
|
||||||
);
|
);
|
||||||
|
@ -314,7 +314,7 @@ async fn should_accept_message_with_new_token() -> TestResult {
|
||||||
//when
|
//when
|
||||||
let (actor, log) = given::a_repo_actor(
|
let (actor, log) = given::a_repo_actor(
|
||||||
repo_details,
|
repo_details,
|
||||||
git::repository::mock(),
|
git::repository::factory::mock(),
|
||||||
given::a_forge(),
|
given::a_forge(),
|
||||||
given::a_network().into(),
|
given::a_network().into(),
|
||||||
);
|
);
|
||||||
|
@ -338,7 +338,7 @@ async fn should_reject_message_with_expired_token() -> TestResult {
|
||||||
//when
|
//when
|
||||||
let (actor, log) = given::a_repo_actor(
|
let (actor, log) = given::a_repo_actor(
|
||||||
repo_details,
|
repo_details,
|
||||||
git::repository::mock(),
|
git::repository::factory::mock(),
|
||||||
given::a_forge(),
|
given::a_forge(),
|
||||||
given::a_network().into(),
|
given::a_network().into(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,7 +13,7 @@ use config::{
|
||||||
RepoAlias, RepoBranches, RepoConfig, ServerRepoConfig, WebhookAuth, WebhookId,
|
RepoAlias, RepoBranches, RepoConfig, ServerRepoConfig, WebhookAuth, WebhookId,
|
||||||
};
|
};
|
||||||
use git::{
|
use git::{
|
||||||
repository::{open::MockOpenRepositoryLike, Direction, MockRepositoryFactory},
|
repository::{factory::MockRepositoryFactory, open::MockOpenRepositoryLike, Direction},
|
||||||
Generation, GitRemote, MockForgeLike, RepoDetails,
|
Generation, GitRemote, MockForgeLike, RepoDetails,
|
||||||
};
|
};
|
||||||
use git_next_actor_macros::message;
|
use git_next_actor_macros::message;
|
||||||
|
|
|
@ -4,7 +4,7 @@ use git::repository::OpenRepositoryLike;
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
pub fn start_actor(
|
pub fn start_actor(
|
||||||
repository_factory: git::repository::MockRepositoryFactory,
|
repository_factory: git::repository::factory::MockRepositoryFactory,
|
||||||
repo_details: git::RepoDetails,
|
repo_details: git::RepoDetails,
|
||||||
forge: Box<dyn git::ForgeLike>,
|
forge: Box<dyn git::ForgeLike>,
|
||||||
) -> (actix::Addr<RepoActor>, RepoActorLog) {
|
) -> (actix::Addr<RepoActor>, RepoActorLog) {
|
||||||
|
@ -24,7 +24,7 @@ pub fn start_actor_with_open_repository(
|
||||||
) -> (actix::Addr<RepoActor>, RepoActorLog) {
|
) -> (actix::Addr<RepoActor>, RepoActorLog) {
|
||||||
let (actor, log) = given::a_repo_actor(
|
let (actor, log) = given::a_repo_actor(
|
||||||
repo_details,
|
repo_details,
|
||||||
git::repository::mock(),
|
git::repository::factory::mock(),
|
||||||
forge,
|
forge,
|
||||||
given::a_network().into(),
|
given::a_network().into(),
|
||||||
);
|
);
|
||||||
|
|
|
@ -13,7 +13,7 @@ use std::path::PathBuf;
|
||||||
use tracing::{error, info, warn};
|
use tracing::{error, info, warn};
|
||||||
use webhook::{AddWebhookRecipient, ShutdownWebhook, WebhookActor, WebhookRouter};
|
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.
|
message!(ReceiveServerConfig: ServerConfig: "Notification of newly loaded server configuration.
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue