mdmg 0.1.6

A scaffold prototype code tool
Documentation
use crate::markdown::parse;
use crate::scaffold_executor::{DryRunScaffoldExecutor, FSScaffoldExecutor, ScaffoldExecutor};
use crate::template::{render, MdmgCtx};
use crate::template_repository::{FSTemplateRepository, TemplateRepository};
use crate::Result;

use std::env::current_dir;
use std::sync::Arc;

pub struct GenerateCommandImpl;

impl GenerateCommandImpl {
    pub fn new() -> Self {
        GenerateCommandImpl
    }
}

trait Dependencies {
    fn template_repository(&self) -> Arc<dyn TemplateRepository>;
}

impl Dependencies for GenerateCommandImpl {
    fn template_repository(&self) -> Arc<dyn TemplateRepository> {
        let current_dir = current_dir().expect("failed fetch current dir");
        Arc::new(FSTemplateRepository::new(current_dir.join(".mdmg")))
    }
}

pub trait GenerateCommand {
    fn run(&self, plan_name: String, component_name: String, dry_run: bool) -> Result<()>;
}

impl GenerateCommand for GenerateCommandImpl {
    fn run(&self, plan_name: String, component_name: String, dry_run: bool) -> Result<()> {
        let template = self.template_repository().resolve(plan_name)?;
        let render_ctx = MdmgCtx::new(component_name);
        if let Ok(scaffolds) = parse(render(template, &render_ctx)?) {
            for scaffold in scaffolds.iter() {
                match dry_run {
                    true => DryRunScaffoldExecutor::new().execute(scaffold)?,
                    false => FSScaffoldExecutor::new().execute(scaffold)?,
                };
            }
        };
        Ok(())
    }
}

#[cfg(not(tarpaulin_include))]
#[cfg(test)]
mod tests {
    use std::fs::{remove_file, write};
    use std::path::Path;

    use super::*;

    fn setup_template() {
        assert!(write(
            ".mdmg/example.md",
            "
          ## test.md

          ```
          hello
          ```
        "
        )
        .is_ok());
    }

    fn terradown_template() {
        let path = Path::new(".mdmg/example.md");

        assert!(remove_file(path).is_ok());
        assert!(remove_file("test.md").is_ok());
    }

    #[test]
    #[cfg_attr(not(feature = "fs-test"), ignore)]
    pub fn generate_command_run_is_file_delete() {
        setup_template();
        let command = GenerateCommandImpl::new();
        let actual = command.run("example".to_string(), "foo".to_string(), false);

        assert!(actual.is_ok());
        terradown_template();
    }
}