mdmg/commands/
generate.rs1use crate::markdown::parse;
2use crate::scaffold_executor::{DryRunScaffoldExecutor, FSScaffoldExecutor, ScaffoldExecutor};
3use crate::template::{render, MdmgCtx};
4use crate::template_repository::{FSTemplateRepository, TemplateRepository};
5use crate::Result;
6
7use std::env::current_dir;
8use std::sync::Arc;
9
10pub struct GenerateCommandImpl;
11
12impl GenerateCommandImpl {
13 pub fn new() -> Self {
14 GenerateCommandImpl
15 }
16}
17
18trait Dependencies {
19 fn template_repository(&self) -> Arc<dyn TemplateRepository>;
20}
21
22impl Dependencies for GenerateCommandImpl {
23 fn template_repository(&self) -> Arc<dyn TemplateRepository> {
24 let current_dir = current_dir().expect("failed fetch current dir");
25 Arc::new(FSTemplateRepository::new(current_dir.join(".mdmg")))
26 }
27}
28
29pub trait GenerateCommand {
30 fn run(&self, plan_name: String, component_name: String, dry_run: bool) -> Result<()>;
31}
32
33impl GenerateCommand for GenerateCommandImpl {
34 fn run(&self, plan_name: String, component_name: String, dry_run: bool) -> Result<()> {
35 let template = self.template_repository().resolve(plan_name)?;
36 let render_ctx = MdmgCtx::new(component_name);
37 if let Ok(scaffolds) = parse(render(template, &render_ctx)?) {
38 for scaffold in scaffolds.iter() {
39 match dry_run {
40 true => DryRunScaffoldExecutor::new().execute(scaffold)?,
41 false => FSScaffoldExecutor::new().execute(scaffold)?,
42 };
43 }
44 };
45 Ok(())
46 }
47}
48
49#[cfg(not(tarpaulin_include))]
50#[cfg(test)]
51mod tests {
52 use std::fs::{remove_file, write};
53 use std::path::Path;
54
55 use super::*;
56
57 fn setup_template() {
58 assert!(write(
59 ".mdmg/example.md",
60 "
61 ## test.md
62
63 ```
64 hello
65 ```
66 "
67 )
68 .is_ok());
69 }
70
71 fn terradown_template() {
72 let path = Path::new(".mdmg/example.md");
73
74 assert!(remove_file(path).is_ok());
75 assert!(remove_file("test.md").is_ok());
76 }
77
78 #[test]
79 #[cfg_attr(not(feature = "fs-test"), ignore)]
80 pub fn generate_command_run_is_file_delete() {
81 setup_template();
82 let command = GenerateCommandImpl::new();
83 let actual = command.run("example".to_string(), "foo".to_string(), false);
84
85 assert!(actual.is_ok());
86 terradown_template();
87 }
88}