From 00131016230b23614666bf5cf74f133b8039f68f Mon Sep 17 00:00:00 2001 From: Olivier 'reivilibre Date: Fri, 24 Oct 2025 15:43:17 +0100 Subject: [PATCH] cli: templates check: allow rendering to --out-dir --- crates/cli/src/commands/templates.rs | 45 ++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/crates/cli/src/commands/templates.rs b/crates/cli/src/commands/templates.rs index 111f19682..b7503cc15 100644 --- a/crates/cli/src/commands/templates.rs +++ b/crates/cli/src/commands/templates.rs @@ -6,6 +6,8 @@ use std::process::ExitCode; +use anyhow::{Context as _, bail}; +use camino::Utf8PathBuf; use clap::Parser; use figment::Figment; use mas_config::{ @@ -27,14 +29,19 @@ pub(super) struct Options { #[derive(Parser, Debug)] enum Subcommand { /// Check that the templates specified in the config are valid - Check, + Check { + /// If set, templates will be rendered to this directory. + /// The directory must either not exist or be empty. + #[arg(long = "out-dir")] + out_dir: Option, + }, } impl Options { pub async fn run(self, figment: &Figment) -> anyhow::Result { use Subcommand as SC; match self.subcommand { - SC::Check => { + SC::Check { out_dir } => { let _span = info_span!("cli.templates.check").entered(); let template_config = TemplatesConfig::extract_or_default(figment) @@ -67,7 +74,39 @@ impl Options { )?; let templates = templates_from_config(&template_config, &site_config, &url_builder).await?; - templates.check_render(clock.now(), &mut rng)?; + let all_renders = templates.check_render(clock.now(), &mut rng)?; + + if let Some(out_dir) = out_dir { + // Save renders to disk. + if out_dir.exists() { + let mut read_dir = + tokio::fs::read_dir(&out_dir).await.with_context(|| { + format!("could not read {out_dir} to check it's empty") + })?; + while let Some(x) = read_dir.next_entry().await? { + bail!("Render directory {out_dir} is not empty, refusing to write."); + } + } else { + tokio::fs::create_dir(&out_dir) + .await + .with_context(|| format!("could not create {out_dir}"))?; + } + + for (template, template_renders) in &all_renders { + let template_filename_base = + template.trim_end_matches(".html").replace('/', "_"); + for (idx, render) in template_renders.iter().enumerate() { + let render_path = + out_dir.join(format!("{template_filename_base}-sample{idx}.html")); + + tokio::fs::write(&render_path, render.as_bytes()) + .await + .with_context(|| { + format!("could not write render to {render_path}") + })?; + } + } + } Ok(ExitCode::SUCCESS) }