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::{ use std::{collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf};
collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf
};
use git2; use git2;
use libpt::log::error; use libpt::log::{debug, error, trace};
use serde::Deserialize; use serde::Deserialize;
use url::Url; use url::Url;
@ -30,22 +28,47 @@ pub struct Cargo {
} }
#[derive(Debug, Clone, Deserialize)] #[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)] #[derive(Debug, Clone, Deserialize)]
pub struct Api { pub struct Api {
r#type: ApiType, r#type: ApiType,
endpoint: Url, 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)] #[derive(Debug, Clone, Deserialize)]
pub enum ApiType { pub enum ApiType {
#[serde(alias="gitea")] #[serde(alias = "gitea")]
Gitea, Gitea,
#[serde(alias="gitlab")] #[serde(alias = "gitlab")]
Gitlab, Gitlab,
#[serde(alias="github", alias="GitHub")] #[serde(alias = "github", alias = "GitHub")]
Github, Github,
} }
@ -53,7 +76,17 @@ pub enum ApiType {
pub struct YamlConfig { pub struct YamlConfig {
pub changelog: Changelog, pub changelog: Changelog,
pub uses: Uses, pub uses: Uses,
pub api: HashMap<String,Api>, 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 struct Config {
@ -80,7 +113,7 @@ impl Config {
let repo = match git2::Repository::open_from_env() { let repo = match git2::Repository::open_from_env() {
Ok(repo) => repo, Ok(repo) => repo,
Err(err) => { Err(err) => {
let err = Error::GitRepoNotFound; let err = ConfigError::GitRepoNotFound.into();
error!("{err}"); error!("{err}");
return Err(err); return Err(err);
} }
@ -93,7 +126,7 @@ impl Config {
} else if path.join(".autocrate.yml").exists() { } else if path.join(".autocrate.yml").exists() {
".autocrate.yml" ".autocrate.yml"
} else { } else {
let err = Error::NoYamlFile; let err = ConfigError::NoYamlFile.into();
error!("{err}"); error!("{err}");
return Err(err); return Err(err);
}; };
@ -101,13 +134,17 @@ impl Config {
// we can be sure it exists from the checks above // we can be sure it exists from the checks above
assert!(yaml_file_path.exists()); assert!(yaml_file_path.exists());
if !yaml_file_path.is_file() { if !yaml_file_path.is_file() {
let err = Error::YamlFileIsNotFile; let err = ConfigError::YamlFileIsNotFile.into();
error!("{err}"); error!("{err}");
return Err(err); return Err(err);
} }
let yaml_rd = BufReader::new(File::open(yaml_file_path)?); 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)?; 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 }) Ok(Config { yaml, repo, path })
} }

View File

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

View File

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