use anyhow::{Context, Result, bail};
use std::fs;
use std::path::Path;
const SCAFFOLD_FILES: &[(&str, &str)] = &[
("config.yaml", include_str!("../../scaffold/config.yaml")),
("content/.gitkeep", ""),
("templates/.gitkeep", ""),
("data/.gitkeep", ""),
("static/.gitkeep", ""),
("archives/.gitkeep", ""),
("themes/.gitkeep", ""),
];
pub fn run(target: &Path) -> Result<()> {
if target.exists() {
bail!("path already exists: {}", target.display());
}
fs::create_dir_all(target).with_context(|| format!("creating {}", target.display()))?;
for (rel, contents) in SCAFFOLD_FILES {
let dest = target.join(rel);
if let Some(parent) = dest.parent() {
fs::create_dir_all(parent).with_context(|| format!("creating {}", parent.display()))?;
}
fs::write(&dest, contents).with_context(|| format!("writing {}", dest.display()))?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::Config;
use crate::test_util::temp_path;
#[test]
fn errors_when_target_exists() {
let dir = temp_path("exists");
fs::create_dir_all(&dir).unwrap();
let err = run(&dir).unwrap_err();
assert!(err.to_string().contains("already exists"));
fs::remove_dir_all(&dir).unwrap();
}
#[test]
fn writes_all_scaffold_files() {
let dir = temp_path("writes");
run(&dir).unwrap();
for (rel, _) in SCAFFOLD_FILES {
let path = dir.join(rel);
assert!(path.exists(), "missing {}", path.display());
}
fs::remove_dir_all(&dir).unwrap();
}
#[test]
fn creates_skeleton_dirs() {
let dir = temp_path("skeleton");
run(&dir).unwrap();
assert!(dir.join("config.yaml").exists());
assert!(dir.join("content/.gitkeep").exists());
assert!(dir.join("templates/.gitkeep").exists());
assert!(dir.join("data/.gitkeep").exists());
assert!(dir.join("static/.gitkeep").exists());
assert!(dir.join("archives/.gitkeep").exists());
assert!(dir.join("themes/.gitkeep").exists());
fs::remove_dir_all(&dir).unwrap();
}
#[test]
fn scaffolded_config_loads_as_defaults() {
let dir = temp_path("config-loads");
run(&dir).unwrap();
let (config, site) = Config::load_with_theme(&dir.join("config.yaml")).unwrap();
assert_eq!(config.content_dir, std::path::PathBuf::from("content"));
assert!(config.theme.is_none());
assert!(site.is_empty());
fs::remove_dir_all(&dir).unwrap();
}
}