we can load a yaml config and have error handling for it
cargo devel CI / cargo CI (push) Successful in 2m16s Details

This commit is contained in:
Christoph J. Scherr 2024-01-25 22:08:05 +01:00
parent a2c699bb98
commit f9daac2f40
Signed by: PlexSheep
GPG Key ID: 7CDD0B14851A08EF
8 changed files with 70 additions and 22 deletions

View File

@ -1,6 +1,6 @@
changelog: changelog:
enable: true enable: true
git-log: true git_log: true
uses: uses:
cargo: cargo:

View File

@ -29,6 +29,7 @@ libpt = { version = "0.3.11", features = ["log"] }
serde = { version = "1.0.195", features = ["derive"] } serde = { version = "1.0.195", features = ["derive"] }
serde_yaml = "0.9.30" serde_yaml = "0.9.30"
thiserror = "1.0.56" thiserror = "1.0.56"
url = { version = "2.5.0", features = ["serde"] }
[[bin]] [[bin]]
name = "autocrate" name = "autocrate"

View File

@ -68,9 +68,9 @@ repository. It should contain the following parameters (replace the placeholders
| Parent | Key | Value | Explanation | | Parent | Key | Value | Explanation |
|-----------------|--------------|----------------------------------------------------------------------------------|------------------------------------------------------------------------------| |-----------------|--------------|----------------------------------------------------------------------------------|------------------------------------------------------------------------------|
| (root) | `changelog` | list of keys with this as parent (`git-log` etc) | information on how a changelog is generated | | (root) | `changelog` | list of keys with this as parent (`git_log` etc) | information on how a changelog is generated |
| `changelog` | `enable` | `true`/`false` | If false, no changelog will be generated | | `changelog` | `enable` | `true`/`false` | If false, no changelog will be generated |
| `changelog` | `git-log` | `true`/`false` | should a changelog be generated with `git log`? | | `changelog` | `git_log` | `true`/`false` | should a changelog be generated with `git log`? |
| (root) | `uses` | list of keys with this as parent (`cargo` etc) | Marks features to be used by Autocrate | | (root) | `uses` | list of keys with this as parent (`cargo` etc) | Marks features to be used by Autocrate |
| `uses` | `cargo` | list of keys with this as parent (`publish` etc) | tells us that your project uses cargo | | `uses` | `cargo` | list of keys with this as parent (`publish` etc) | tells us that your project uses cargo |
| `cargo` | `publish` | `true`/`false` | should we publish crates? | | `cargo` | `publish` | `true`/`false` | should we publish crates? |
@ -86,7 +86,7 @@ An example `.autocrate.yaml` could look like this:
```yaml ```yaml
changelog: changelog:
enable: true enable: true
git-log: true git_log: true
uses: uses:
cargo: cargo:

View File

@ -1,8 +1,3 @@
use serde;
use serde_yaml;
use std::path::PathBuf;
use libpt::log::{Level, Logger}; use libpt::log::{Level, Logger};
use clap::Parser; use clap::Parser;

View File

@ -1,19 +1,20 @@
use std::{ use std::{
fmt::{write, Debug}, fs::File, path::PathBuf collections::HashMap, fmt::Debug, fs::File, io::BufReader, path::PathBuf
}; };
use anyhow::{anyhow, Result};
use git2; use git2;
use libpt::log::error; use libpt::log::error;
use serde::Deserialize; use serde::Deserialize;
use url::Url;
use self::cli::Cli; use crate::error::*;
pub mod cli; pub mod cli;
use cli::Cli;
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
pub struct Changelog { pub struct Changelog {
enabled: bool, enable: bool,
git_log: bool, git_log: bool,
} }
@ -28,17 +29,23 @@ pub struct Cargo {
registries: Vec<String>, registries: Vec<String>,
} }
#[derive(Debug, Clone, Deserialize)]
pub struct ApiAuth { user: String, pass: String }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
pub struct Api { pub struct Api {
api_type: ApiType, r#type: ApiType,
publish: bool, endpoint: Url,
registries: Vec<String>, auth: ApiAuth,
} }
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
pub enum ApiType { pub enum ApiType {
#[serde(alias="gitea")]
Gitea, Gitea,
#[serde(alias="gitlab")]
Gitlab, Gitlab,
#[serde(alias="github", alias="GitHub")]
Github, Github,
} }
@ -46,7 +53,7 @@ pub enum ApiType {
pub struct YamlConfig { pub struct YamlConfig {
pub changelog: Changelog, pub changelog: Changelog,
pub uses: Uses, pub uses: Uses,
pub apis: Vec<Api>, pub api: HashMap<String,Api>,
} }
pub struct Config { pub struct Config {
@ -73,14 +80,35 @@ 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 msg = format!("could not find a git repository: {err:?}"); let err = Error::GitRepoNotFound;
error!("{}", msg); error!("{err}");
return Err(anyhow!(msg)); return Err(err);
} }
}; };
let mut path = repo.path().to_path_buf(); let mut path = repo.path().to_path_buf();
path.pop(); // we want the real root, not the `.git` dir path.pop(); // we want the real root, not the `.git` dir
todo!() let yaml_file_name = if path.join(".autocrate.yaml").exists() {
".autocrate.yaml"
} else if path.join(".autocrate.yml").exists() {
".autocrate.yml"
} else {
let err = Error::NoYamlFile;
error!("{err}");
return Err(err);
};
let yaml_file_path = path.join(yaml_file_name);
// 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;
error!("{err}");
return Err(err);
}
let yaml_rd = BufReader::new(File::open(yaml_file_path)?);
let yaml: YamlConfig = serde_yaml::from_reader(yaml_rd)?;
Ok(Config { yaml, repo, path })
} }
} }

21
src/error.rs Normal file
View File

@ -0,0 +1,21 @@
use anyhow;
use thiserror::Error;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Error, Debug)]
pub enum Error {
#[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)
}

View File

@ -1 +1,2 @@
pub mod error;
pub mod config; pub mod config;

View File

@ -1,5 +1,7 @@
use anyhow::Result; use anyhow::Result;
use libpt::log::{debug, trace};
mod error;
mod config; mod config;
use config::{cli::Cli, Config}; use config::{cli::Cli, Config};
@ -7,6 +9,6 @@ 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())?;
dbg!(config); trace!("loaded config:\n{:#?}", config.yaml);
todo!() todo!()
} }