refactor(git): only expose OpenRepository from repository::open

This commit is contained in:
Paul Campbell 2024-05-19 15:05:24 +01:00
parent 70100f6dc5
commit c3c4c41c73
7 changed files with 89 additions and 60 deletions

View file

@ -17,6 +17,6 @@ pub use generation::Generation;
pub use git_ref::GitRef;
pub use git_remote::GitRemote;
pub use repo_details::RepoDetails;
pub use repository::open::OpenRepository;
pub use repository::OpenRepository;
pub use repository::Repository;
pub use validate::validate;

View file

@ -1,11 +1,17 @@
use super::*;
use git_next_config::GitDir;
use crate::{
repository::{open::OpenRepository, Error, RepositoryLike},
RepoDetails,
};
pub struct MockRepository;
impl RepositoryLike for MockRepository {
fn open(&self, _gitdir: &GitDir) -> Result<open::OpenRepository, Error> {
Ok(open::OpenRepository::Mock)
fn open(&self, _gitdir: &GitDir) -> Result<OpenRepository, Error> {
Ok(OpenRepository::Mock)
}
fn git_clone(&self, _repo_details: &RepoDetails) -> Result<open::OpenRepository, Error> {
Ok(open::OpenRepository::Mock)
fn git_clone(&self, _repo_details: &RepoDetails) -> Result<OpenRepository, Error> {
Ok(OpenRepository::Mock)
}
}

View file

@ -2,18 +2,12 @@
#![cfg(not(tarpaulin_include))]
mod mock;
pub mod open;
mod open;
mod real;
use std::{
ops::Deref as _,
sync::{atomic::AtomicBool, Arc, Mutex},
};
use git_next_config::GitDir;
use git_next_config::{BranchName, GitDir, Hostname, RepoPath};
use tracing::{info, warn};
use crate::{fetch, push, GitRef, GitRemote};
pub use open::OpenRepository;
use super::RepoDetails;
@ -30,8 +24,8 @@ pub const fn mock() -> Repository {
}
pub trait RepositoryLike {
fn open(&self, gitdir: &GitDir) -> Result<open::OpenRepository, Error>;
fn git_clone(&self, repo_details: &RepoDetails) -> Result<open::OpenRepository, Error>;
fn open(&self, gitdir: &GitDir) -> Result<OpenRepository, Error>;
fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository, Error>;
}
impl std::ops::Deref for Repository {
type Target = dyn RepositoryLike;

View file

@ -0,0 +1,44 @@
//
pub mod oreal;
use std::sync::{Arc, Mutex};
use git_next_config::BranchName;
use crate::{
fetch, push,
repository::{open::oreal::RealOpenRepository, Direction},
GitRef, GitRemote, RepoDetails,
};
#[derive(Clone, Debug)]
pub enum OpenRepository {
Real(oreal::RealOpenRepository),
Mock, // TODO: (#38) contain a mock model of a repo
}
impl OpenRepository {
pub fn new(gix_repo: gix::Repository) -> Self {
Self::Real(RealOpenRepository::new(Arc::new(Mutex::new(gix_repo))))
}
}
pub trait OpenRepositoryLike {
fn find_default_remote(&self, direction: Direction) -> Option<GitRemote>;
fn fetch(&self) -> Result<(), fetch::Error>;
fn push(
&self,
repo_details: &RepoDetails,
branch_name: BranchName,
to_commit: GitRef,
force: push::Force,
) -> Result<(), push::Error>;
}
impl std::ops::Deref for OpenRepository {
type Target = dyn OpenRepositoryLike;
fn deref(&self) -> &Self::Target {
match self {
Self::Real(real) => real,
Self::Mock => todo!(),
}
}
}

View file

@ -1,34 +1,14 @@
use super::*;
#[derive(Clone, Debug)]
pub enum OpenRepository {
Real(RealOpenRepository),
Mock, // TODO: (#38) contain a mock model of a repo
}
pub trait OpenRepositoryLike {
fn find_default_remote(&self, direction: Direction) -> Option<GitRemote>;
fn fetch(&self) -> Result<(), fetch::Error>;
fn push(
&self,
repo_details: &RepoDetails,
branch_name: BranchName,
to_commit: GitRef,
force: push::Force,
) -> Result<(), push::Error>;
}
impl std::ops::Deref for OpenRepository {
type Target = dyn OpenRepositoryLike;
//
use std::sync::{Arc, Mutex};
fn deref(&self) -> &Self::Target {
match self {
Self::Real(real) => real,
Self::Mock => todo!(),
}
}
}
use git_next_config::{BranchName, Hostname, RepoPath};
use tracing::{info, warn};
use crate::{fetch, push, repository::Direction, GitRef, GitRemote, RepoDetails};
#[derive(Clone, Debug, derive_more::Constructor)]
pub struct RealOpenRepository(Arc<Mutex<gix::Repository>>);
impl OpenRepositoryLike for RealOpenRepository {
impl super::OpenRepositoryLike for RealOpenRepository {
fn find_default_remote(&self, direction: Direction) -> Option<GitRemote> {
let Ok(repository) = self.0.lock() else {
return None;

View file

@ -1,23 +1,28 @@
use super::*;
use std::sync::atomic::AtomicBool;
use derive_more::Deref as _;
use git_next_config::GitDir;
use crate::{
repository::{open::OpenRepository, Error, RepositoryLike},
RepoDetails,
};
pub struct RealRepository;
impl RepositoryLike for RealRepository {
fn open(&self, gitdir: &GitDir) -> Result<open::OpenRepository, Error> {
Ok(open::OpenRepository::Real(open::RealOpenRepository::new(
Arc::new(Mutex::new(
gix::ThreadSafeRepository::open(gitdir.to_path_buf())?.to_thread_local(),
)),
)))
fn open(&self, gitdir: &GitDir) -> Result<OpenRepository, Error> {
let gix_repo = gix::ThreadSafeRepository::open(gitdir.to_path_buf())?.to_thread_local();
Ok(OpenRepository::new(gix_repo))
}
fn git_clone(&self, repo_details: &RepoDetails) -> Result<open::OpenRepository, Error> {
fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository, Error> {
use secrecy::ExposeSecret;
let origin = repo_details.origin();
let (repository, _outcome) =
gix::prepare_clone_bare(origin.expose_secret().as_str(), repo_details.gitdir.deref())?
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?;
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))?;
Ok(open::OpenRepository::Real(open::RealOpenRepository::new(
Arc::new(Mutex::new(repository)),
)))
Ok(OpenRepository::new(gix_repo))
}
}

View file

@ -1,6 +1,6 @@
use tracing::info;
use crate::repository::{open::OpenRepository, Direction};
use crate::repository::{Direction, OpenRepository};
use super::{GitRemote, RepoDetails};