Replace nushell hooks with lua hooks

main
trivernis 8 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"] }
dialoguer = "0.11.0"
dirs = "5.0.1"
embed-nu = "0.9.1"
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"] }
globset = { version = "0.4.14", features = ["serde", "serde1"] }
@ -25,7 +24,7 @@ lazy_static = "1.4.0"
log = "0.4.20"
merge-struct = "0.1.0"
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"
rusty-value = "0.6.0"
serde = { version = "1.0.195", features = ["derive"] }

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

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

Loading…
Cancel
Save