cargo-actions 0.3.4

cargo, create a CI github action
Documentation
use crate::{info, success};
use actions_templates::ActionConfig;
use anyhow::anyhow;
use dialogue_macro::Asker;
use std::{
    env::current_dir,
    fmt::Display,
    ops::Deref,
    path::{Path, PathBuf},
};

#[derive(Debug, Clone)]
pub struct PathConfig(pub ActionConfig);

impl Deref for PathConfig {
    type Target = ActionConfig;
    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Display for PathConfig {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}", self.0.config.name)
    }
}

pub struct PathConfigs {
    pub inner: Vec<PathConfig>,
}

impl Deref for PathConfigs {
    type Target = Vec<PathConfig>;
    fn deref(&self) -> &Self::Target {
        &self.inner
    }
}

impl PathConfigs {
    pub fn from(paths: &[PathBuf]) -> anyhow::Result<Self> {
        let mut configs = vec![];
        for path in paths {
            let config = ActionConfig::from_dir(path)?;
            configs.push(config);
        }
        let path_configs = configs.into_iter().map(PathConfig).collect::<Vec<_>>();
        Ok(Self {
            inner: path_configs,
        })
    }
}

#[derive(Debug, Clone, Asker)]
pub struct SelectPathConfig {
    #[select(with_default = true, prompt = "请选择actions template")]
    pub action_config: PathConfig,
}

#[derive(Debug, Clone, Asker)]
pub struct WritePath {
    #[input(with_default = true, prompt = "请输入写入路径:")]
    pub write_path: String,
}

impl AsRef<str> for WritePath {
    fn as_ref(&self) -> &str {
        self.write_path.as_ref()
    }
}

impl WritePath {
    pub fn input_and_confirm<P: Into<String>>(default_write_path: P) -> anyhow::Result<PathBuf> {
        let write_path = WritePath::asker()
            .write_path(default_write_path.into())
            .finish();
        let path = Path::new(write_path.as_ref());
        if path.exists() {
            let ConfirmWrite { confirm } = ConfirmWrite::asker().confirm().finish();
            if confirm {
                Ok(path.to_path_buf())
            } else {
                Err(anyhow!("您已经取消写入"))
            }
        } else {
            std::fs::create_dir_all(path.parent().unwrap())?;
            Ok(path.to_path_buf())
        }
    }
}

#[derive(Debug, Clone, Asker)]
pub struct ConfirmWrite {
    #[confirm(with_default = false, prompt = "该路径以及存在,是否继续写入?")]
    pub confirm: bool,
}

impl SelectPathConfig {
    pub fn write_template(&self) -> anyhow::Result<()> {
        let default_write_path = current_dir()?
            .join(".github/workflows")
            .join(format!("{}.yaml", self.action_config.config.name))
            .to_string_lossy()
            .to_string();
        info!(
            "⚙️ Action description: {}",
            self.action_config.config.description.as_ref().unwrap()
        );
        let write_path = WritePath::input_and_confirm(default_write_path)?;
        self.action_config.write_template(write_path)?;

        success!("write success");

        if self.action_config.config.success_message.is_some() {
            info!(
                "{}",
                self.action_config.config.success_message.as_ref().unwrap()
            );
        }

        Ok(())
    }
}