1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
use std::env; use std::fs; use std::path::PathBuf; use std::process::Command; use tinytemplate::TinyTemplate; use crate::config::{Context, Dependencies}; fn build_template() -> String { fs::read_to_string( PathBuf::from("src") .join("templates") .join("elixir") .join("mix.exs.tmpl"), ) .unwrap() } fn source_template() -> String { fs::read_to_string( PathBuf::from("src") .join("templates") .join("elixir") .join("parser.ex.tmpl"), ) .unwrap() } fn generate_templates(deps: Dependencies) -> Vec<(&'static str, String)> { let build = build_template(); let source = source_template(); let mut template = TinyTemplate::new(); template.add_template("mix.exs", &build).unwrap(); template.add_template("parser.ex", &source).unwrap(); let build_template = template .render("mix.exs", &Context { deps: deps.clone() }) .unwrap(); let source_template = template .render("parser.ex", &Context { deps }) .unwrap(); let mut templates = Vec::new(); templates.push(("mix.exs", build_template)); templates.push(("lib/parser.ex", source_template)); templates } pub fn write_project(path: String, deps: Dependencies) -> Result<(), String> { println!("Generating mix project..."); let folder_path = PathBuf::from(path); let templates = generate_templates(deps.clone()); let (build_path, build_template) = templates.get(0).unwrap(); let (source_path, source_template) = templates.get(1).unwrap(); fs::create_dir_all(folder_path.clone()) .map_err(|err| format!("Failed to create dir: {}", err)) .and_then(|_| { env::set_current_dir(folder_path.clone()) .map_err(|err| format!("Failed to set cwd: {}", err)) }) .and_then(|_| { fs::write(build_path, build_template) .map_err(|err| format!("Failed to write `mix.exs`: {}", err)) }) .and_then(|_| { fs::create_dir(PathBuf::from("lib")) .map_err(|err| format!("Failed to create `lib` dir: {}", err)) }) .and_then(|_| { fs::write(source_path, source_template) .map_err(|err| format!("Failed to write `lib/parser.ex`: {}", err)) }) } pub fn run(shell: bool) -> Result<(), String> { let stdout = os_pipe::dup_stdout().unwrap(); let mut mix = match Command::new("mix") .args(&["do", "deps.get,", "deps.compile"]) .stdout(stdout) .spawn() { Err(error) => panic!("Failed to spawn `mix` process: {}", error), Ok(process) => process, }; let _ = mix.wait(); if shell { let stdout = os_pipe::dup_stdout().unwrap(); let mut iex_command = match Command::new("iex") .args(&["-S", "mix"]) .stdout(stdout) .stdin(os_pipe::dup_stdin().unwrap()) .spawn() { Err(error) => panic!("Failed to run `iex` shell: {}", error), Ok(process) => process, }; let _ = iex_command.wait(); } Ok(()) }