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::path::{Path, PathBuf};

use serde::{de::DeserializeOwned, Deserialize, Serialize};

use crate::stage0_config::PleaseConfigBuilder;

#[derive(Debug, Clone, Serialize, Deserialize)]
struct CuddleEmbeddedPleaseConfig {
    please: PleaseConfigBuilder,
}

impl From<CuddleEmbeddedPleaseConfig> for PleaseConfigBuilder {
    fn from(value: CuddleEmbeddedPleaseConfig) -> Self {
        value.please
    }
}
#[derive(Debug, Clone, Serialize, Deserialize)]
struct CuddlePleaseConfig {
    #[serde(flatten)]
    please: PleaseConfigBuilder,
}
impl From<CuddlePleaseConfig> for PleaseConfigBuilder {
    fn from(value: CuddlePleaseConfig) -> Self {
        value.please
    }
}

const CUDDLE_FILE_NAME: &str = "cuddle";
const CUDDLE_CONFIG_FILE_NAME: &str = "cuddle.please";
const YAML_EXTENSION: &str = "yaml";

pub fn get_config_from_config_file(current_dir: &Path) -> PleaseConfigBuilder {
    let current_cuddle_path = current_dir
        .clone()
        .join(format!("{CUDDLE_FILE_NAME}.{YAML_EXTENSION}"));
    let current_cuddle_config_path = current_dir
        .clone()
        .join(format!("{CUDDLE_CONFIG_FILE_NAME}.{YAML_EXTENSION}"));
    let mut please_config = PleaseConfigBuilder::default();

    if let Some(config) = get_config_from_file::<CuddleEmbeddedPleaseConfig>(current_cuddle_path) {
        please_config = please_config.merge(&config).clone();
    }

    if let Some(config) = get_config_from_file::<CuddlePleaseConfig>(current_cuddle_config_path) {
        please_config = please_config.merge(&config).clone();
    }

    please_config
}

pub fn get_config_from_file<T>(current_cuddle_path: PathBuf) -> Option<PleaseConfigBuilder>
where
    T: DeserializeOwned,
    T: Into<PleaseConfigBuilder>,
{
    match std::fs::File::open(&current_cuddle_path) {
        Ok(file) => match serde_yaml::from_reader::<_, T>(file) {
            Ok(config) => {
                return Some(config.into());
            }
            Err(e) => {
                tracing::debug!(
                    "{} doesn't contain a valid please config: {}",
                    &current_cuddle_path.display(),
                    e
                );
            }
        },
        Err(e) => {
            tracing::debug!(
                "did not find or was not allowed to read {}, error: {}",
                &current_cuddle_path.display(),
                e,
            );
        }
    }

    None
}