From 546de297061d6fd93e76f93261c058b93abd44e9 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 17 Aug 2023 15:01:00 +0200 Subject: [PATCH] Extract git commands to own module --- src/git.rs | 79 +++++++++++++++++++++++++++++++++++ src/main.rs | 1 + src/server/recurring/fetch.rs | 40 ++---------------- src/server/recurring/queue.rs | 2 +- src/server/recurring/repo.rs | 2 +- 5 files changed, 85 insertions(+), 39 deletions(-) create mode 100644 src/git.rs diff --git a/src/git.rs b/src/git.rs new file mode 100644 index 0000000..56777df --- /dev/null +++ b/src/git.rs @@ -0,0 +1,79 @@ +//! Execute git binary commands. + +use std::{ + error, fmt, io, + path::Path, + process::{Command, Output}, +}; + +use log::trace; + +#[derive(Debug)] +pub enum Error { + Io(io::Error), + Command(Command, Output), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Error::Io(e) => e.fmt(f), + Error::Command(command, output) => { + write!(f, "Command exited with {}", output.status)?; + write!(f, "COMMAND: {command:?}")?; + if !output.stdout.is_empty() { + let stdout = String::from_utf8_lossy(&output.stdout); + write!(f, "STDOUT:\n{}", stdout.trim_end())?; + } + if !output.stderr.is_empty() { + let stderr = String::from_utf8_lossy(&output.stderr); + write!(f, "STDERR:\n{}", stderr.trim_end())?; + } + Ok(()) + } + } + } +} + +impl error::Error for Error {} + +impl From for Error { + fn from(value: io::Error) -> Self { + Self::Io(value) + } +} + +fn run(mut command: Command) -> Result { + let output = command.output()?; + if output.status.success() { + trace!("Command exited with {}", output.status); + trace!("COMMAND: {command:?}"); + if !output.stdout.is_empty() { + let stdout = String::from_utf8_lossy(&output.stdout); + trace!("STDOUT:\n{}", stdout.trim_end()); + } + if !output.stderr.is_empty() { + let stderr = String::from_utf8_lossy(&output.stderr); + trace!("STDERR:\n{}", stderr.trim_end()); + } + Ok(output) + } else { + Err(Error::Command(command, output)) + } +} + +pub fn fetch(path: &Path, url: &str, refspecs: &[String]) -> Result<(), Error> { + let mut command = Command::new("git"); + command + .arg("fetch") + .arg("-C") + .arg(path) + .arg("--prune") + .arg("--") + .arg(url); + for refspec in refspecs { + command.arg(refspec); + } + run(command)?; + Ok(()) +} diff --git a/src/main.rs b/src/main.rs index 2edadf5..dbfc0a2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ mod args; mod config; +mod git; mod id; mod server; mod shared; diff --git a/src/server/recurring/fetch.rs b/src/server/recurring/fetch.rs index c839ac0..b1f084d 100644 --- a/src/server/recurring/fetch.rs +++ b/src/server/recurring/fetch.rs @@ -1,51 +1,17 @@ //! Update repo refs using the `git` binary. -use std::process::Command; - -use gix::bstr::ByteSlice; use log::{info, warn}; -use crate::{config::ServerConfig, server::Repo, somehow}; - -fn fetch(repo: Repo, url: &str, refspecs: &[String]) -> somehow::Result<()> { - info!("Fetching refs from {url}"); - - let mut command = Command::new("git"); - command - .arg("fetch") - .arg("-C") - .arg(repo.0.path()) - .arg("--prune") - .arg("--") - .arg(url); - for refspec in refspecs { - command.arg(refspec); - } - - let output = command.output()?; - if output.status.success() { - } else { - warn!( - "Error fetching refs:\n\ - {command:?} exited with code {}\n\ - STDOUT:\n{}\n\ - STDERR:\n{}", - output.status, - output.stdout.to_str_lossy(), - output.stderr.to_str_lossy() - ); - } - - Ok(()) -} +use crate::{config::ServerConfig, git, server::Repo, somehow}; async fn inner(repo: Repo, url: &'static str, refspecs: &'static [String]) -> somehow::Result<()> { - tokio::task::spawn_blocking(move || fetch(repo, url, refspecs)).await??; + tokio::task::spawn_blocking(move || git::fetch(repo.0.path(), url, refspecs)).await??; Ok(()) } pub(super) async fn update(config: &'static ServerConfig, repo: Repo) { if let Some(url) = &config.repo_fetch_url { + info!("Fetching refs from {url}"); if let Err(e) = inner(repo, url, &config.repo_fetch_refspecs).await { warn!("Error fetching refs:\n{e:?}"); } diff --git a/src/server/recurring/queue.rs b/src/server/recurring/queue.rs index 3d299da..e3cf525 100644 --- a/src/server/recurring/queue.rs +++ b/src/server/recurring/queue.rs @@ -5,7 +5,6 @@ use time::OffsetDateTime; use crate::somehow; async fn inner(db: &SqlitePool) -> somehow::Result<()> { - debug!("Updating queue"); let mut tx = db.begin().await?; let conn = tx.acquire().await?; @@ -40,6 +39,7 @@ async fn inner(db: &SqlitePool) -> somehow::Result<()> { } pub(super) async fn update(db: &SqlitePool) { + debug!("Updating queue"); if let Err(e) = inner(db).await { warn!("Error updating queue:\n{e:?}"); } diff --git a/src/server/recurring/repo.rs b/src/server/recurring/repo.rs index 49e58e2..813f258 100644 --- a/src/server/recurring/repo.rs +++ b/src/server/recurring/repo.rs @@ -235,7 +235,6 @@ async fn update_commit_tracked_status(conn: &mut SqliteConnection) -> somehow::R } pub async fn inner(db: &SqlitePool, repo: Repo) -> somehow::Result<()> { - debug!("Updating repo data"); let thread_local_repo = repo.0.to_thread_local(); let mut tx = db.begin().await?; let conn = tx.acquire().await?; @@ -290,6 +289,7 @@ pub async fn inner(db: &SqlitePool, repo: Repo) -> somehow::Result<()> { } pub(super) async fn update(db: &SqlitePool, repo: Repo) { + debug!("Updating repo data"); if let Err(e) = inner(db, repo).await { warn!("Error updating repo data:\n{e:?}"); }