Move rendering functions to templating mod

main
trivernis 10 months ago
parent 74a09087c2
commit 99deb162b1
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -1,6 +1,6 @@
use globset::{Glob, GlobSet, GlobSetBuilder}; use globset::{Glob, GlobSet, GlobSetBuilder};
use miette::{bail, Context, IntoDiagnostic, Result}; use miette::{bail, Context, IntoDiagnostic, Result};
use serde::Deserialize; use serde::{Deserialize, Serialize};
use std::{ use std::{
env, env,
fs::{self}, fs::{self},
@ -25,10 +25,14 @@ impl SiloRepo {
if !path.try_exists().into_diagnostic()? { if !path.try_exists().into_diagnostic()? {
bail!("The repository {path:?} does not exist"); bail!("The repository {path:?} does not exist");
} }
let config = read_config(path)?;
Ok(Self { Ok(Self {
config: read_config(path)?, root: DirEntry::parse(
root: DirEntry::parse(Rc::new(ParseContext::default()), path.to_owned())?, Rc::new(ParseContext::new(GlobSet::empty(), config.clone())),
path.to_owned(),
)?,
config,
}) })
} }
@ -45,19 +49,12 @@ impl SiloRepo {
pub struct ParseContext { pub struct ParseContext {
ignored: GlobSet, ignored: GlobSet,
config: SiloConfig,
} }
impl ParseContext { impl ParseContext {
pub fn new(ignored: GlobSet) -> Self { pub fn new(ignored: GlobSet, config: SiloConfig) -> Self {
Self { ignored } Self { ignored, config }
}
}
impl Default for ParseContext {
fn default() -> Self {
Self {
ignored: GlobSet::empty(),
}
} }
} }
@ -81,7 +78,7 @@ pub enum DirEntry {
} }
impl DirEntry { impl DirEntry {
fn parse(mut context: Rc<ParseContext>, path: PathBuf) -> Result<Self> { fn parse(mut ctx: Rc<ParseContext>, path: PathBuf) -> Result<Self> {
if path.is_dir() { if path.is_dir() {
log::debug!("Parsing directory {path:?}"); log::debug!("Parsing directory {path:?}");
@ -91,13 +88,20 @@ impl DirEntry {
let metadata = if meta_file.exists() { let metadata = if meta_file.exists() {
log::debug!("Found metadata file"); log::debug!("Found metadata file");
let metadata = RootDirData::read(&meta_file)?; let metadata = RootDirData::read(&meta_file)?;
context = Rc::new(ParseContext::new(metadata.ignored.clone())); ctx = Rc::new(ParseContext::new(
metadata.ignored.clone(),
ctx.config.clone(),
));
Some(metadata) Some(metadata)
} else if meta_tmpl.exists() { } else if meta_tmpl.exists() {
log::debug!("Found metadata template"); log::debug!("Found metadata template");
let metadata = RootDirData::read_template(&meta_tmpl)?; let metadata =
context = Rc::new(ParseContext::new(metadata.ignored.clone())); RootDirData::read_template(&meta_tmpl, &ctx.config.template_context)?;
ctx = Rc::new(ParseContext::new(
metadata.ignored.clone(),
ctx.config.clone(),
));
Some(metadata) Some(metadata)
} else { } else {
@ -112,8 +116,8 @@ impl DirEntry {
let entry_path = read_entry.path(); let entry_path = read_entry.path();
let test_path = entry_path.strip_prefix(&path).into_diagnostic()?; let test_path = entry_path.strip_prefix(&path).into_diagnostic()?;
if !IGNORED_PATHS.is_match(&test_path) && !context.ignored.is_match(&test_path) { if !IGNORED_PATHS.is_match(&test_path) && !ctx.ignored.is_match(&test_path) {
children.push(DirEntry::parse(context.clone(), entry_path)?); children.push(DirEntry::parse(ctx.clone(), entry_path)?);
} else { } else {
log::debug!("Entry {entry_path:?} is ignored") log::debug!("Entry {entry_path:?} is ignored")
} }
@ -152,14 +156,7 @@ impl DirEntry {
Ok(()) Ok(())
} }
DirEntry::Root(_, data, children) => { DirEntry::Root(_, data, children) => {
let engine = templating::engine(); let rendered_path = templating::render(&data.path, &ctx.config.template_context)?;
let rendered_path = engine
.render_template(
&data.path,
&templating::context(&ctx.config.template_context),
)
.into_diagnostic()
.with_context(|| format!("render template {}", data.path))?;
let cwd = PathBuf::from(rendered_path); let cwd = PathBuf::from(rendered_path);
@ -201,22 +198,12 @@ impl FileEntry {
log::debug!("Processing template {path:?}"); log::debug!("Processing template {path:?}");
let contents = fs::read_to_string(path).into_diagnostic()?; let contents = fs::read_to_string(path).into_diagnostic()?;
let rendered = templating::engine()
.render_template(
&contents,
&templating::context(&ctx.config.template_context),
)
.into_diagnostic()
.with_context(|| format!("rendering template {path:?}"))?;
let new_path = path.with_extension(""); let new_path = path.with_extension("");
let filename = new_path.file_name().unwrap(); let filename = new_path.file_name().unwrap();
let dest = cwd.join(filename); let dest = cwd.join(filename);
log::info!("Writing {path:?} -> {dest:?}");
fs::write(&dest, rendered) templating::render_to_file(&dest, &contents, &ctx.config.template_context)?;
.into_diagnostic() log::info!("Render {path:?} -> {dest:?}");
.with_context(|| format!("write to destination {dest:?}"))?;
} }
FileEntry::Plain(path) => { FileEntry::Plain(path) => {
let filename = path.file_name().unwrap(); let filename = path.file_name().unwrap();
@ -250,14 +237,11 @@ impl RootDirData {
.with_context(|| format!("parsing metadata file {path:?}")) .with_context(|| format!("parsing metadata file {path:?}"))
} }
fn read_template(path: &Path) -> Result<Self> { fn read_template<T: Serialize>(path: &Path, ctx: T) -> Result<Self> {
let contents = fs::read_to_string(path) let contents = fs::read_to_string(path)
.into_diagnostic() .into_diagnostic()
.with_context(|| format!("reading metadata file {path:?}"))?; .with_context(|| format!("reading metadata file {path:?}"))?;
let rendered = templating::engine() let rendered = templating::render(&contents, ctx)?;
.render_template(&contents, &templating::context(()))
.into_diagnostic()
.with_context(|| format!("processing template {path:?}"))?;
toml::from_str(&rendered) toml::from_str(&rendered)
.into_diagnostic() .into_diagnostic()
.with_context(|| format!("parsing metadata file {path:?}")) .with_context(|| format!("parsing metadata file {path:?}"))

@ -1,11 +1,36 @@
use std::{env, path::PathBuf}; use std::{
env,
fs::File,
io::BufWriter,
path::{Path, PathBuf},
};
use handlebars::Handlebars; use handlebars::Handlebars;
use handlebars_switch::SwitchHelper; use handlebars_switch::SwitchHelper;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use miette::{Context, IntoDiagnostic, Result};
use serde::Serialize; use serde::Serialize;
pub fn engine<'a>() -> Handlebars<'a> { pub fn render_to_file<T: Serialize>(path: &Path, template: &str, ctx: T) -> Result<()> {
let file = File::create(path)
.into_diagnostic()
.context("creating file")?;
let writer = BufWriter::new(file);
engine()
.render_template_to_write(template, &context(ctx), writer)
.into_diagnostic()
.context("rendering to path")?;
Ok(())
}
pub fn render<T: Serialize>(template: &str, ctx: T) -> Result<String> {
engine()
.render_template(template, &context(ctx))
.into_diagnostic()
.context("rendering to path")
}
fn engine<'a>() -> Handlebars<'a> {
let mut hb = Handlebars::new(); let mut hb = Handlebars::new();
hb.register_helper("switch", Box::new(SwitchHelper)); hb.register_helper("switch", Box::new(SwitchHelper));
hb hb

Loading…
Cancel
Save