use terrors::OneOf; use tracing::error; use crate::server::{ config::{BranchName, RepoConfig, RepoDetails}, gitforge::{self, ForgeFileError}, }; pub async fn load( details: &RepoDetails, forge: &gitforge::Forge, ) -> Result< RepoConfig, OneOf<( ForgeFileError, crate::server::config::Error, toml::de::Error, RepoConfigValidationErrors, )>, > { let contents = forge .file_contents_get(&details.branch, ".git-next.toml") .await .map_err(OneOf::new)?; let config = RepoConfig::load(&contents).map_err(OneOf::new)?; let config = validate(config, forge).await.map_err(OneOf::new)?; Ok(config) } #[derive(Debug)] pub enum RepoConfigValidationErrors { Forge(gitforge::ForgeBranchError), BranchNotFound(BranchName), } pub async fn validate( config: RepoConfig, forge: &gitforge::Forge, ) -> Result { let branches = forge.branches_get_all().await.map_err(|e| { error!(?e, "Failed to list branches"); RepoConfigValidationErrors::Forge(e) })?; if !branches .iter() .any(|branch| branch.name() == &config.branches().main()) { return Err(RepoConfigValidationErrors::BranchNotFound( config.branches().main(), )); } if !branches .iter() .any(|branch| branch.name() == &config.branches().next()) { return Err(RepoConfigValidationErrors::BranchNotFound( config.branches().next(), )); } if !branches .iter() .any(|branch| branch.name() == &config.branches().dev()) { return Err(RepoConfigValidationErrors::BranchNotFound( config.branches().dev(), )); } Ok(config) }