proplate_core/gen/
bootstrap.rs1use std::{collections::HashMap, fs, path::Path};
2
3use crate::{
4 fs as pfs,
5 template::{config::analyze_dyn_files, interpolation::Interpolate, op::Execute, Template},
6};
7
8use proplate_errors::{ProplateError, ProplateErrorKind, ProplateResult};
9use proplate_tui::logger;
10
11pub type Context = HashMap<String, String>;
13
14pub fn bootstrap(template: &mut Template, dest: &str, ctx: &Context) -> ProplateResult<()> {
16 (|| -> ProplateResult<()> {
17 process_template(template, ctx)?;
18 prepare_dest(dest)?;
19 copy_files(template, dest)?;
20 cleanup(template)?;
21 Ok(())
22 })()
23 .map_err(|e| -> ProplateError {
24 if let Err(_) = cleanup(template) {
25 logger::warn("Unable to cleanup");
26 }
27 e
28 })
29}
30
31pub fn process_template(template: &mut Template, ctx: &Context) -> ProplateResult<()> {
33 println!("{}", logger::step("Running additional operations..."));
34
35 for op in &template.conf.additional_operations {
38 op.execute(&ctx)?;
39 }
40
41 println!(
42 "{}",
43 logger::step("Verifying whether analysis of dyn files is necessary...")
44 );
45 if template.conf.require_dyn_file_analysis {
46 analyze_dyn_files(&mut template.conf, &template.base_path);
47 }
48
49 println!("{}", logger::step("Binding ctx to dynamic_files..."));
50
51 for filepath in &template.conf.dynamic_files {
52 println!(" {}", logger::step(&format!("processing...")));
53 bind_ctx_to_file(Path::new(&filepath), ctx);
54 }
55
56 Ok(())
57}
58
59pub fn bind_ctx_to_file(path: &Path, ctx: &Context) {
61 match pfs::map_file(path, |s| s.to_string().interpolate(ctx)) {
62 Err(_) => {
63 }
65 _ => (),
66 }
67}
68
69fn prepare_dest(dest: &str) -> ProplateResult<()> {
71 println!("{}", logger::title("Finalizing"));
72 fs::create_dir_all(dest).map_err(|e| {
73 ProplateError::create(ProplateErrorKind::Fs {
74 concerned_paths: vec![dest.into()],
75 operation: "create_dir_all".into(),
76 })
77 .with_ctx("gen:bootstrap:prepare")
78 .with_cause(&e.to_string())
79 })?;
80 Ok(())
81}
82
83pub fn copy_files(template: &Template, dest: &str) -> ProplateResult<()> {
86 let src = &template.base_path;
87 let dest = Path::new(dest);
88
89 println!("{}", logger::step("Copying..."));
90
91 pfs::copy_fdir(
92 src,
93 dest,
94 Some(
95 template
96 .conf
97 .exclude
98 .iter()
99 .map(|s| s.into())
100 .collect::<Vec<_>>(),
101 ),
102 )
103 .map_err(|e| {
104 ProplateError::create(ProplateErrorKind::Fs {
105 concerned_paths: vec![src.display().to_string(), dest.display().to_string()],
106 operation: "copy_fdir".into(),
107 })
108 .with_ctx("gen:bootstrap:copy_files")
109 .with_cause(&e.to_string())
110 })
111}
112
113pub fn cleanup(template: &Template) -> ProplateResult<()> {
114 println!("{}", logger::step("cleaning up..."));
115 fs::remove_dir_all(&template.base_path).map_err(|e| {
116 ProplateError::create(ProplateErrorKind::Fs {
117 concerned_paths: vec![template.base_path.display().to_string()],
118 operation: "remove_dir_all".into(),
119 })
120 .with_ctx("gen:bootstrap:cleanup")
121 .with_cause(&e.to_string())
122 })?;
123 Ok(())
124}