anesis 0.12.5

CLI for scaffolding projects from remote templates and extending them with project addons
Documentation
use std::{fs, path::Path};

use anyhow::Result;
use ignore::WalkBuilder;

use crate::templates::TemplateFile;

pub fn copy_dir_respecting_gitignore(source: &Path, dest: &Path) -> Result<()> {
  for entry in WalkBuilder::new(source)
    .hidden(false)
    .require_git(false)
    .filter_entry(|e| e.file_name() != ".git")
    .build()
  {
    let entry = entry?;
    if !entry.file_type().is_some_and(|t| t.is_file()) {
      continue;
    }
    let relative = entry.path().strip_prefix(source)?;
    let out = dest.join(relative);
    if let Some(parent) = out.parent() {
      fs::create_dir_all(parent)?;
    }
    fs::copy(entry.path(), &out)?;
  }
  Ok(())
}

pub fn read_dir_to_files(path: &Path) -> Result<Vec<TemplateFile>> {
  let mut files = Vec::new();
  read_dir_recursive(path, path, &mut files)?;
  Ok(files)
}

pub fn read_dir_recursive(
  base: &Path,
  current: &Path,
  files: &mut Vec<TemplateFile>,
) -> Result<()> {
  for entry in fs::read_dir(current)? {
    let entry = entry?;
    let path = entry.path();
    let file_type = entry.file_type()?;

    if file_type.is_file() {
      let contents = fs::read(&path)?;
      let relative_path = path.strip_prefix(base)?.to_path_buf();
      files.push(TemplateFile {
        path: relative_path,
        contents,
      });
    } else if file_type.is_dir() {
      read_dir_recursive(base, &path, files)?;
    }
  }

  Ok(())
}