git_next_core/git/repository/
mod.rs1use crate::{
3 git::{
4 self,
5 repository::{
6 open::{OpenRepository, OpenRepositoryLike},
7 test::TestRepository,
8 },
9 validation::remotes::validate_default_remotes,
10 RepoDetails,
11 },
12 GitDir, RemoteUrl,
13};
14
15use tracing::info;
16
17pub mod factory;
18pub mod open;
19mod test;
20
21#[allow(clippy::module_name_repetitions)]
22pub use factory::RepositoryFactory;
23
24#[cfg(test)]
25mod tests;
26
27#[derive(Clone, Debug)]
28#[allow(clippy::large_enum_variant)]
29pub enum Repository {
30 Real,
31 Test(TestRepository),
32}
33
34#[cfg(test)]
35pub(crate) const fn test(
36 fs: kxio::fs::FileSystem,
37 forge_details: crate::ForgeDetails,
38) -> TestRepository {
39 TestRepository::new(fs, vec![], vec![], forge_details)
40}
41
42#[tracing::instrument(skip_all)]
44#[cfg(not(tarpaulin_include))] pub fn open(
46 repository_factory: &dyn factory::RepositoryFactory,
47 repo_details: &RepoDetails,
48) -> Result<Box<dyn OpenRepositoryLike>> {
49 use crate::s;
50
51 let open_repository = if repo_details.gitdir.exists() {
52 info!("Local copy found - opening...");
53 repository_factory.open(repo_details)?
54 } else {
55 info!("Local copy not found - cloning...");
56 repository_factory.git_clone(repo_details)?
57 };
58 validate_default_remotes(&*open_repository, repo_details)
59 .map_err(|e| Error::Validation(s!(e)))?;
60 Ok(open_repository)
61}
62
63#[allow(clippy::module_name_repetitions)]
64pub trait RepositoryLike {
65 fn open(&self, gitdir: &GitDir) -> Result<OpenRepository>;
71
72 fn git_clone(&self, repo_details: &RepoDetails) -> Result<OpenRepository>;
79}
80
81#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
82pub enum Direction {
83 Push,
85 Fetch,
87}
88impl From<Direction> for gix::remote::Direction {
89 fn from(value: Direction) -> Self {
90 match value {
91 Direction::Push => Self::Push,
92 Direction::Fetch => Self::Fetch,
93 }
94 }
95}
96
97pub type Result<T> = core::result::Result<T, Error>;
98
99#[derive(Debug, thiserror::Error)]
100pub enum Error {
101 #[error("invalid git dir: {0}")]
102 InvalidGitDir(GitDir),
103
104 #[error("kxiofs: {0}")]
105 KxioFs(#[from] kxio::fs::Error),
106
107 #[error("io: {0}")]
108 Io(std::io::Error),
109
110 #[error("git exec wait: {0}")]
111 Wait(std::io::Error),
112
113 #[error("git exec spawn: {0}")]
114 Spawn(std::io::Error),
115
116 #[error("validation: {0}")]
117 Validation(String),
118
119 #[error("git clone: {0}")]
120 Clone(String),
121
122 #[error("git fetch: {0}")]
123 FetchError(#[from] git::fetch::Error),
124
125 #[error("open: {0}")]
126 Open(String),
127
128 #[error("git fetch: {0}")]
129 Fetch(String),
130
131 #[error("fake repository lock")]
132 FakeLock,
133
134 #[error("MismatchDefaultFetchRemote(found: {found:?}, expected: {expected:?})")]
135 MismatchDefaultFetchRemote {
136 found: Box<RemoteUrl>,
137 expected: Box<RemoteUrl>,
138 },
139}
140
141mod gix_errors {
142 #![cfg(not(tarpaulin_include))]
143 use crate::s;
144
145 use super::Error;
147 impl From<gix::clone::Error> for Error {
148 fn from(value: gix::clone::Error) -> Self {
149 Self::Clone(s!(value))
150 }
151 }
152 impl From<gix::open::Error> for Error {
153 fn from(value: gix::open::Error) -> Self {
154 Self::Open(s!(value))
155 }
156 }
157 impl From<gix::clone::fetch::Error> for Error {
158 fn from(value: gix::clone::fetch::Error) -> Self {
159 Self::Fetch(s!(value))
160 }
161 }
162}