Initialize repo if fetch url is configured
This commit is contained in:
parent
546de29706
commit
5ca8fee66a
2 changed files with 89 additions and 6 deletions
42
src/git.rs
42
src/git.rs
|
|
@ -6,7 +6,8 @@ use std::{
|
||||||
process::{Command, Output},
|
process::{Command, Output},
|
||||||
};
|
};
|
||||||
|
|
||||||
use log::trace;
|
use log::{trace, warn};
|
||||||
|
use regex::bytes::Regex;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
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> {
|
pub fn fetch(path: &Path, url: &str, refspecs: &[String]) -> Result<(), Error> {
|
||||||
let mut command = Command::new("git");
|
let mut command = Command::new("git");
|
||||||
command
|
command
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ use std::{
|
||||||
time::Duration,
|
time::Duration,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use anyhow::anyhow;
|
||||||
use axum::extract::FromRef;
|
use axum::extract::FromRef;
|
||||||
use gix::ThreadSafeRepository;
|
use gix::ThreadSafeRepository;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
|
|
@ -18,10 +19,54 @@ use sqlx::{
|
||||||
};
|
};
|
||||||
use tokio::select;
|
use tokio::select;
|
||||||
|
|
||||||
use crate::{args::ServerCommand, config::ServerConfig, somehow};
|
use crate::{args::ServerCommand, config::ServerConfig, git, somehow};
|
||||||
|
|
||||||
use self::workers::Workers;
|
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> {
|
async fn open_db(path: &Path) -> sqlx::Result<SqlitePool> {
|
||||||
let options = SqliteConnectOptions::new()
|
let options = SqliteConnectOptions::new()
|
||||||
// https://www.sqlite.org/pragma.html#pragma_journal_mode
|
// https://www.sqlite.org/pragma.html#pragma_journal_mode
|
||||||
|
|
@ -77,16 +122,14 @@ impl Server {
|
||||||
command: ServerCommand,
|
command: ServerCommand,
|
||||||
) -> somehow::Result<Self> {
|
) -> somehow::Result<Self> {
|
||||||
let repo = if let Some(path) = command.repo.as_ref() {
|
let repo = if let Some(path) = command.repo.as_ref() {
|
||||||
info!("Opening repo at {}", path.display());
|
let repo = open_repo(path, &config.repo_fetch_url, &config.repo_fetch_refspecs)?;
|
||||||
let repo = ThreadSafeRepository::open(path)?;
|
|
||||||
Some(Repo(Arc::new(repo)))
|
Some(Repo(Arc::new(repo)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let bench_repo = if let Some(path) = command.bench_repo.as_ref() {
|
let bench_repo = if let Some(path) = command.bench_repo.as_ref() {
|
||||||
info!("Opening bench repo at {}", path.display());
|
let repo = open_bench_repo(path)?;
|
||||||
let repo = ThreadSafeRepository::open(path)?;
|
|
||||||
Some(BenchRepo(Arc::new(repo)))
|
Some(BenchRepo(Arc::new(repo)))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue