cuddle-please-frontend 0.1.0

A release-please inspired release manager tool, built on top of cuddle, but also useful standalone, cuddle-please supports, your ci of choice, as well as gitea, github
Documentation
use std::{
    fmt::Display,
    path::{Path, PathBuf},
};

pub mod gatheres;
mod stage0_config;

pub use gatheres::ConfigArgs;

#[derive(Debug, Clone)]
pub struct PleaseProjectConfig {
    pub owner: String,
    pub repository: String,
    pub source: PathBuf,
    pub branch: String,
}

#[derive(Debug, Clone)]
pub struct PleaseSettingsConfig {
    pub api_url: String,
    pub git_username: Option<String>,
    pub git_email: Option<String>,
}

#[derive(Debug, Clone)]
pub struct PleaseConfig {
    pub project: PleaseProjectConfig,
    pub settings: PleaseSettingsConfig,
}

impl PleaseConfig {
    pub fn get_owner(&self) -> &str {
        &self.project.owner
    }
    pub fn get_repository(&self) -> &str {
        &self.project.repository
    }
    pub fn get_source(&self) -> &PathBuf {
        &self.project.source
    }
    pub fn get_branch(&self) -> &str {
        &self.project.branch
    }
    pub fn get_api_url(&self) -> &str {
        &self.settings.api_url
    }
    pub fn get_git_username(&self) -> Option<String> {
        self.settings.git_username.clone()
    }
    pub fn get_git_email(&self) -> Option<String> {
        self.settings.git_email.clone()
    }
}

impl Display for PleaseConfig {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        writeln!(f, "PleaseConfig")?;
        writeln!(f, "  owner: {}", self.get_owner())?;
        writeln!(f, "  repository: {}", self.get_repository())?;
        writeln!(f, "  branch: {}", self.get_branch())?;
        writeln!(f, "  api_url: {}", self.get_api_url())?;
        if let Some(git_username) = self.get_git_username() {
            writeln!(f, "  git_username: {}", git_username)?;
        }
        if let Some(git_email) = self.get_git_email() {
            writeln!(f, "  git_email: {}", git_email)?;
        }

        Ok(())
    }
}

#[derive(Clone, Debug, Default)]
pub struct PleaseConfigBuilder {
    stdin: Option<stage0_config::PleaseConfigBuilder>,
    execution_env: Option<stage0_config::PleaseConfigBuilder>,
    cli: Option<stage0_config::PleaseConfigBuilder>,
    config: Option<stage0_config::PleaseConfigBuilder>,
    source: Option<stage0_config::PleaseConfigBuilder>,
}

impl PleaseConfigBuilder {
    pub fn new() -> Self {
        Self {
            ..Default::default()
        }
    }

    pub fn with_stdin(&mut self, stdin: String) -> &mut Self {
        self.stdin = Some(gatheres::get_config_from_stdin::<
            stage0_config::PleaseConfigBuilder,
        >(stdin.as_str()));
        self
    }

    pub fn with_config_file(&mut self, current_dir: &Path) -> &mut Self {
        self.config = Some(gatheres::get_config_from_config_file(current_dir));

        self
    }

    pub fn with_execution_env(&mut self, env_bag: std::env::Vars) -> &mut Self {
        self.execution_env = Some(gatheres::get_from_environment(env_bag));
        self
    }

    pub fn with_cli(&mut self, cli: gatheres::ConfigArgs) -> &mut Self {
        self.cli = Some(cli.into());
        self
    }

    pub fn with_source(&mut self, source: &Path) -> &mut Self {
        self.source = Some(gatheres::get_source(source));

        self
    }

    pub fn build(&mut self) -> anyhow::Result<PleaseConfig> {
        let gathered = vec![
            &self.execution_env,
            &self.source,
            &self.config,
            &self.stdin,
            &self.cli,
        ];

        let final_config = gathered
            .into_iter()
            .flatten()
            .fold(stage0_config::PleaseConfigBuilder::default(), |mut a, x| {
                a.merge(x).clone()
            });

        final_config.try_into()
    }
}