Something went wrong. Try again.
Mirror your Git repositories
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788use std::collections::BTreeMap;use std::path::{Path, PathBuf};
use anyhow::{Context as _, Result, bail};use serde::Deserialize;
/// The top-level Kalandra configuration.#[derive(Debug, Deserialize)]#[serde(deny_unknown_fields)]pub struct Config { /// The directory in which mirrored repositories are cached. /// /// Defaults to `~/.cache/kalandra`. pub cache_dir: Option<PathBuf>, #[serde(default)] pub repos: Vec<RepoConfig>, #[serde(default)] pub destinations: BTreeMap<String, DestinationConfig>,}
#[derive(Debug, Deserialize)]#[serde(deny_unknown_fields)]pub struct RepoConfig { /// The name of the repository (e.g., `kalandra`). pub name: String, /// The source of the repository: a Git URL or a local path. pub source: String, /// The names of the destinations to mirror this repository to. #[serde(default)] pub destinations: Vec<String>,}
#[derive(Debug, Deserialize)]#[serde(tag = "type", rename_all = "snake_case", deny_unknown_fields)]pub enum DestinationConfig { /// A generic Git remote (another forge, a bare server, etc.). Git { /// The push URL. `{name}` is replaced with the repository name. url: String, }, /// An S3-compatible object store (AWS S3, Cloudflare R2, etc.). S3 { bucket: String, /// A custom endpoint, e.g. `https://<account-id>.r2.cloudflarestorage.com`. endpoint: Option<String>, /// The region. Use `auto` for R2. Defaults to `auto`. region: Option<String>, /// A key prefix under which bundles are stored. Defaults to `repos`. prefix: Option<String>, },}
impl Config { pub fn load(path: &Path) -> Result<Self> { let contents = std::fs::read_to_string(path) .with_context(|| format!("failed to read config file: {}", path.display()))?; let config: Self = toml::from_str(&contents) .with_context(|| format!("failed to parse config file: {}", path.display()))?; config.validate()?; Ok(config) }
fn validate(&self) -> Result<()> { for repo in &self.repos { for destination in &repo.destinations { if !self.destinations.contains_key(destination) { bail!( "repo {:?} references unknown destination {:?}", repo.name, destination ); } } }
Ok(()) }
pub fn cache_dir(&self) -> Result<PathBuf> { if let Some(cache_dir) = &self.cache_dir { return Ok(cache_dir.clone()); }
let cache_dir = dirs::cache_dir().context("failed to determine cache directory")?; Ok(cache_dir.join("kalandra")) }}