#![allow(clippy::result_large_err)]
use crate::{bstr::BString, config::tree::gitoxide, remote};
type ConfigureRemoteFn =
Box<dyn FnMut(crate::Remote<'_>) -> Result<crate::Remote<'_>, Box<dyn std::error::Error + Send + Sync>>>;
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
type ConfigureConnectionFn = Box<
dyn FnMut(
&mut remote::Connection<'_, '_, Box<dyn gix_protocol::transport::client::Transport + Send>>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>>,
>;
#[must_use]
pub struct PrepareFetch {
repo: Option<crate::Repository>,
remote_name: Option<BString>,
config_overrides: Vec<BString>,
configure_remote: Option<ConfigureRemoteFn>,
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
configure_connection: Option<ConfigureConnectionFn>,
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
fetch_options: remote::ref_map::Options,
#[cfg_attr(not(feature = "blocking-network-client"), allow(dead_code))]
url: gix_url::Url,
#[cfg_attr(not(feature = "blocking-network-client"), allow(dead_code))]
shallow: remote::fetch::Shallow,
#[cfg_attr(not(feature = "blocking-network-client"), allow(dead_code))]
ref_name: Option<gix_ref::PartialName>,
}
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
#[error(transparent)]
Init(#[from] crate::init::Error),
#[error(transparent)]
UrlParse(#[from] gix_url::parse::Error),
#[error("Failed to turn a the relative file url \"{}\" into an absolute one", url.to_bstring())]
CanonicalizeUrl {
url: gix_url::Url,
source: gix_path::realpath::Error,
},
}
impl PrepareFetch {
#[allow(clippy::result_large_err)]
pub fn new<Url, E>(
url: Url,
path: impl AsRef<std::path::Path>,
kind: crate::create::Kind,
create_opts: crate::create::Options,
open_opts: crate::open::Options,
) -> Result<Self, Error>
where
Url: TryInto<gix_url::Url, Error = E>,
gix_url::parse::Error: From<E>,
{
Self::new_inner(
url.try_into().map_err(gix_url::parse::Error::from)?,
path.as_ref(),
kind,
create_opts,
open_opts,
)
}
#[allow(clippy::result_large_err)]
fn new_inner(
mut url: gix_url::Url,
path: &std::path::Path,
kind: crate::create::Kind,
mut create_opts: crate::create::Options,
open_opts: crate::open::Options,
) -> Result<Self, Error> {
create_opts.destination_must_be_empty = true;
let mut repo = crate::ThreadSafeRepository::init_opts(path, kind, create_opts, open_opts)?.to_thread_local();
url.canonicalize(repo.options.current_dir_or_empty())
.map_err(|err| Error::CanonicalizeUrl {
url: url.clone(),
source: err,
})?;
if repo.committer().is_none() {
let mut config = gix_config::File::new(gix_config::file::Metadata::api());
config
.set_raw_value(&gitoxide::Committer::NAME_FALLBACK, "no name configured during clone")
.expect("works - statically known");
config
.set_raw_value(&gitoxide::Committer::EMAIL_FALLBACK, "noEmailAvailable@example.com")
.expect("works - statically known");
let mut repo_config = repo.config_snapshot_mut();
repo_config.append(config);
repo_config.commit().expect("configuration is still valid");
}
Ok(PrepareFetch {
url,
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
fetch_options: Default::default(),
repo: Some(repo),
config_overrides: Vec::new(),
remote_name: None,
configure_remote: None,
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
configure_connection: None,
shallow: remote::fetch::Shallow::NoChange,
ref_name: None,
})
}
}
#[must_use]
#[cfg(feature = "worktree-mutation")]
#[derive(Debug)]
pub struct PrepareCheckout {
pub(self) repo: Option<crate::Repository>,
pub(self) ref_name: Option<gix_ref::PartialName>,
}
#[cfg(any(feature = "async-network-client", feature = "blocking-network-client"))]
mod access_feat {
use crate::clone::PrepareFetch;
impl PrepareFetch {
pub fn configure_connection(
mut self,
f: impl FnMut(
&mut crate::remote::Connection<'_, '_, Box<dyn gix_protocol::transport::client::Transport + Send>>,
) -> Result<(), Box<dyn std::error::Error + Send + Sync>>
+ 'static,
) -> Self {
self.configure_connection = Some(Box::new(f));
self
}
pub fn with_fetch_options(mut self, opts: crate::remote::ref_map::Options) -> Self {
self.fetch_options = opts;
self
}
}
}
#[cfg(any(feature = "async-network-client-async-std", feature = "blocking-network-client"))]
pub mod fetch;
mod access;
#[cfg(feature = "worktree-mutation")]
pub mod checkout;