extern crate rustache;
use self::rustache::*;
use std::fs;
use std::fs::File;
use std::io::prelude::*;
use std::io::Cursor;
#[cfg(not(target_os = "windows"))]
use std::os::unix::fs::PermissionsExt;
use std::process::*;
pub trait Create {
fn create_dirs(&self, name: &str) -> ();
}
pub fn render_dirs(dirs_pre: Vec<String>, hash: &HashBuilder, name: &str) {
let dirs: Vec<String> = dirs_pre
.into_iter()
.map(|file| {
let mut o = Cursor::new(Vec::new());
hash.render(&file, &mut o).unwrap();
String::from_utf8(o.into_inner()).unwrap()
})
.collect();
dirs.create_dirs(name);
}
pub fn render_files<'a>(files_pre: Vec<String>, hash: &HashBuilder, name: &str) -> VecBuilder<'a> {
let substitutions: Vec<String> = files_pre
.into_iter()
.map(|file| {
let mut o = Cursor::new(Vec::new());
hash.render(&file, &mut o).unwrap();
String::from_utf8(o.into_inner()).unwrap()
})
.collect();
let _ = substitutions
.clone()
.into_iter()
.map(|path| {
let mut full_path = name.to_string();
full_path.push('/');
full_path.push_str(&path);
File::create(full_path)
})
.count();
let s: Vec<Data> = substitutions.into_iter().map(Data::from).collect();
VecBuilder { data: s }
}
impl<T: ToString> Create for Vec<T> {
fn create_dirs(&self, name: &str) {
self.iter()
.map(|dir| {
let mut subdir = name.to_string();
subdir.push('/');
subdir.push_str(&dir.to_string());
fs::create_dir(subdir).unwrap_or(());
})
.count();
}
}
#[cfg(target_os = "windows")]
pub fn render_templates(
project: &str,
name: &str,
hash: &HashBuilder,
templates_pre: Option<Vec<String>>,
executable: bool,
) {
if let Some(t) = templates_pre {
let templates: Vec<String> = t
.into_iter()
.map(|file| {
let mut p = project.to_string();
p.push('/');
p.push_str(&file);
if executable {
p.push_str(".bat");
}
p
})
.collect();
let template_files: Vec<String> = templates
.into_iter()
.map(|p| {
let template_f_pre = File::open(&p);
let mut t = String::new();
let mut template_f = if let Ok(f) = template_f_pre {
f
} else {
eprintln!("Failed to open file: {:?}", p);
exit(0x0f00);
};
template_f
.read_to_string(&mut t)
.expect("File read failed."); t
})
.collect();
let templates_new: Vec<String> = t
.into_iter()
.map(|file| {
let mut p = name.to_string();
p.push('/');
p.push_str(&file);
p
})
.collect();
let templates_named: Vec<String> = templates_new
.into_iter()
.map(|n| {
let mut o = Cursor::new(Vec::new());
hash.render(&n, &mut o).unwrap();
String::from_utf8(o.into_inner()).unwrap()
})
.collect();
let s: Vec<String> = template_files
.into_iter()
.map(|file| {
let mut o = Cursor::new(Vec::new());
hash.render(&file, &mut o).unwrap();
String::from_utf8(o.into_inner()).unwrap()
})
.collect();
let files_to_write = templates_named.iter().zip(s.iter());
let _ = files_to_write
.into_iter()
.map(|(path, contents)| {
let c = File::create(&path);
if let Ok(mut f) = c {
let _ = f.write(contents.as_bytes());
} else {
eprintln!("Failed to create file: {:?}. Check that the directory is included in your template.toml", path);
exit(0x0f01);
};
})
.count();
}
}
#[cfg(not(target_os = "windows"))]
pub fn render_templates(
project: &str,
name: &str,
hash: &HashBuilder,
templates_pre: Option<Vec<String>>,
executable: bool,
) {
if let Some(t) = templates_pre {
let templates: Vec<String> = t
.clone()
.into_iter()
.map(|file| {
let mut p = project.to_string();
p.push('/');
p.push_str(&file);
p
})
.collect();
let template_files: Vec<String> = templates
.into_iter()
.map(|p| {
let template_f_pre = File::open(&p);
let mut t = String::new();
let mut template_f = if let Ok(f) = template_f_pre {
f
} else {
eprintln!("Failed to open file: {:?}", p);
exit(0x0f01);
};
template_f
.read_to_string(&mut t)
.expect("File read failed."); t
})
.collect();
let templates_new: Vec<String> = t
.into_iter()
.map(|file| {
let mut p = name.to_string();
p.push('/');
p.push_str(&file);
p
})
.collect();
let templates_named: Vec<String> = templates_new
.into_iter()
.map(|n| {
let mut o = Cursor::new(Vec::new());
hash.render(&n, &mut o).unwrap();
String::from_utf8(o.into_inner()).unwrap()
})
.collect();
let s: Vec<String> = template_files
.into_iter()
.map(|file| {
let mut o = Cursor::new(Vec::new());
hash.render(&file, &mut o).unwrap();
String::from_utf8(o.into_inner()).unwrap()
})
.collect();
let files_to_write = templates_named.iter().zip(s.iter());
let _ = files_to_write
.map(|(path, contents)| {
let c = File::create(&path);
if let Ok(mut f) = c {
let _ = f.write(contents.as_bytes());
} else {
eprintln!("Failed to create file: {:?}. Check that the directory is included in your template.toml", path);
exit(0x0f01);
};
if executable {
let mut p = fs::metadata(path)
.expect("failed to read file metadata")
.permissions();
p.set_mode(0o755);
let _ = fs::set_permissions(path, p);
};
})
.count();
}
}
pub fn create_file(static_contents: &'static str, name: &str, filename: &str) {
let mut p = name.to_string();
p.push('/');
p.push_str(filename);
let mut c = File::create(p).expect("File creation failed."); let _ = c.write(static_contents.as_bytes());
}
pub fn write_file_plain(static_contents: &'static str, name: &str, filename: &str) {
let mut p = name.to_string();
p.push('/');
p.push_str(filename);
let mut c = File::create(p).expect("File creation failed."); let _ = c.write(static_contents.as_bytes());
}
pub fn render_file(static_template: &'static str, name: &str, filename: &str, hash: &HashBuilder) {
let mut o = Cursor::new(Vec::new());
hash.render(static_template, &mut o).unwrap();
let contents = String::from_utf8(o.into_inner()).unwrap();
let mut p = name.to_string();
p.push('/');
p.push_str(filename);
let c = File::create(&p);
if let Ok(mut f) = c {
let _ = f.write(contents.as_bytes());
} else {
eprintln!(
"Failed to create file: {:?}. Check that the directory is included in your template.toml",
p
);
exit(0x0f01);
}
}