diff --git a/crates/lune-std-process/src/lib.rs b/crates/lune-std-process/src/lib.rs index 7c31558..742039d 100644 --- a/crates/lune-std-process/src/lib.rs +++ b/crates/lune-std-process/src/lib.rs @@ -57,19 +57,15 @@ pub fn module(lua: Lua) -> LuaResult { "little" })?; - // Find the readonly args array - let args_vec = lua - .app_data_ref::>() - .ok_or_else(|| LuaError::runtime("Missing args vec in Lua app data"))? + // Extract stored userdatas for args + env, the runtime struct should always provide this + let process_args = lua + .app_data_ref::() + .ok_or_else(|| LuaError::runtime("Missing process args in Lua app data"))? + .clone(); + let process_env = lua + .app_data_ref::() + .ok_or_else(|| LuaError::runtime("Missing process env in Lua app data"))? .clone(); - - // Create userdatas for args + env - // TODO: Move this up into the runtime creation instead, - // and set it as app data there to later fetch here - let process_args = ProcessArgs::from_iter(args_vec); - let process_env = ProcessEnv::current(); - lua.set_app_data(process_args.clone()); - lua.set_app_data(process_env.clone()); // Create our process exit function, the scheduler crate provides this let fns = Functions::new(lua.clone())?; diff --git a/crates/lune/src/rt/runtime.rs b/crates/lune/src/rt/runtime.rs index cf2f0fc..c68f639 100644 --- a/crates/lune/src/rt/runtime.rs +++ b/crates/lune/src/rt/runtime.rs @@ -1,11 +1,14 @@ #![allow(clippy::missing_panics_doc)] -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, +use std::{ + ffi::OsString, + sync::{ + atomic::{AtomicBool, Ordering}, + Arc, + }, }; -use lune_utils::jit::JitEnablement; +use lune_utils::process::{ProcessArgs, ProcessEnv, ProcessJitEnablement}; use mlua::prelude::*; use mlua_luau_scheduler::{Functions, Scheduler}; @@ -58,7 +61,9 @@ impl RuntimeReturnValues { pub struct Runtime { lua: Lua, sched: Scheduler, - jit: JitEnablement, + args: ProcessArgs, + env: ProcessEnv, + jit: ProcessJitEnablement, } impl Runtime { @@ -126,21 +131,47 @@ impl Runtime { .set(g_table.name(), g_table.create(lua.clone())?)?; } - let jit = JitEnablement::default(); - Ok(Self { lua, sched, jit }) + let args = ProcessArgs::current(); + let env = ProcessEnv::current(); + let jit = ProcessJitEnablement::default(); + + Ok(Self { + lua, + sched, + args, + env, + jit, + }) } /** Sets arguments to give in `process.args` for Lune scripts. + + By default, `std::env::args_os()` is used. */ #[must_use] - pub fn with_args(self, args: A) -> Self + pub fn with_args(mut self, args: A) -> Self where A: IntoIterator, - S: Into, + S: Into, { - let args = args.into_iter().map(Into::into).collect::>(); - self.lua.set_app_data(args); + self.args = args.into_iter().map(Into::into).collect(); + self + } + + /** + Sets environment values to give in `process.env` for Lune scripts. + + By default, `std::env::vars_os()` is used. + */ + #[must_use] + pub fn with_env(mut self, env: E) -> Self + where + E: IntoIterator, + K: Into, + V: Into, + { + self.env = env.into_iter().map(|(k, v)| (k.into(), v.into())).collect(); self } @@ -148,7 +179,10 @@ impl Runtime { Enables or disables JIT compilation. */ #[must_use] - pub fn with_jit(mut self, jit_status: impl Into) -> Self { + pub fn with_jit(mut self, jit_status: J) -> Self + where + J: Into, + { self.jit = jit_status.into(); self } @@ -175,8 +209,12 @@ impl Runtime { eprintln!("{}", RuntimeError::from(e)); }); - // Enable / disable the JIT as requested and store the current status as AppData + // Store the provided args, environment variables, and jit enablement as AppData + self.lua.set_app_data(self.args.clone()); + self.lua.set_app_data(self.env.clone()); self.lua.set_app_data(self.jit); + + // Enable / disable the JIT as requested, before loading anything self.lua.enable_jit(self.jit.enabled()); // Load our "main" thread diff --git a/crates/lune/src/tests.rs b/crates/lune/src/tests.rs index 253d46d..d4472e6 100644 --- a/crates/lune/src/tests.rs +++ b/crates/lune/src/tests.rs @@ -33,14 +33,8 @@ macro_rules! create_tests { let full_name = format!("{}/tests/{}.luau", workspace_dir.display(), $value); let script = read_to_string(&full_name).await?; let mut lune = Runtime::new()? - .with_jit(true) - .with_args( - ARGS - .clone() - .iter() - .map(ToString::to_string) - .collect::>() - ); + .with_args(ARGS.iter().cloned()) + .with_jit(true); let script_name = full_name .trim_end_matches(".luau") .trim_end_matches(".lua")