#![allow(clippy::unwrap_used, clippy::expect_used)]
use anyhow::Result;
use ssg::cache::BuildCache;
use ssg::livereload::LiveReloadPlugin;
use ssg::plugin::{PluginContext, PluginManager};
use ssg::plugins::MinifyPlugin;
use ssg::postprocess::{HtmlFixPlugin, ManifestFixPlugin};
use ssg::search::SearchPlugin;
use ssg::seo::{CanonicalPlugin, RobotsPlugin, SeoPlugin};
use staticdatagen::compiler::service::compile;
use std::fs;
use std::path::Path;
fn main() -> Result<()> {
let build_dir = Path::new("./examples/plugins/build");
let site_dir = Path::new("./examples/plugins/public");
let content_dir = Path::new("./examples/plugins/content");
let template_dir = Path::new("./examples/templates");
let cache_dir = Path::new("target/.ssg-cache");
fs::create_dir_all(cache_dir)?;
let cache_path = &cache_dir.join("plugins.json");
fs::create_dir_all(build_dir)?;
fs::create_dir_all(site_dir)?;
let mut cache = BuildCache::load(cache_path)?;
let changed = cache.changed_files(content_dir)?;
let output_missing = !site_dir.join("index.html").exists();
if changed.is_empty() && !output_missing {
println!(" ✅ No content changes detected — skipping build");
} else {
if output_missing && changed.is_empty() {
println!(" 🔨 Output missing — forcing rebuild");
}
println!(" 🔨 {} file(s) changed — rebuilding", changed.len());
for path in &changed {
println!(" ↳ {}", path.display());
}
match compile(build_dir, content_dir, site_dir, template_dir) {
Ok(()) => println!(" ✅ Site compiled successfully"),
Err(e) => {
println!(" ❌ Compilation error: {e:?}");
return Ok(());
}
}
cache.update(content_dir)?;
cache.save()?;
println!(" 💾 Build cache updated ({} entries)", cache.len());
}
let base_url = "https://example.com";
let mut plugins = PluginManager::new();
plugins.register(HtmlFixPlugin);
plugins.register(ManifestFixPlugin);
plugins.register(SeoPlugin);
plugins.register(CanonicalPlugin::new(base_url));
plugins.register(RobotsPlugin::new(base_url));
plugins.register(SearchPlugin);
plugins.register(MinifyPlugin);
plugins.register(LiveReloadPlugin::new());
let ctx =
PluginContext::new(content_dir, build_dir, site_dir, template_dir);
println!("\n 🔌 Running {} plugins:", plugins.len());
for name in plugins.names() {
println!(" ↳ {name}");
}
plugins.run_before_compile(&ctx)?;
plugins.run_after_compile(&ctx)?;
plugins.run_on_serve(&ctx)?;
println!("\n ✅ Plugin pipeline complete");
let index_path = site_dir.join("search-index.json");
if index_path.exists() {
let size = fs::metadata(&index_path)?.len();
println!(" 🔍 Search index: {size} bytes");
}
let robots_path = site_dir.join("robots.txt");
if robots_path.exists() {
println!(" 🤖 robots.txt generated");
}
println!("\n Done. Site ready at {}", site_dir.display());
Ok(())
}