use std::{ env, fs::{self, File}, io::{self, Write}, path::{Path, PathBuf}, process, str::EscapeDefault, }; const GITIGNORE_DIR: &str = "gitignore"; fn main() { let mut d = PathBuf::from(env!("CARGO_MANIFEST_DIR")); d.push(GITIGNORE_DIR); let mut path_vec = Vec::new(); visit_dirs(&d, &mut path_vec).expect("Could not navigate templates directory."); if path_vec.is_empty() { eprintln!( "Could not get any templates. \ Please open an issue at \ https://github.com/DavSanchez/gib/issues/new" ); process::exit(1); } let out_dir = env::var("OUT_DIR").expect("OUT_DIR variable not defined."); let dest_path = Path::new(&out_dir).join("gitignore_data.rs"); let mut gitignore_data = File::create(&dest_path).unwrap(); writeln!(&mut gitignore_data, r#"["#,).unwrap(); for path in path_vec { let (filename, filepath) = match extract_escaped_filename(&path) { Some((filename, filepath)) => (filename, filepath), None => continue, }; writeln!( &mut gitignore_data, r###"("{}", ("{}", include_bytes!("{}"))),"###, filename.to_lowercase(), filename, filepath, ).unwrap(); } writeln!(&mut gitignore_data, r#"]"#,).unwrap(); println!("cargo:rerun-if-changed=build.rs"); } fn extract_escaped_filename(path: &PathBuf) -> Option<(&str, EscapeDefault)> { let filename = path.file_stem()?.to_str()?; let filepath = path.to_str()?; Some((filename, filepath.escape_default())) } fn visit_dirs(dir: &Path, path_vec: &mut Vec) -> io::Result<()> { if dir.is_dir() { for entry in fs::read_dir(dir)? { let entry = entry?; let path = entry.path(); if path.is_dir() { visit_dirs(&path, path_vec)?; } else { match path.extension() { Some(ext) => { if ext == "gitignore" { path_vec.push(path) } } None => continue, } } } } Ok(()) }