Initialize repo if fetch url is configured

This commit is contained in:
Joscha 2023-08-17 15:08:09 +02:00
parent 546de29706
commit 5ca8fee66a
2 changed files with 89 additions and 6 deletions

View file

@ -6,7 +6,8 @@ use std::{
process::{Command, Output},
};
use log::trace;
use log::{trace, warn};
use regex::bytes::Regex;
#[derive(Debug)]
pub enum Error {
@ -62,6 +63,45 @@ fn run(mut command: Command) -> Result<Output, Error> {
}
}
pub fn init_bare(path: &Path) -> Result<(), Error> {
let mut command = Command::new("git");
command.arg("init").arg("--bare").arg("--").arg(path);
run(command)?;
Ok(())
}
pub fn fetch_head(path: &Path, url: &str) -> Result<(), Error> {
let mut command = Command::new("git");
command
.arg("-C")
.arg(path)
.arg("ls-remote")
.arg("--symref")
.arg("--")
.arg(url)
.arg("HEAD"); // Includes other refs like refs/foo/HEAD
let output = run(command)?;
let regex = Regex::new(r"(?m)^ref: (refs/\S+)\s+HEAD$").unwrap();
let Some(captures) = regex.captures(&output.stdout) else {
warn!("Did not find HEAD of {url}");
return Ok(());
};
let head = String::from_utf8_lossy(captures.get(1).unwrap().as_bytes());
let mut command = Command::new("git");
command
.arg("-C")
.arg(path)
.arg("symbolic-ref")
.arg("--")
.arg("HEAD")
.arg(&head as &str);
run(command)?;
Ok(())
}
pub fn fetch(path: &Path, url: &str, refspecs: &[String]) -> Result<(), Error> {
let mut command = Command::new("git");
command

View file

@ -9,6 +9,7 @@ use std::{
time::Duration,
};
use anyhow::anyhow;
use axum::extract::FromRef;
use gix::ThreadSafeRepository;
use log::{debug, info};
@ -18,10 +19,54 @@ use sqlx::{
};
use tokio::select;
use crate::{args::ServerCommand, config::ServerConfig, somehow};
use crate::{args::ServerCommand, config::ServerConfig, git, somehow};
use self::workers::Workers;
fn open_repo(
path: &Path,
url: &Option<String>,
refspecs: &[String],
) -> somehow::Result<ThreadSafeRepository> {
if path.exists() {
info!("Opening repo at {}", path.display());
Ok(ThreadSafeRepository::open(path)?)
} else if let Some(url) = url {
info!(
"No repo found at {} but a fetch url is configured",
path.display()
);
info!("Creating bare repo");
git::init_bare(path)?;
info!("Fetching HEAD from {url}");
git::fetch_head(path, url)?;
info!("Fetching refs for the first time (this may take a while)");
git::fetch(path, url, refspecs)?;
Ok(ThreadSafeRepository::open(path)?)
} else {
Err(somehow::Error(anyhow!(
"Failed to open repo: No repo found at {} and no fetch url is configured",
path.display()
)))
}
}
fn open_bench_repo(path: &Path) -> somehow::Result<ThreadSafeRepository> {
if path.exists() {
info!("Opening bench repo at {}", path.display());
Ok(ThreadSafeRepository::open(path)?)
} else {
Err(somehow::Error(anyhow!(
"Failed to open bench repo: No repo found at {}",
path.display()
)))
}
}
async fn open_db(path: &Path) -> sqlx::Result<SqlitePool> {
let options = SqliteConnectOptions::new()
// https://www.sqlite.org/pragma.html#pragma_journal_mode
@ -77,16 +122,14 @@ impl Server {
command: ServerCommand,
) -> somehow::Result<Self> {
let repo = if let Some(path) = command.repo.as_ref() {
info!("Opening repo at {}", path.display());
let repo = ThreadSafeRepository::open(path)?;
let repo = open_repo(path, &config.repo_fetch_url, &config.repo_fetch_refspecs)?;
Some(Repo(Arc::new(repo)))
} else {
None
};
let bench_repo = if let Some(path) = command.bench_repo.as_ref() {
info!("Opening bench repo at {}", path.display());
let repo = ThreadSafeRepository::open(path)?;
let repo = open_bench_repo(path)?;
Some(BenchRepo(Arc::new(repo)))
} else {
None