Replace nushell hooks with lua hooks

main
trivernis 9 months ago
parent e1e7280241
commit 844de492bb
Signed by: Trivernis
GPG Key ID: 7E6D18B61C8D2F4B

2310
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -15,7 +15,6 @@ chksum = "0.3.0"
clap = { version = "4.4.17", features = ["derive", "env"] } clap = { version = "4.4.17", features = ["derive", "env"] }
dialoguer = "0.11.0" dialoguer = "0.11.0"
dirs = "5.0.1" dirs = "5.0.1"
embed-nu = "0.9.1"
figment = { version = "0.10.13", features = ["toml", "env"] } figment = { version = "0.10.13", features = ["toml", "env"] }
gix = { version = "0.57.1", default-features = false, features = ["basic", "index", "worktree-mutation", "revision", "blocking-network-client", "prodash", "blocking-http-transport-reqwest-rust-tls"] } gix = { version = "0.57.1", default-features = false, features = ["basic", "index", "worktree-mutation", "revision", "blocking-network-client", "prodash", "blocking-http-transport-reqwest-rust-tls"] }
globset = { version = "0.4.14", features = ["serde", "serde1"] } globset = { version = "0.4.14", features = ["serde", "serde1"] }
@ -25,7 +24,7 @@ lazy_static = "1.4.0"
log = "0.4.20" log = "0.4.20"
merge-struct = "0.1.0" merge-struct = "0.1.0"
miette = { version = "5.10.0", features = ["serde", "fancy"] } miette = { version = "5.10.0", features = ["serde", "fancy"] }
mlua = { version = "0.9.6", features = ["serialize", "luau", "vendored"] } mlua = { version = "0.9.6", features = ["serialize", "luau", "vendored", "unstable"] }
pretty_env_logger = "0.5.0" pretty_env_logger = "0.5.0"
rusty-value = "0.6.0" rusty-value = "0.6.0"
serde = { version = "1.0.195", features = ["derive"] } serde = { version = "1.0.195", features = ["derive"] }

@ -1,21 +1,23 @@
use embed_nu::{CommandGroupConfig, Context}; use mlua::{Lua, LuaSerdeExt, OwnedTable};
use rusty_value::*;
use serde::Serialize; use serde::Serialize;
use std::{ use std::{
fs, mem, fs, mem,
path::{Path, PathBuf}, path::{Path, PathBuf},
sync::Arc,
}; };
use miette::{IntoDiagnostic, Result}; use miette::{IntoDiagnostic, Result};
use crate::{scripting::create_lua, utils::Describe};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Hooks { pub struct Hooks {
scripts: Vec<HookScript>, scripts: Vec<Arc<HookScript>>,
} }
#[derive(Clone)]
pub struct HookScript { pub struct HookScript {
script: embed_nu::Context, lua: Lua,
module: mlua::OwnedTable,
} }
impl std::fmt::Debug for HookScript { impl std::fmt::Debug for HookScript {
@ -24,13 +26,13 @@ impl std::fmt::Debug for HookScript {
} }
} }
#[derive(Clone, Debug, RustyValue, Serialize)] #[derive(Clone, Debug, Serialize)]
pub struct ApplyAllContext { pub struct ApplyAllContext {
pub repo: PathBuf, pub repo: PathBuf,
pub paths: Vec<PathBuf>, pub paths: Vec<PathBuf>,
} }
#[derive(Clone, Debug, RustyValue, Serialize)] #[derive(Clone, Debug, Serialize)]
pub struct ApplyEachContext { pub struct ApplyEachContext {
pub repo: PathBuf, pub repo: PathBuf,
pub src: PathBuf, pub src: PathBuf,
@ -44,7 +46,7 @@ impl Hooks {
} }
} }
pub fn parse(path: &Path) -> Result<Self> { pub fn load(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();
@ -52,9 +54,13 @@ impl Hooks {
for entry in readdir { for entry in readdir {
let path = entry.into_diagnostic()?.path(); let path = entry.into_diagnostic()?.path();
if path.is_file() && path.extension().is_some_and(|e| e == "nu") { if path.is_file()
&& path
.file_name()
.is_some_and(|f| f.to_string_lossy().ends_with(".hook.lua"))
{
log::debug!("Found hook {path:?}"); log::debug!("Found hook {path:?}");
scripts.push(HookScript::parse(&path)?) scripts.push(Arc::new(HookScript::load(&path)?))
} }
} }
@ -62,32 +68,32 @@ impl Hooks {
} }
pub fn before_apply_all(&mut self, ctx: ApplyAllContext) -> Result<()> { pub fn before_apply_all(&mut self, ctx: ApplyAllContext) -> Result<()> {
for script in &mut self.scripts { for script in &self.scripts {
script.before_apply_all(ctx.clone())?; script.before_apply_all(&ctx)?;
} }
Ok(()) Ok(())
} }
pub fn after_apply_all(&mut self, ctx: ApplyAllContext) -> Result<()> { pub fn after_apply_all(&mut self, ctx: ApplyAllContext) -> Result<()> {
for script in &mut self.scripts { for script in &self.scripts {
script.after_apply_all(ctx.clone())?; script.after_apply_all(&ctx)?;
} }
Ok(()) Ok(())
} }
pub fn before_apply_each(&mut self, ctx: ApplyEachContext) -> Result<()> { pub fn before_apply_each(&mut self, ctx: ApplyEachContext) -> Result<()> {
for script in &mut self.scripts { for script in &self.scripts {
script.before_apply_each(ctx.clone())?; script.before_apply_each(&ctx)?;
} }
Ok(()) Ok(())
} }
pub fn after_apply_each(&mut self, ctx: ApplyEachContext) -> Result<()> { pub fn after_apply_each(&mut self, ctx: ApplyEachContext) -> Result<()> {
for script in &mut self.scripts { for script in &self.scripts {
script.after_apply_each(ctx.clone())?; script.after_apply_each(&ctx)?;
} }
Ok(()) Ok(())
@ -101,71 +107,39 @@ impl Hooks {
} }
impl HookScript { impl HookScript {
pub fn parse(path: &Path) -> Result<Self> { pub fn load(path: &Path) -> Result<Self> {
let contents = fs::read_to_string(path).into_diagnostic()?; let lua = create_lua(&())?;
let module: OwnedTable = lua
.load(path)
.eval()
.with_describe(|| format!("loading hook script {path:?}"))?;
let ctx = Context::builder() Ok(Self { lua, module })
.with_command_groups(CommandGroupConfig::default().all_groups(true))
.into_diagnostic()?
.add_script(contents)
.into_diagnostic()?
.add_parent_env_vars()
.build()
.into_diagnostic()?;
Ok(Self { script: ctx })
} }
pub fn before_apply_all(&mut self, ctx: ApplyAllContext) -> Result<()> { pub fn before_apply_all(&self, ctx: &ApplyAllContext) -> Result<()> {
if self.script.has_fn("before_apply_all") { self.call_function("before_apply_all", ctx)
let pipeline = self
.script
.call_fn("before_apply_all", [ctx])
.into_diagnostic()?;
self.script.print_pipeline(pipeline).into_diagnostic()?;
} else {
log::debug!("No `before_apply_all` in script");
} }
Ok(()) pub fn after_apply_all(&self, ctx: &ApplyAllContext) -> Result<()> {
self.call_function("after_apply_all", ctx)
} }
pub fn after_apply_all(&mut self, ctx: ApplyAllContext) -> Result<()> { pub fn before_apply_each(&self, ctx: &ApplyEachContext) -> Result<()> {
if self.script.has_fn("after_apply_all") { self.call_function("before_apply_each", ctx)
let pipeline = self
.script
.call_fn("after_apply_all", [ctx])
.into_diagnostic()?;
self.script.print_pipeline(pipeline).into_diagnostic()?;
} else {
log::debug!("No `after_apply_all` in script");
} }
Ok(()) pub fn after_apply_each(&self, ctx: &ApplyEachContext) -> Result<()> {
self.call_function("after_apply_each", ctx)
} }
pub fn before_apply_each(&mut self, ctx: ApplyEachContext) -> Result<()> { fn call_function<S: Serialize>(&self, name: &str, ctx: &S) -> Result<()> {
if self.script.has_fn("before_apply_each") { if let Ok(hook_fn) = self.module.to_ref().get::<_, mlua::Function<'_>>(name) {
let pipeline = self hook_fn
.script .call(self.lua.to_value(&ctx).describe("Serializing context")?)
.call_fn("before_apply_each", [ctx]) .with_describe(|| format!("Calling hook script {name}"))?;
.into_diagnostic()?;
self.script.print_pipeline(pipeline).into_diagnostic()?;
} else { } else {
log::debug!("No `before_apply_each` in script"); log::debug!("No `before_apply_all` in script");
}
Ok(())
}
pub fn after_apply_each(&mut self, ctx: ApplyEachContext) -> Result<()> {
if self.script.has_fn("after_apply_each") {
let pipeline = self
.script
.call_fn("after_apply_each", [ctx])
.into_diagnostic()?;
self.script.print_pipeline(pipeline).into_diagnostic()?;
} else {
log::debug!("No `after_apply_each` in script");
} }
Ok(()) Ok(())

@ -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::parse(&hook_path)? Hooks::load(&hook_path)?
} else { } else {
Hooks::empty() Hooks::empty()
}; };

Loading…
Cancel
Save