use std::fs;
use std::path::Path;
use color_eyre::{eyre::WrapErr, Result};
use include_dir::{include_dir, Dir, DirEntry};
static EXAMPLE_DIR: Dir = include_dir!("$CARGO_MANIFEST_DIR/example");
pub fn initialize_directory(dir: &Path) -> Result<()> {
if !dir.exists() {
log::info!("The directory does not exist. Creating.");
fs::create_dir_all(dir).wrap_err("Failed to create the project directory.")?;
}
let absolute_target = dir.canonicalize()?;
log::info!(
"Initializing a release notes project in {}",
absolute_target.display()
);
let files = display_files(&EXAMPLE_DIR, &absolute_target);
log::info!("Creating files:\n{}", files);
EXAMPLE_DIR
.extract(dir)
.wrap_err("Failed to copy files to the project directory.")?;
Ok(())
}
fn display_files(dir: &Dir, abs_target: &Path) -> String {
let rel_paths = files_in_entries(dir.entries());
let abs_paths = rel_paths.iter().map(|rel_path| abs_target.join(rel_path));
let strings: Vec<String> = abs_paths
.map(|path| format!("• {}", path.display()))
.collect();
strings.join("\n")
}
fn files_in_entries<'a>(entries: &'a [DirEntry<'a>]) -> Vec<&'a Path> {
let mut results = Vec::new();
for entry in entries {
let mut files = files_in_entry(entry);
results.append(&mut files);
}
results
}
fn files_in_entry<'a>(entry: &'a DirEntry) -> Vec<&'a Path> {
match entry {
DirEntry::File(file) => {
vec![file.path()]
}
DirEntry::Dir(dir) => files_in_entries(dir.entries()),
}
}