checks for the yaml config
cargo devel CI / cargo CI (push) Has been cancelled Details

This commit is contained in:
Christoph J. Scherr 2024-01-25 22:33:48 +01:00
parent f9daac2f40
commit 7f1c4d3888
Signed by: PlexSheep
GPG Key ID: 7CDD0B14851A08EF
3 changed files with 69 additions and 23 deletions

View File

@ -1,9 +1,7 @@
use std::{
collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf
};
use std::{collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf};
use git2;
use libpt::log::error;
use libpt::log::{debug, error, trace};
use serde::Deserialize;
use url::Url;
@ -30,13 +28,38 @@ pub struct Cargo {
}
#[derive(Debug, Clone, Deserialize)]
pub struct ApiAuth { user: String, pass: String }
pub struct ApiAuth {
user: String,
pass: Option<String>,
pass_file: Option<PathBuf>,
}
impl ApiAuth {
pub fn check(&self) -> Result<()> {
if self.pass.is_some() && self.pass_file.is_some() {
let err = ConfigError::YamlApiAuthBothPass(self.clone()).into();
error!("{err}");
return Err(err);
}
Ok(())
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct Api {
r#type: ApiType,
endpoint: Url,
auth: ApiAuth,
/// May be left empty if the Api does not need auth or the auth is part of the
/// [endpoint](Api::endpoint) [Url].
auth: Option<ApiAuth>,
}
impl Api {
pub fn check(&self) -> Result<()> {
if let Some(auth) = &self.auth {
auth.check()?;
}
Ok(())
}
}
#[derive(Debug, Clone, Deserialize)]
@ -56,6 +79,16 @@ pub struct YamlConfig {
pub api: HashMap<String, Api>,
}
impl YamlConfig {
/// check if the built configuration is valid
pub fn check(&self) -> Result<()> {
for api in &self.api {
api.1.check()?;
}
Ok(())
}
}
pub struct Config {
pub yaml: YamlConfig,
pub repo: git2::Repository,
@ -80,7 +113,7 @@ impl Config {
let repo = match git2::Repository::open_from_env() {
Ok(repo) => repo,
Err(err) => {
let err = Error::GitRepoNotFound;
let err = ConfigError::GitRepoNotFound.into();
error!("{err}");
return Err(err);
}
@ -93,7 +126,7 @@ impl Config {
} else if path.join(".autocrate.yml").exists() {
".autocrate.yml"
} else {
let err = Error::NoYamlFile;
let err = ConfigError::NoYamlFile.into();
error!("{err}");
return Err(err);
};
@ -101,13 +134,17 @@ impl Config {
// we can be sure it exists from the checks above
assert!(yaml_file_path.exists());
if !yaml_file_path.is_file() {
let err = Error::YamlFileIsNotFile;
let err = ConfigError::YamlFileIsNotFile.into();
error!("{err}");
return Err(err);
}
let yaml_rd = BufReader::new(File::open(yaml_file_path)?);
debug!("reading yaml config and building data structure");
let yaml: YamlConfig = serde_yaml::from_reader(yaml_rd)?;
trace!("load config:\n{:#?}", yaml);
yaml.check()?;
debug!("built and checked yaml config");
Ok(Config { yaml, repo, path })
}

View File

@ -1,21 +1,31 @@
use anyhow;
use thiserror::Error;
use crate::config::ApiAuth;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
/// Bad IO operation
#[error("Bad IO operation")]
IO(#[from] std::io::Error),
#[error("Bad configuration file")]
Config(#[from] ConfigError),
#[error(transparent)]
Other(#[from] anyhow::Error),
#[error("Yaml error")]
SerdeYaml(#[from] serde_yaml::Error),
}
#[derive(Error, Debug)]
pub enum ConfigError {
#[error("could not find git repository")]
GitRepoNotFound,
#[error("no \".autocrate.yaml\" or \".autocrate.yml\" found in repository root")]
NoYamlFile,
#[error("the autocrate config file is not a regular file (is it a directory?)")]
YamlFileIsNotFile,
#[error("could not find git repository")]
GitRepoNotFound,
/// Bad IO operation
#[error("Bad IO operation")]
IO(#[from] std::io::Error),
#[error(transparent)]
Other(#[from] anyhow::Error),
#[error("Yaml error")]
SerdeYaml(#[from] serde_yaml::Error)
#[error("api {0:?} provides both a `pass` and a `pass_file`")]
YamlApiAuthBothPass(ApiAuth),
}

View File

@ -9,6 +9,5 @@ fn main() -> Result<()> {
let cli = Cli::cli_parse();
let config = Config::load(cli.clone())?;
trace!("loaded config:\n{:#?}", config.yaml);
todo!()
}