refactor(git): only expose OpenRepository from repository::open
All checks were successful
Rust / build (push) Successful in 1m29s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful

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_ref::GitRef;
pub use git_remote::GitRemote; pub use git_remote::GitRemote;
pub use repo_details::RepoDetails; pub use repo_details::RepoDetails;
pub use repository::open::OpenRepository; pub use repository::OpenRepository;
pub use repository::Repository; pub use repository::Repository;
pub use validate::validate; 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; pub struct MockRepository;
impl RepositoryLike for MockRepository { impl RepositoryLike for MockRepository {
fn open(&self, _gitdir: &GitDir) -> Result<open::OpenRepository, Error> { fn open(&self, _gitdir: &GitDir) -> Result<OpenRepository, Error> {
Ok(open::OpenRepository::Mock) Ok(OpenRepository::Mock)
} }
fn git_clone(&self, _repo_details: &RepoDetails) -> Result<open::OpenRepository, Error> { fn git_clone(&self, _repo_details: &RepoDetails) -> Result<OpenRepository, Error> {
Ok(open::OpenRepository::Mock) Ok(OpenRepository::Mock)
} }
} }

View file

@ -2,18 +2,12 @@
#![cfg(not(tarpaulin_include))] #![cfg(not(tarpaulin_include))]
mod mock; mod mock;
pub mod open; mod open;
mod real; mod real;
use std::{ use git_next_config::GitDir;
ops::Deref as _,
sync::{atomic::AtomicBool, Arc, Mutex},
};
use git_next_config::{BranchName, GitDir, Hostname, RepoPath}; pub use open::OpenRepository;
use tracing::{info, warn};
use crate::{fetch, push, GitRef, GitRemote};
use super::RepoDetails; use super::RepoDetails;
@ -30,8 +24,8 @@ pub const fn mock() -> Repository {
} }
pub trait RepositoryLike { pub trait RepositoryLike {
fn open(&self, gitdir: &GitDir) -> Result<open::OpenRepository, Error>; fn open(&self, gitdir: &GitDir) -> Result<OpenRepository, Error>;
fn git_clone(&self, repo_details: &RepoDetails) -> Result<open::OpenRepository, Error>; fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository, Error>;
} }
impl std::ops::Deref for Repository { impl std::ops::Deref for Repository {
type Target = dyn RepositoryLike; 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)] use std::sync::{Arc, Mutex};
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;
fn deref(&self) -> &Self::Target { use git_next_config::{BranchName, Hostname, RepoPath};
match self { use tracing::{info, warn};
Self::Real(real) => real,
Self::Mock => todo!(), use crate::{fetch, push, repository::Direction, GitRef, GitRemote, RepoDetails};
}
}
}
#[derive(Clone, Debug, derive_more::Constructor)] #[derive(Clone, Debug, derive_more::Constructor)]
pub struct RealOpenRepository(Arc<Mutex<gix::Repository>>); 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> { fn find_default_remote(&self, direction: Direction) -> Option<GitRemote> {
let Ok(repository) = self.0.lock() else { let Ok(repository) = self.0.lock() else {
return None; 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; pub struct RealRepository;
impl RepositoryLike for RealRepository { impl RepositoryLike for RealRepository {
fn open(&self, gitdir: &GitDir) -> Result<open::OpenRepository, Error> { fn open(&self, gitdir: &GitDir) -> Result<OpenRepository, Error> {
Ok(open::OpenRepository::Real(open::RealOpenRepository::new( let gix_repo = gix::ThreadSafeRepository::open(gitdir.to_path_buf())?.to_thread_local();
Arc::new(Mutex::new( Ok(OpenRepository::new(gix_repo))
gix::ThreadSafeRepository::open(gitdir.to_path_buf())?.to_thread_local(),
)),
)))
} }
fn git_clone(&self, repo_details: &RepoDetails) -> Result<open::OpenRepository, Error> { fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository, Error> {
use secrecy::ExposeSecret; use secrecy::ExposeSecret;
let origin = repo_details.origin(); let (gix_repo, _outcome) = gix::prepare_clone_bare(
let (repository, _outcome) = repo_details.origin().expose_secret().as_str(),
gix::prepare_clone_bare(origin.expose_secret().as_str(), repo_details.gitdir.deref())? repo_details.gitdir.deref(),
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?; )?
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?;
Ok(open::OpenRepository::Real(open::RealOpenRepository::new( Ok(OpenRepository::new(gix_repo))
Arc::new(Mutex::new(repository)),
)))
} }
} }

View file

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