Add hooks

integration-not-installation
trivernis 2 years ago
parent bf2f0a5b83
commit d19f405911
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

@ -0,0 +1,3 @@
def main [cfg] {
echo "Running after creating users"
}

@ -0,0 +1,4 @@
def main [cfg] {
echo "Running before creating users"
echo $TRM_VERSION
}

@ -1,5 +1,9 @@
use config::Config;
use error::AppResult;
use scripting::{loader::ScriptLoader, script::Script};
use scripting::{
loader::{HookType, ScriptLoader},
script::{NuScript, Script, ScriptArgs},
};
use tasks::*;
pub mod config;
@ -9,6 +13,7 @@ pub mod tasks;
pub(crate) mod utils;
pub struct TaskExecutor {
config: Option<Config>,
loader: ScriptLoader,
}
@ -17,7 +22,7 @@ macro_rules! tasks {
$(
#[tracing::instrument(level = "trace", skip(self))]
pub async fn $function(&self, cfg: &<$script as crate::scripting::script::Script>::Args) -> AppResult<()> {
self.execute::<$script>(cfg).await
self.execute_task::<$script>(cfg).await
}
)+
}
@ -34,9 +39,30 @@ impl TaskExecutor {
configure_local => ConfigureLocaleScript
);
async fn execute_task<S: Script>(&self, args: &S::Args) -> AppResult<()> {
if let Some(pre_hook) = self.loader.load_hook::<S>(HookType::Pre) {
self.execute(pre_hook, args).await?;
}
let script = self.loader.load::<S>()?;
self.execute(script, args).await?;
if let Some(post_hook) = self.loader.load_hook::<S>(HookType::Post) {
self.execute(post_hook, args).await?;
}
Ok(())
}
#[inline]
async fn execute<S: Script>(&self, args: &S::Args) -> AppResult<()> {
self.loader.load::<S>()?.execute(&args).await
async fn execute<S: Script>(&self, mut script: NuScript<S>, args: &S::Args) -> AppResult<()> {
if let Some(cfg) = self.config.as_ref() {
script.set_global_var("TRM_CONFIG", cfg.get_args())
} else {
&mut script
}
.set_global_var("TRM_VERSION", env!("CARGO_PKG_VERSION"))
.execute(args)
.await
}
}
@ -44,6 +70,7 @@ impl Default for TaskExecutor {
fn default() -> Self {
Self {
loader: ScriptLoader::new(),
config: None,
}
}
}

@ -53,8 +53,23 @@ impl NuExecutor {
/// Adds a global variable to the executor which can
/// be accessed from within the script
pub fn add_global_var<S: ToString>(&mut self, name: S, value: RecordValue) -> &mut Self {
self.global_vars.insert(name.to_string(), value);
pub fn add_global_var<S: ToString, V: Into<RecordValue>>(
&mut self,
name: S,
value: V,
) -> &mut Self {
self.global_vars.insert(name.to_string(), value.into());
self
}
/// Adds multiple global variables
pub fn add_global_vars<S: ToString, R: Into<RecordValue>, I: IntoIterator<Item = (S, R)>>(
&mut self,
vars: I,
) -> &mut Self {
self.global_vars
.extend(&mut vars.into_iter().map(|(k, v)| (k.to_string(), v.into())));
self
}

@ -6,21 +6,28 @@ use super::script::{NuScript, Script};
/// A loader for nu script files
pub struct ScriptLoader {
base_dir: PathBuf,
script_dir: PathBuf,
hook_dir: PathBuf,
}
pub enum HookType {
Pre,
Post,
}
impl ScriptLoader {
/// Creates a new script loader with the default config dir
pub fn new() -> Self {
Self {
base_dir: crate::utils::SCRIPT_PATH.to_owned(),
script_dir: crate::utils::SCRIPT_PATH.to_owned(),
hook_dir: crate::utils::HOOK_PATH.to_owned(),
}
}
/// Loads the given script file
#[tracing::instrument(level = "trace", skip_all)]
pub fn load<S: Script>(&self) -> AppResult<NuScript<S>> {
let script_path = self.base_dir.join(S::get_name());
let script_path = self.script_dir.join(S::get_name());
if !script_path.exists() {
Err(AppError::ScriptNotFound(script_path))
@ -28,4 +35,18 @@ impl ScriptLoader {
Ok(NuScript::new(script_path))
}
}
pub fn load_hook<S: Script>(&self, hook_type: HookType) -> Option<NuScript<S>> {
let script_name = match hook_type {
HookType::Pre => S::get_pre_hook(),
HookType::Post => S::get_post_hook(),
};
let script_path = self.hook_dir.join(script_name);
if !script_path.exists() {
None
} else {
Some(NuScript::new(script_path))
}
}
}

@ -1,5 +1,5 @@
use core::fmt;
use std::{marker::PhantomData, path::PathBuf};
use std::{collections::HashMap, marker::PhantomData, path::PathBuf};
use serde::Serialize;
@ -46,6 +46,7 @@ impl<T: Serialize> ScriptArgs for T {
/// A nu script instance that can be executed
pub struct NuScript<S: Script> {
path: PathBuf,
vars: HashMap<String, RecordValue>,
__phantom: PhantomData<S>,
}
@ -53,15 +54,28 @@ impl<S: Script> NuScript<S> {
pub(crate) fn new(path: PathBuf) -> Self {
Self {
path,
vars: HashMap::new(),
__phantom: PhantomData,
}
}
/// Adds a global variable
pub fn set_global_var<S1: ToString, V: Into<RecordValue>>(
&mut self,
key: S1,
value: V,
) -> &mut Self {
self.vars.insert(key.to_string(), value.into());
self
}
/// Executes the script with the given args
#[tracing::instrument(level = "trace", skip(self))]
pub async fn execute(&self, args: &S::Args) -> AppResult<()> {
NuExecutor::new(&self.path)
.add_args(args.get_args())
.add_global_vars(self.vars.clone())
.execute()
.await
}
@ -86,11 +100,11 @@ macro_rules! script {
}
fn get_pre_hook() -> &'static str {
concat!("name", ".pre.nu")
concat!($name, ".pre.nu")
}
fn get_post_hook() -> &'static str {
concat!("name", ".post.nu")
concat!($name, ".post.nu")
}
}
};

Loading…
Cancel
Save