From 1faf42bd82477a85403e15e3e1a45f6cde585a2d Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 17 Aug 2023 01:15:46 +0200 Subject: [PATCH] Update repo using `git fetch` --- src/server/recurring.rs | 15 +++++++---- src/server/recurring/fetch.rs | 47 +++++++++++++++++++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) create mode 100644 src/server/recurring/fetch.rs diff --git a/src/server/recurring.rs b/src/server/recurring.rs index 8c62ab0..37c177b 100644 --- a/src/server/recurring.rs +++ b/src/server/recurring.rs @@ -1,16 +1,18 @@ //! Recurring actions and updates. -// TODO `fetch` submodule for fetching new commits -// TODO `queue` submodule for updating the queue - +mod fetch; mod queue; mod repo; -use tracing::{debug_span, error, Instrument}; +use tracing::{debug_span, error, warn_span, Instrument}; use super::{Repo, Server}; async fn recurring_task(state: &Server, repo: Repo) { + fetch::update(state.config, repo.clone()) + .instrument(debug_span!("fetch refs")) + .await; + async { if let Err(e) = repo::update(&state.db, repo).await { error!("Error updating repo:\n{e:?}"); @@ -30,7 +32,10 @@ async fn recurring_task(state: &Server, repo: Repo) { pub(super) async fn run(server: Server, repo: Repo) { loop { - recurring_task(&server, repo.clone()).await; + recurring_task(&server, repo.clone()) + .instrument(warn_span!("update")) + .await; + tokio::time::sleep(server.config.repo_update).await; } } diff --git a/src/server/recurring/fetch.rs b/src/server/recurring/fetch.rs new file mode 100644 index 0000000..2e148f5 --- /dev/null +++ b/src/server/recurring/fetch.rs @@ -0,0 +1,47 @@ +//! Update repo refs using the `git` binary. + +use std::process::Command; + +use gix::bstr::ByteVec; +use tracing::{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!(exitcode = %output.status, "'git fetch' failed"); + warn!(output = "stdout", "{}", output.stdout.into_string_lossy()); + warn!(output = "stderr", "{}", output.stderr.into_string_lossy()); + } + + Ok(()) +} + +async fn inner(repo: Repo, url: &'static str, refspecs: &'static [String]) -> somehow::Result<()> { + tokio::task::spawn_blocking(move || fetch(repo, url, refspecs)).await??; + Ok(()) +} + +pub async fn update(config: &'static ServerConfig, repo: Repo) { + if let Some(url) = &config.repo_fetch_url { + if let Err(e) = inner(repo, url, &config.repo_fetch_refspecs).await { + warn!("Error fetching refs:\n{e:?}"); + } + } +}