use std::ops::Deref; use tracing::info; use crate::server::config::RepoDetails; #[derive(Debug, derive_more::From, derive_more::Display)] pub enum Error { UnableToOpenRepo(Box), NoFetchRemoteFound, Connect(Box), Fetch(String), } impl std::error::Error for Error {} #[tracing::instrument] pub fn fetch(repo_details: &RepoDetails) -> Result<(), Error> { // INFO: gitdir validate tests that the default fetch remote matches the configured remote let repository = gix::ThreadSafeRepository::open(repo_details.gitdir.deref()) .map_err(Box::new)? .to_thread_local(); info!(?repository, "opened repo"); let Some(remote) = repository.find_default_remote(gix::remote::Direction::Fetch) else { return Err(Error::NoFetchRemoteFound); }; info!(?remote, "fetch remote"); remote .map_err(|e| Error::Fetch(e.to_string()))? .connect(gix::remote::Direction::Fetch) .map_err(Box::new)? .prepare_fetch(gix::progress::Discard, Default::default()) .map_err(|e| Error::Fetch(e.to_string()))? .receive(gix::progress::Discard, &Default::default()) .map_err(|e| Error::Fetch(e.to_string()))?; info!("fetched"); Ok(()) // INFO: never log the command as it contains the API token within the 'origin' // let command: secrecy::Secret = format!( // "/usr/bin/git push {} {to_commit}:{branch_name} {force}", // origin.expose_secret() // ) // .into(); // info!("Resetting {branch_name} to {to_commit}"); // let ctx = gix::diff::command::Context { // git_dir: Some(repo_details.gitdir.deref().clone()), // ..Default::default() // }; // // info!(?ctx, command = command.expose_secret(), "prepare"); // match gix::command::prepare(command.expose_secret()) // .with_context(ctx) // .with_shell_allow_argument_splitting() // // .stdout(std::process::Stdio::null()) // // .stderr(std::process::Stdio::null()) // .spawn() // { // Ok(mut child) => match child.wait() { // Ok(_) => Ok(()), // Err(err) => { // warn!(?err, "Failed (wait)"); // Err(()) // } // }, // Err(err) => { // warn!(?err, "Failed (spawn)"); // Err(()) // } // } }