Add full config to hook and template context

main
trivernis 8 months ago
parent 844de492bb
commit 16cbbdf62b
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS.
GPG Key ID: 7E6D18B61C8D2F4B

@ -15,15 +15,16 @@ use crate::{scripting::create_lua, utils::Describe};
pub struct SiloConfig { pub struct SiloConfig {
/// Diff tool used to display file differences /// Diff tool used to display file differences
pub diff_tool: String, pub diff_tool: String,
/// Context values for handlebars that are available globally under the `ctx` variable /// Additional config options
pub template_context: HashMap<String, toml::Value>, #[serde(flatten)]
pub userdata: HashMap<String, toml::Value>,
} }
impl Default for SiloConfig { impl Default for SiloConfig {
fn default() -> Self { fn default() -> Self {
Self { Self {
diff_tool: detect_difftool(), diff_tool: detect_difftool(),
template_context: HashMap::new(), userdata: HashMap::new(),
} }
} }
} }
@ -50,7 +51,7 @@ pub fn read_config(repo: &Path) -> Result<SiloConfig> {
let mut lines = vec![ let mut lines = vec![
"local silo = require 'silo'".to_owned(), "local silo = require 'silo'".to_owned(),
"local utils = require 'utils'".to_owned(), "local utils = require 'utils'".to_owned(),
"local config = silo.config".to_owned(), "local config = silo.default_config".to_owned(),
]; ];
if old_config.exists() { if old_config.exists() {
lines.push("".to_owned()); lines.push("".to_owned());
@ -86,7 +87,7 @@ pub fn read_config(repo: &Path) -> Result<SiloConfig> {
} }
fn read_lua_config(path: &Path) -> Result<SiloConfig> { fn read_lua_config(path: &Path) -> Result<SiloConfig> {
let lua = create_lua(&())?; let lua = create_lua(&SiloConfig::default())?;
let result = lua let result = lua
.load(path) .load(path)
.eval() .eval()

@ -26,7 +26,7 @@ fn main() -> Result<()> {
let repo = SiloRepo::open(&args.repo)?; let repo = SiloRepo::open(&args.repo)?;
println!( println!(
"{}", "{}",
serde_json::to_string_pretty(&templating::context(repo.config.template_context)) serde_json::to_string_pretty(&templating::context(repo.config.userdata))
.into_diagnostic()? .into_diagnostic()?
) )
} }

@ -4,14 +4,14 @@ use std::{
rc::Rc, rc::Rc,
}; };
use crate::{scripting::create_lua, templating, utils::Describe}; use crate::{config::SiloConfig, scripting::create_lua, templating, utils::Describe};
use super::{ApplyContext, ParseContext, ReadMode}; use super::{ApplyContext, ParseContext, ReadMode};
use globset::{Glob, GlobSet, GlobSetBuilder}; use globset::{Glob, GlobSet, GlobSetBuilder};
use lazy_static::lazy_static; use lazy_static::lazy_static;
use miette::{Context, IntoDiagnostic, Result}; use miette::{Context, IntoDiagnostic, Result};
use mlua::LuaSerdeExt; use mlua::LuaSerdeExt;
use serde::{Deserialize, Serialize}; use serde::Deserialize;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Contents { pub struct Contents {
@ -56,7 +56,7 @@ impl DirEntry {
let metadata = if script_tmpl.exists() { let metadata = if script_tmpl.exists() {
log::debug!("Found script template"); log::debug!("Found script template");
let metadata = RootDirData::read_lua(&script_tmpl, &ctx.config.template_context)?; let metadata = RootDirData::read_lua(&script_tmpl, &ctx.config)?;
ctx = Rc::new(ParseContext::new( ctx = Rc::new(ParseContext::new(
path.clone(), path.clone(),
metadata.read_mode(), metadata.read_mode(),
@ -78,8 +78,7 @@ impl DirEntry {
} else if meta_tmpl.exists() { } else if meta_tmpl.exists() {
log::debug!("Found metadata template"); log::debug!("Found metadata template");
log::warn!("Old template metadata files are deprecated. Please migrate to the `silo.dir.lua` syntax"); log::warn!("Old template metadata files are deprecated. Please migrate to the `silo.dir.lua` syntax");
let metadata = let metadata = RootDirData::read_template(&meta_tmpl, &ctx.config)?;
RootDirData::read_template(&meta_tmpl, &ctx.config.template_context)?;
ctx = Rc::new(ParseContext::new( ctx = Rc::new(ParseContext::new(
path.clone(), path.clone(),
metadata.read_mode(), metadata.read_mode(),
@ -132,7 +131,7 @@ impl DirEntry {
Ok(()) Ok(())
} }
DirEntry::Root(_, data, children) => { DirEntry::Root(_, data, children) => {
let rendered_path = templating::render(&data.path, &ctx.config.template_context)?; let rendered_path = templating::render(&data.path, &ctx.config)?;
let cwd = PathBuf::from(rendered_path); let cwd = PathBuf::from(rendered_path);
for child in children { for child in children {
@ -171,7 +170,7 @@ impl FileEntry {
let filename = new_path.file_name().unwrap(); let filename = new_path.file_name().unwrap();
let dest = cwd.join(filename); let dest = cwd.join(filename);
let render_contents = templating::render(&contents, &ctx.config.template_context)?; let render_contents = templating::render(&contents, &ctx.config.userdata)?;
ctx.fs.write_all(&dest, &render_contents.into_bytes())?; ctx.fs.write_all(&dest, &render_contents.into_bytes())?;
ctx.fs ctx.fs
@ -223,18 +222,18 @@ impl RootDirData {
.with_context(|| format!("parsing metadata file {path:?}")) .with_context(|| format!("parsing metadata file {path:?}"))
} }
fn read_template<T: Serialize>(path: &Path, ctx: T) -> Result<Self> { fn read_template(path: &Path, cfg: &SiloConfig) -> 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::render(&contents, ctx)?; let rendered = templating::render(&contents, cfg)?;
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:?}"))
} }
fn read_lua<T: Serialize>(path: &Path, ctx: T) -> Result<Self> { fn read_lua(path: &Path, cfg: &SiloConfig) -> Result<Self> {
let lua = create_lua(&ctx)?; let lua = create_lua(&cfg)?;
let cfg: Self = lua let cfg: Self = lua
.from_value(lua.load(path).eval().describe("evaluating script")?) .from_value(lua.load(path).eval().describe("evaluating script")?)
.describe("deserialize lua value")?; .describe("deserialize lua value")?;

@ -8,7 +8,7 @@ use std::{
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use crate::{scripting::create_lua, utils::Describe}; use crate::{config::SiloConfig, scripting::create_lua, utils::Describe};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Hooks { pub struct Hooks {
@ -46,7 +46,7 @@ impl Hooks {
} }
} }
pub fn load(path: &Path) -> Result<Self> { pub fn load(config: &SiloConfig, path: &Path) -> Result<Self> {
log::debug!("Parsing hooks in {path:?}"); log::debug!("Parsing hooks in {path:?}");
let readdir = fs::read_dir(path).into_diagnostic()?; let readdir = fs::read_dir(path).into_diagnostic()?;
let mut scripts = Vec::new(); let mut scripts = Vec::new();
@ -60,7 +60,7 @@ impl Hooks {
.is_some_and(|f| f.to_string_lossy().ends_with(".hook.lua")) .is_some_and(|f| f.to_string_lossy().ends_with(".hook.lua"))
{ {
log::debug!("Found hook {path:?}"); log::debug!("Found hook {path:?}");
scripts.push(Arc::new(HookScript::load(&path)?)) scripts.push(Arc::new(HookScript::load(config, &path)?))
} }
} }
@ -107,8 +107,8 @@ impl Hooks {
} }
impl HookScript { impl HookScript {
pub fn load(path: &Path) -> Result<Self> { pub fn load(config: &SiloConfig, path: &Path) -> Result<Self> {
let lua = create_lua(&())?; let lua = create_lua(&config)?;
let module: OwnedTable = lua let module: OwnedTable = lua
.load(path) .load(path)
.eval() .eval()

@ -43,7 +43,7 @@ impl SiloRepo {
let hook_path = path.join("hooks"); let hook_path = path.join("hooks");
let hooks = if hook_path.exists() { let hooks = if hook_path.exists() {
Hooks::load(&hook_path)? Hooks::load(&config, &hook_path)?
} else { } else {
Hooks::empty() Hooks::empty()
}; };

@ -5,19 +5,19 @@ pub mod utils_module;
use miette::Result; use miette::Result;
use mlua::{Lua, LuaSerdeExt}; use mlua::{Lua, LuaSerdeExt};
use serde::Serialize;
use crate::utils::Describe; use crate::{config::SiloConfig, utils::Describe};
pub fn create_lua<T: Serialize>(ctx: &T) -> Result<Lua> { pub fn create_lua(config: &SiloConfig) -> Result<Lua> {
let lua = Lua::new(); let lua = Lua::new();
{ {
let globals = lua.globals(); let globals = lua.globals();
require::register_require(&lua).describe("registering custom require")?; require::register_require(&lua).describe("registering custom require")?;
globals globals
.set( .set(
"silo_ctx", "__silo_config",
lua.to_value(ctx).describe("serializing context to lua")?, lua.to_value(config)
.describe("serializing context to lua")?,
) )
.describe("registering silo context")?; .describe("registering silo context")?;
} }

@ -9,8 +9,9 @@ pub fn silo_module(lua: &Lua) -> Result<Table> {
exports.set("dirs", lua.to_value(&silo_ctx.dirs)?)?; exports.set("dirs", lua.to_value(&silo_ctx.dirs)?)?;
exports.set("flags", lua.to_value(&silo_ctx.flags)?)?; exports.set("flags", lua.to_value(&silo_ctx.flags)?)?;
exports.set("system", lua.to_value(&silo_ctx.system)?)?; exports.set("system", lua.to_value(&silo_ctx.system)?)?;
exports.set("usercfg", lua.globals().get::<_, mlua::Value>("silo_ctx")?)?; let config = lua.globals().get::<_, mlua::Value>("__silo_config")?;
exports.set("config", lua.to_value(&SiloConfig::default())?)?; exports.set("config", config)?;
exports.set("default_config", lua.to_value(&SiloConfig::default())?)?;
Ok(exports) Ok(exports)
} }

@ -7,7 +7,7 @@ use miette::{Context, IntoDiagnostic, Result};
use serde::Serialize; use serde::Serialize;
mod helpers; mod helpers;
pub fn render<T: Serialize>(template: &str, ctx: T) -> Result<String> { pub fn render<T: Serialize + Clone>(template: &str, ctx: T) -> Result<String> {
engine() engine()
.render_template(template, &context(ctx)) .render_template(template, &context(ctx))
.into_diagnostic() .into_diagnostic()
@ -28,11 +28,15 @@ fn engine<'a>() -> Handlebars<'a> {
hb hb
} }
pub fn context<'a, T: Serialize>(ctx: T) -> WrappedContext<'a, T> { pub fn context<'a, T: Serialize + Clone>(cfg: T) -> WrappedContext<'a, T> {
lazy_static! { lazy_static! {
static ref CTX: ContextData = ContextData::default(); static ref CTX: ContextData = ContextData::default();
} }
WrappedContext { data: &CTX, ctx } WrappedContext {
data: &CTX,
ctx: cfg.clone(),
cfg,
}
} }
#[derive(Serialize)] #[derive(Serialize)]
@ -40,6 +44,7 @@ pub struct WrappedContext<'a, T: Serialize> {
#[serde(flatten)] #[serde(flatten)]
data: &'a ContextData, data: &'a ContextData,
ctx: T, ctx: T,
cfg: T,
} }
#[derive(Clone, Debug, Serialize, Default)] #[derive(Clone, Debug, Serialize, Default)]

Loading…
Cancel
Save