fix config parser
cargo devel CI / cargo CI (push) Failing after 1m41s Details

This commit is contained in:
Christoph J. Scherr 2024-04-25 14:33:48 +02:00
parent 926f72b87e
commit 0e4d694b35
6 changed files with 51 additions and 24 deletions

View File

@ -1,4 +1,5 @@
--- version:
!text "echo foo"
changelog: changelog:
enable: true enable: true
git-log: true git-log: true
@ -14,12 +15,11 @@ uses:
api: api:
github: github:
type: github type: github
endpoint: https://github.com
repository: autocrate repository: autocrate
auth: auth:
user: PlexSheep user: PlexSheep
pass: pass:
env: TOKEN_GH !env TOKEN_GH
cscherr: cscherr:
type: forgejo type: forgejo
endpoint: https://git.cscherr.de endpoint: https://git.cscherr.de
@ -27,4 +27,4 @@ api:
auth: auth:
user: PlexSheep user: PlexSheep
pass: pass:
env: TOKEN_CSCHERR !env TOKEN_CSCHERR

2
.env Normal file
View File

@ -0,0 +1,2 @@
TOKEN_CSCHERR=test
TOKEN_GH=test

View File

@ -35,7 +35,6 @@ impl Changelog {
return Err(ChangelogError::GitBadStatus(out.status, buf).into()); return Err(ChangelogError::GitBadStatus(out.status, buf).into());
} }
dbg!(&buf);
Ok(Some(buf)) Ok(Some(buf))
} }

View File

@ -1,10 +1,11 @@
use std::str::FromStr;
use std::{ use std::{
collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf, process::Command, collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf, process::Command,
}; };
use git2; use git2;
use libpt::log::{debug, error, trace}; use libpt::log::{debug, error, trace};
use serde::Deserialize; use serde::{Deserialize, Serialize};
use url::Url; use url::Url;
use crate::error::*; use crate::error::*;
@ -17,7 +18,7 @@ pub trait YamlConfigSection: Debug + Clone + for<'a> Deserialize<'a> {
fn check(&self) -> Result<()>; fn check(&self) -> Result<()>;
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Changelog { pub struct Changelog {
pub enable: bool, pub enable: bool,
#[serde(alias = "git-log")] #[serde(alias = "git-log")]
@ -29,7 +30,7 @@ impl YamlConfigSection for Changelog {
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct UseCargo { pub struct UseCargo {
pub publish: bool, pub publish: bool,
pub registries: Vec<String>, pub registries: Vec<String>,
@ -40,7 +41,7 @@ impl YamlConfigSection for UseCargo {
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Uses { pub struct Uses {
cargo: UseCargo, cargo: UseCargo,
} }
@ -51,7 +52,7 @@ impl YamlConfigSection for Uses {
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum Pass { pub enum Pass {
/// pass specified as plainext /// pass specified as plainext
@ -94,7 +95,7 @@ impl YamlConfigSection for Pass {
Ok(()) Ok(())
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct ApiAuth { pub struct ApiAuth {
pub user: String, pub user: String,
pub pass: Pass, pub pass: Pass,
@ -106,11 +107,12 @@ impl YamlConfigSection for ApiAuth {
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Api { pub struct Api {
#[serde(alias = "type")] #[serde(alias = "type")]
pub server_type: ApiType, pub server_type: ApiType,
pub endpoint: Url, /// May be left empty if the [ApiType] is [Github](ApiType::Github).
pub endpoint: Option<Url>,
/// May be left empty if the Api does not need auth or the auth is part of the /// May be left empty if the Api does not need auth or the auth is part of the
/// [endpoint](Api::endpoint) [Url]. /// [endpoint](Api::endpoint) [Url].
pub auth: Option<ApiAuth>, pub auth: Option<ApiAuth>,
@ -120,10 +122,17 @@ pub struct Api {
impl YamlConfigSection for Api { impl YamlConfigSection for Api {
fn check(&self) -> Result<()> { fn check(&self) -> Result<()> {
self.server_type.check()?; self.server_type.check()?;
match self.endpoint.socket_addrs(|| None) { if self.server_type != ApiType::Github {
if self.auth.is_none() {
return Err(ConfigError::NoEndpointSet.into());
}
match self.endpoint.clone().unwrap().socket_addrs(|| None) {
Ok(_) => (), Ok(_) => (),
Err(err) => return Err(err.into()), Err(err) => return Err(err.into()),
} }
} else if let Some(_url) = &self.endpoint {
return Err(ConfigError::EndpointSetButNotNeeded.into());
}
if self.auth.is_some() { if self.auth.is_some() {
self.auth.clone().unwrap().check()?; self.auth.clone().unwrap().check()?;
} }
@ -131,7 +140,7 @@ impl YamlConfigSection for Api {
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
pub enum ApiType { pub enum ApiType {
#[serde(alias = "gitea")] #[serde(alias = "gitea")]
Gitea, Gitea,
@ -142,13 +151,22 @@ pub enum ApiType {
#[serde(alias = "forgejo")] #[serde(alias = "forgejo")]
Forgejo, Forgejo,
} }
impl ApiType {
pub fn default_endpoint(&self) -> Option<Url> {
match self {
Self::Github => Some(Url::from_str("https://github.com").unwrap()),
_ => None,
}
}
}
impl YamlConfigSection for ApiType { impl YamlConfigSection for ApiType {
fn check(&self) -> Result<()> { fn check(&self) -> Result<()> {
Ok(()) Ok(())
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")] #[serde(rename_all = "snake_case")]
pub enum Version { pub enum Version {
Text(String), Text(String),
@ -198,7 +216,7 @@ impl YamlConfigSection for Version {
} }
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize, Serialize)]
pub struct YamlConfig { pub struct YamlConfig {
pub changelog: Changelog, pub changelog: Changelog,
pub uses: Uses, pub uses: Uses,

View File

@ -61,4 +61,8 @@ pub enum ConfigError {
EnvNotSet(String), EnvNotSet(String),
#[error("Bad value for environment variable: {0}")] #[error("Bad value for environment variable: {0}")]
BadEnv(#[from] VarError), BadEnv(#[from] VarError),
#[error("An endpoint was set for an ApiType that does not require one")]
EndpointSetButNotNeeded,
#[error("No endpoint was set for an ApiType that requires one")]
NoEndpointSet
} }

View File

@ -45,11 +45,15 @@ impl ServerApi for Forgejo {
Ok(()) Ok(())
} }
async fn push_release(&mut self, rc: ReleaseContext) -> Result<()> { async fn push_release(&mut self, rc: ReleaseContext) -> Result<()> {
let raw_url = format!( let url: Url = match &self.cfg.endpoint {
"{}/api/v1/repos/{}/{}/releases", Some(url) => url.clone(),
self.cfg.endpoint, rc.username, rc.repository None => self
); .cfg
let url = Url::parse(&raw_url).map_err(ServerApiError::from)?; .server_type
.default_endpoint()
.expect("no default endpoint for this api type"),
};
url.join("/api/v1/repos/{}/{}/releases");
let body = format!( let body = format!(
r#" r#"
{{ {{