From 1f2be297ae53c9ee98742a882f3bf1b15df0ca6c Mon Sep 17 00:00:00 2001 From: bainchild Date: Fri, 24 Apr 2026 19:55:10 -0500 Subject: [PATCH 1/2] Add Lua require mode that adheres to the PUC Lua require. New require mode has no configuration other than the key `lua_path`, followed by the environment variable `LUA_PATH`, defaulting to `./?.luau;./?.lua;./?/init.luau;./?/init.lua`. --- Cargo.lock | 292 ++++++++++++++++++++++++++ Cargo.toml | 1 + src/rules/bundle/require_mode.rs | 13 +- src/rules/require/lua_path_locator.rs | 60 ++++++ src/rules/require/lua_require_mode.rs | 63 ++++++ src/rules/require/mod.rs | 4 + 6 files changed, 432 insertions(+), 1 deletion(-) create mode 100644 src/rules/require/lua_path_locator.rs create mode 100644 src/rules/require/lua_require_mode.rs diff --git a/Cargo.lock b/Cargo.lock index fb0eb254..99c6c1be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20,6 +20,15 @@ dependencies = [ "cc", ] +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anes" version = "0.1.6" @@ -103,6 +112,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + [[package]] name = "bitflags" version = "2.11.1" @@ -196,6 +211,18 @@ dependencies = [ "rand_core", ] +[[package]] +name = "chrono" +version = "0.4.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + [[package]] name = "ciborium" version = "0.2.2" @@ -301,6 +328,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + [[package]] name = "cpufeatures" version = "0.3.0" @@ -419,6 +452,7 @@ dependencies = [ "serde", "serde_bytes", "serde_json", + "serde_with", "serde_yaml", "tempfile", "toml", @@ -429,6 +463,50 @@ dependencies = [ "xxhash-rust", ] +[[package]] +name = "darling" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" +dependencies = [ + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.117", +] + +[[package]] +name = "darling_macro" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "deranged" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c" +dependencies = [ + "powerfmt", + "serde_core", +] + [[package]] name = "derive_more" version = "1.0.0" @@ -480,6 +558,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "232860130f75128af6852aef5105ee3813539258f2ce74d0f0ec2dca9b69e22d" +[[package]] +name = "dyn-clone" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" + [[package]] name = "either" version = "1.15.0" @@ -685,12 +769,48 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "iana-time-zone" +version = "0.1.65" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + [[package]] name = "id-arena" version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "include_dir" version = "0.7.4" @@ -718,6 +838,7 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", + "serde", ] [[package]] @@ -1008,6 +1129,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num-conv" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" + [[package]] name = "num-traits" version = "0.2.19" @@ -1143,6 +1270,12 @@ dependencies = [ "portable-atomic", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "predicates" version = "3.1.4" @@ -1261,6 +1394,26 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "ref-cast" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "regex" version = "1.12.3" @@ -1324,6 +1477,30 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schemars" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + +[[package]] +name = "schemars" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2b42f36aa1cd011945615b92222f6bf73c599a102a300334cd7f8dbeec726cc" +dependencies = [ + "dyn-clone", + "ref-cast", + "serde", + "serde_json", +] + [[package]] name = "semver" version = "1.0.28" @@ -1392,6 +1569,37 @@ dependencies = [ "serde_core", ] +[[package]] +name = "serde_with" +version = "3.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd5414fad8e6907dbdd5bc441a50ae8d6e26151a03b1de04d89a5576de61d01f" +dependencies = [ + "base64", + "chrono", + "hex", + "indexmap 1.9.3", + "indexmap 2.14.0", + "schemars 0.9.0", + "schemars 1.2.1", + "serde_core", + "serde_json", + "serde_with_macros", + "time", +] + +[[package]] +name = "serde_with_macros" +version = "3.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3db8978e608f1fe7357e211969fd9abdcae80bac1ba7a3369bb7eb6b404eb65" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -1530,6 +1738,37 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "time" +version = "0.3.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde_core", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca" + +[[package]] +name = "time-macros" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinytemplate" version = "1.2.1" @@ -1860,12 +2099,65 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-sys" version = "0.60.2" diff --git a/Cargo.toml b/Cargo.toml index 534ec204..e19a17e7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -42,6 +42,7 @@ petgraph = "0.8.3" regex = "1.12.3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.149" +serde_with = "3.18.0" serde_yaml = "0.9.33" toml = "1.1.2" tracing = { version = "0.1", optional = true } diff --git a/src/rules/bundle/require_mode.rs b/src/rules/bundle/require_mode.rs index 81f13a4c..51c24d85 100644 --- a/src/rules/bundle/require_mode.rs +++ b/src/rules/bundle/require_mode.rs @@ -3,7 +3,10 @@ use std::str::FromStr; use serde::{Deserialize, Serialize}; use crate::rules::{ - require::{LuauPathLocator, LuauRequireMode, PathRequireMode, RequirePathLocator}, + require::{ + LuaPathLocator, LuaRequireMode, LuauPathLocator, LuauRequireMode, PathRequireMode, + RequirePathLocator, + }, RuleProcessResult, }; use crate::{nodes::Block, rules::Context}; @@ -14,6 +17,7 @@ use super::{path_require_mode, BundleOptions}; #[serde(deny_unknown_fields, rename_all = "snake_case", tag = "name")] pub enum BundleRequireMode { Path(PathRequireMode), + Lua(LuaRequireMode), Luau(LuauRequireMode), } @@ -29,6 +33,7 @@ impl FromStr for BundleRequireMode { fn from_str(s: &str) -> Result { Ok(match s { "path" => Self::Path(Default::default()), + "lua" => Self::Lua(Default::default()), "luau" => Self::Luau(Default::default()), _ => return Err(format!("invalid require mode `{}`", s)), }) @@ -63,6 +68,12 @@ impl BundleRequireMode { path_require_mode::process_block(block, context, options, locator) } + Self::Lua(lua_require_mode) => { + let require_mode = lua_require_mode.clone(); + let locator = LuaPathLocator::new(&require_mode, context.resources()); + + path_require_mode::process_block(block, context, options, locator) + } Self::Luau(luau_require_mode) => { let mut require_mode = luau_require_mode.clone(); require_mode diff --git a/src/rules/require/lua_path_locator.rs b/src/rules/require/lua_path_locator.rs new file mode 100644 index 00000000..21217bec --- /dev/null +++ b/src/rules/require/lua_path_locator.rs @@ -0,0 +1,60 @@ +use std::path::{Path, PathBuf}; + +use super::LuaRequireMode; +use crate::{utils, DarkluaError, Resources}; + +#[derive(Debug)] +pub(crate) struct LuaPathLocator<'a, 'resources> { + lua_require_mode: &'a LuaRequireMode, + resources: &'resources Resources, +} + +impl<'a, 'b> LuaPathLocator<'a, 'b> { + pub(crate) fn new(lua_require_mode: &'a LuaRequireMode, resources: &'b Resources) -> Self { + Self { + lua_require_mode, + resources, + } + } +} + +impl super::PathLocator for LuaPathLocator<'_, '_> { + fn find_require_path( + &self, + path: impl Into, + source: &Path, + ) -> Result { + let path: String = path + .into() + .to_string_lossy().into_owned() + .replace(".", std::path::MAIN_SEPARATOR_STR); + log::trace!( + "find require path for `{}` from `{}` (lua mode)", + path, + source.display() + ); + for potential_path in self + .lua_require_mode + .lua_path() + .iter() + .map(|x| x.replace("?", &path)) + { + let potential_pathbuf: PathBuf = potential_path.into(); + if self.resources.is_file(&potential_pathbuf)? { + return Ok(utils::normalize_path_with_current_dir(potential_pathbuf)); + } + } + + Err( + DarkluaError::resource_not_found(path.clone()).context(format!( + "tried `{}`", + self.lua_require_mode + .lua_path() + .iter() + .map(|x| x.replace("?", &path)) + .collect::>() + .join("`, `") + )), + ) + } +} diff --git a/src/rules/require/lua_require_mode.rs b/src/rules/require/lua_require_mode.rs new file mode 100644 index 00000000..4b084fa9 --- /dev/null +++ b/src/rules/require/lua_require_mode.rs @@ -0,0 +1,63 @@ +use serde::{Deserialize, Serialize}; +use serde_with::formats::SemicolonSeparator; +use serde_with::serde_as; +use serde_with::StringWithSeparator; + +use std::collections::HashMap; +use std::path::PathBuf; + +/// A require mode for the default behavior of PUC Lua interpreters. +#[serde_as] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(deny_unknown_fields, rename_all = "snake_case")] +pub struct LuaRequireMode { + #[serde(default, skip_serializing_if = "HashMap::is_empty")] + sources: HashMap, + #[serde_as(as = "StringWithSeparator::")] + #[serde(default = "get_default_lua_path")] + lua_path: Vec, +} + +fn get_default_lua_path() -> Vec { + std::env::var("LUA_PATH") + .ok() + .map(|x| x.split(";").map(|x| x.to_owned()).collect()) + .unwrap_or(vec![ + // this is order sensitive, and adjusted to match (roughly) the path require mode + // "./?".to_string(), + "./?.luau".to_string(), + "./?.lua".to_string(), + "./?/init.luau".to_string(), + "./?/init.lua".to_string(), // TODO: do we want to allow resource files to both overshadow eachother AND possibly code? + // ex: require("ab.c") -> ./ab/c.lua, ./ab/c/init.lua, ./ab/c.{txt,json,toml,yaml} + // Might actually be useful in the case you want to replace a resource file with code (just by shadowing). + // These are needed (either in LUA_PATH or here) for requiring resources because you can't use . in lua + // require paths. + // "./?.txt".to_string(), + // "./?.json".to_string(), + // "./?.toml".to_string(), + // "./?.yaml".to_string(), + ]) +} + +impl Default for LuaRequireMode { + fn default() -> Self { + Self { + lua_path: get_default_lua_path(), + sources: Default::default(), + } + } +} + +impl LuaRequireMode { + pub fn new(lua_path: impl Into) -> Self { + Self { + lua_path: lua_path.into().split(";").map(|x| x.to_owned()).collect(), + sources: Default::default(), + } + } + + pub(crate) fn lua_path(&self) -> &Vec { + &self.lua_path + } +} diff --git a/src/rules/require/mod.rs b/src/rules/require/mod.rs index 8feb1990..50f27407 100644 --- a/src/rules/require/mod.rs +++ b/src/rules/require/mod.rs @@ -1,3 +1,5 @@ +mod lua_path_locator; +mod lua_require_mode; mod luau_path_locator; mod luau_require_mode; mod match_require; @@ -8,6 +10,8 @@ pub(crate) mod path_utils; use std::path::{Path, PathBuf}; +pub(crate) use lua_path_locator::LuaPathLocator; +pub use lua_require_mode::LuaRequireMode; pub(crate) use luau_path_locator::LuauPathLocator; pub use luau_require_mode::LuauRequireMode; pub(crate) use match_require::{is_require_call, match_path_require_call}; From aa8dea17ee9f13f60e5b4f5945119a53dcbd1750 Mon Sep 17 00:00:00 2001 From: bainchild <55368789+bainchild@users.noreply.github.com> Date: Mon, 18 May 2026 12:08:30 -0500 Subject: [PATCH 2/2] Add Lua require mode docs, integrate feedback. --- site/content/docs/config/index.md | 1 - site/content/docs/lua-require-mode/index.md | 38 +++++++++++ site/package-lock.json | 48 +++++++++----- src/rules/require/lua_path_locator.rs | 7 +- src/rules/require/lua_require_mode.rs | 72 ++++++++------------- 5 files changed, 103 insertions(+), 63 deletions(-) create mode 100644 site/content/docs/lua-require-mode/index.md diff --git a/site/content/docs/config/index.md b/site/content/docs/config/index.md index 3b55c00b..fec3666a 100644 --- a/site/content/docs/config/index.md +++ b/site/content/docs/config/index.md @@ -58,7 +58,6 @@ Any missing field will be replaced with its default value. // Configure how requires are interpreted require_mode: { - // Currently, the only supported require mode is `path` name: "path", // When requiring folders, require the file named like this value inside of it diff --git a/site/content/docs/lua-require-mode/index.md b/site/content/docs/lua-require-mode/index.md new file mode 100644 index 00000000..218a7827 --- /dev/null +++ b/site/content/docs/lua-require-mode/index.md @@ -0,0 +1,38 @@ +--- +title: Lua Require Mode +description: How lua (and darklua) understands require calls +group: Configuration +order: 6 +--- + +This require mode is used for lua programs outside of the Luau ecosystem, including PUC lua, luajit, and most other plain lua +implementations that include a require function. +For more information, please refer to the documentation for [package.searchpath at lua.org](https://lua.org/manual/5.5/manual.html#pdf-package.searchpath). + +## Bundling Support + +It can be configured in the **bundle** part of the configuration file. For a quick overview of the bundling configuration, see [the documentation page](../bundle/). + +## Configuration + +The lua require mode uses the environment variable `LUA_PATH` by default as the search path, +but it can be configured to either use a different environment variable, just use the default search path, or +to use a string from the configuration file. +Lua's require does not support aliases or hierarchy beyond the filesystem, so there is no configuration for them. +Note that despite lua's require not supporting embedding text, JSON, TOML, and YAML files, you may do so with darklua, +as long as it is present in the search string. + +### Example +```json5 +{ + bundle: { + require_mode: { + name: "lua", + env: "DARKLUA_PATH", + // Path takes priority over env when provided. In the search string, + // order is important. + path: "./?.luau;./?/init.luau;./res/?.json;./res/?.toml" + } + } +} +``` diff --git a/site/package-lock.json b/site/package-lock.json index 7bd00a09..9ec06bd6 100644 --- a/site/package-lock.json +++ b/site/package-lock.json @@ -113,6 +113,7 @@ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.29.0", "@babel/generator": "^7.29.0", @@ -2075,6 +2076,7 @@ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz", "integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -2118,6 +2120,7 @@ "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.14.1.tgz", "integrity": "sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.18.3", "@emotion/babel-plugin": "^11.13.5", @@ -2256,6 +2259,7 @@ "resolved": "https://registry.npmjs.org/@gatsbyjs/reach-router/-/reach-router-2.0.1.tgz", "integrity": "sha512-gmSZniS9/phwgEgpFARMpNg21PkYDZEpfgEzvkgpE/iku4uvXqCrxr86fXbTpI9mkrhKS1SCTYmLGe60VdHcdQ==", "license": "MIT", + "peer": true, "dependencies": { "invariant": "^2.2.4", "prop-types": "^15.8.1" @@ -3052,6 +3056,7 @@ "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.18.0.tgz", "integrity": "sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.23.9", "@mui/core-downloads-tracker": "^5.18.0", @@ -3468,6 +3473,7 @@ "resolved": "https://registry.npmjs.org/@parcel/core/-/core-2.8.3.tgz", "integrity": "sha512-Euf/un4ZAiClnlUXqPB9phQlKbveU+2CotZv7m7i+qkgvFn5nAGnrV4h1OzQU42j9dpgOxWi7AttUDMrvkbhCQ==", "license": "MIT", + "peer": true, "dependencies": { "@mischnic/json-sourcemap": "^0.1.0", "@parcel/cache": "2.8.3", @@ -4729,6 +4735,7 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.10.tgz", "integrity": "sha512-WPigyYuGhgZ/cTPRXB2EwUw+XvsRA3GqHlsP4qteqrnnjDrApbS7MxcGr/hke5iUoeB7E/gQtrs9I37zAJ0Vjw==", "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -4781,7 +4788,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/experimental-utils": "4.33.0", "@typescript-eslint/scope-manager": "4.33.0", @@ -4814,7 +4820,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -4827,7 +4832,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", "license": "MIT", - "peer": true, "dependencies": { "@types/json-schema": "^7.0.7", "@typescript-eslint/scope-manager": "4.33.0", @@ -4852,7 +4856,6 @@ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", "license": "MIT", - "peer": true, "dependencies": { "eslint-visitor-keys": "^2.0.0" }, @@ -4899,7 +4902,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0" @@ -4917,7 +4919,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", "license": "MIT", - "peer": true, "engines": { "node": "^8.10.0 || ^10.13.0 || >=11.10.1" }, @@ -4931,7 +4932,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/types": "4.33.0", "@typescript-eslint/visitor-keys": "4.33.0", @@ -4959,7 +4959,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", - "peer": true, "bin": { "semver": "bin/semver.js" }, @@ -4972,7 +4971,6 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", "license": "MIT", - "peer": true, "dependencies": { "@typescript-eslint/types": "4.33.0", "eslint-visitor-keys": "^2.0.0" @@ -5203,6 +5201,7 @@ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -5215,7 +5214,6 @@ "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" }, @@ -5270,6 +5268,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5812,7 +5811,6 @@ "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.0.0", "@babel/parser": "^7.7.0", @@ -5833,7 +5831,6 @@ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", "license": "Apache-2.0", - "peer": true, "engines": { "node": ">=4" } @@ -6354,6 +6351,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -7341,6 +7339,7 @@ "integrity": "sha512-zpEHTy1fjTMZCKLHUZoVeylt9XrzaIN2rbPXEt0k+q7JE5CkCZdo6bNq55bn24a69CH7ErAVLKijxJja4fw+UQ==", "hasInstallScript": true, "license": "MIT", + "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/core-js" @@ -8551,8 +8550,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/es-object-atoms": { "version": "1.1.1", @@ -8701,6 +8699,7 @@ "integrity": "sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==", "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "7.12.11", "@eslint/eslintrc": "^0.4.3", @@ -8837,6 +8836,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-5.10.0.tgz", "integrity": "sha512-vcz32f+7TP+kvTUyMXZmCnNujBQZDNmcqPImw8b9PZ+16w1Qdm6ryRuYZYVaG9xRqqmAPr2Cs9FAX5gN+x/bjw==", "license": "BSD-3-Clause", + "peer": true, "dependencies": { "lodash": "^4.17.15", "string-natural-compare": "^3.0.1" @@ -8853,6 +8853,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -8907,6 +8908,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz", "integrity": "sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==", "license": "MIT", + "peer": true, "dependencies": { "aria-query": "^5.3.2", "array-includes": "^3.1.8", @@ -8936,6 +8938,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", "license": "MIT", + "peer": true, "dependencies": { "array-includes": "^3.1.8", "array.prototype.findlast": "^1.2.5", @@ -8968,6 +8971,7 @@ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz", "integrity": "sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=10" }, @@ -10287,6 +10291,7 @@ "integrity": "sha512-xVzKmYvi2UFvwmHvkW0mBW6wirMtqoenTw9aLFVWDTSvyJycka70yNk4dnaaKSJ7TwpVStYZ/Z2J5Pc1ROgJqQ==", "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.18.6", "@babel/core": "^7.20.12", @@ -10783,6 +10788,7 @@ "resolved": "https://registry.npmjs.org/gatsby-plugin-sharp/-/gatsby-plugin-sharp-5.16.0.tgz", "integrity": "sha512-MYcvpSKM39iVvagjqxCQCYEbhwv4Ql6REp93qFRxARCaDJ50tRSLvAz/i9iI4oZs0He+3AANYN2SK/GxqwV4eQ==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.20.13", "async": "^3.2.5", @@ -11018,6 +11024,7 @@ "resolved": "https://registry.npmjs.org/gatsby-source-filesystem/-/gatsby-source-filesystem-5.16.0.tgz", "integrity": "sha512-z64lyDaonLpD1fHV8s9MYVBz2z6Mv3jwEntwt/KA4QKPJsH/qD1eKZ0OBSilGqEadzLw7EcgTGkTXBAz1gd8fg==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.20.13", "chokidar": "^3.6.0", @@ -11308,6 +11315,7 @@ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.62.0.tgz", "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "license": "BSD-2-Clause", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -11776,6 +11784,7 @@ "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.12.0.tgz", "integrity": "sha512-DKKrynuQRne0PNpEbzuEdHlYOMksHSUI8Zc9Unei5gTsMNA2/vMpoMz/yKba50pejK56qj98qM0SjYxAKi13gQ==", "license": "MIT", + "peer": true, "engines": { "node": "^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0" } @@ -16670,6 +16679,7 @@ "resolved": "https://registry.npmjs.org/monaco-editor/-/monaco-editor-0.55.1.tgz", "integrity": "sha512-jz4x+TJNFHwHtwuV9vA9rMujcZRb0CEilTEwG2rRSpe/A7Jdkuj8xPKttCgOh+v/lkHy7HsZ64oj+q3xoAFl9A==", "license": "MIT", + "peer": true, "dependencies": { "dompurify": "3.2.7", "marked": "14.0.0" @@ -18093,6 +18103,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -18769,6 +18780,7 @@ "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", "license": "MIT", + "peer": true, "engines": { "node": ">=6" } @@ -19080,6 +19092,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -19226,6 +19239,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -19251,6 +19265,7 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -19436,6 +19451,7 @@ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", "license": "MIT", + "peer": true, "dependencies": { "@babel/runtime": "^7.9.2" } @@ -20597,6 +20613,7 @@ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -22249,6 +22266,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "license": "(MIT OR CC0-1.0)", + "peer": true, "engines": { "node": ">=10" }, @@ -22386,6 +22404,7 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -23160,7 +23179,6 @@ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", "license": "MIT", - "peer": true, "engines": { "node": ">=10.13.0" } diff --git a/src/rules/require/lua_path_locator.rs b/src/rules/require/lua_path_locator.rs index 21217bec..dac8deb3 100644 --- a/src/rules/require/lua_path_locator.rs +++ b/src/rules/require/lua_path_locator.rs @@ -26,7 +26,8 @@ impl super::PathLocator for LuaPathLocator<'_, '_> { ) -> Result { let path: String = path .into() - .to_string_lossy().into_owned() + .to_string_lossy() + .into_owned() .replace(".", std::path::MAIN_SEPARATOR_STR); log::trace!( "find require path for `{}` from `{}` (lua mode)", @@ -35,7 +36,7 @@ impl super::PathLocator for LuaPathLocator<'_, '_> { ); for potential_path in self .lua_require_mode - .lua_path() + .path() .iter() .map(|x| x.replace("?", &path)) { @@ -49,7 +50,7 @@ impl super::PathLocator for LuaPathLocator<'_, '_> { DarkluaError::resource_not_found(path.clone()).context(format!( "tried `{}`", self.lua_require_mode - .lua_path() + .path() .iter() .map(|x| x.replace("?", &path)) .collect::>() diff --git a/src/rules/require/lua_require_mode.rs b/src/rules/require/lua_require_mode.rs index 4b084fa9..c75681d3 100644 --- a/src/rules/require/lua_require_mode.rs +++ b/src/rules/require/lua_require_mode.rs @@ -3,61 +3,45 @@ use serde_with::formats::SemicolonSeparator; use serde_with::serde_as; use serde_with::StringWithSeparator; -use std::collections::HashMap; -use std::path::PathBuf; +const DEFAULT_PATH_VARIABLE: &str = "LUA_PATH"; +const DEFAULT_SEARCH_PATHS: [&str; 4] = [ + // this is order sensitive, and adjusted to match the path require mode + "./?.luau", + "./?.lua", + "./?/init.luau", + "./?/init.lua", +]; /// A require mode for the default behavior of PUC Lua interpreters. #[serde_as] -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Default, Clone, Serialize, Deserialize, PartialEq, Eq)] #[serde(deny_unknown_fields, rename_all = "snake_case")] pub struct LuaRequireMode { - #[serde(default, skip_serializing_if = "HashMap::is_empty")] - sources: HashMap, - #[serde_as(as = "StringWithSeparator::")] - #[serde(default = "get_default_lua_path")] - lua_path: Vec, -} - -fn get_default_lua_path() -> Vec { - std::env::var("LUA_PATH") - .ok() - .map(|x| x.split(";").map(|x| x.to_owned()).collect()) - .unwrap_or(vec![ - // this is order sensitive, and adjusted to match (roughly) the path require mode - // "./?".to_string(), - "./?.luau".to_string(), - "./?.lua".to_string(), - "./?/init.luau".to_string(), - "./?/init.lua".to_string(), // TODO: do we want to allow resource files to both overshadow eachother AND possibly code? - // ex: require("ab.c") -> ./ab/c.lua, ./ab/c/init.lua, ./ab/c.{txt,json,toml,yaml} - // Might actually be useful in the case you want to replace a resource file with code (just by shadowing). - // These are needed (either in LUA_PATH or here) for requiring resources because you can't use . in lua - // require paths. - // "./?.txt".to_string(), - // "./?.json".to_string(), - // "./?.toml".to_string(), - // "./?.yaml".to_string(), - ]) -} - -impl Default for LuaRequireMode { - fn default() -> Self { - Self { - lua_path: get_default_lua_path(), - sources: Default::default(), - } - } + env: Option, + #[serde_as(as = "Option>")] + path: Option>, } impl LuaRequireMode { - pub fn new(lua_path: impl Into) -> Self { + pub fn new(path: Option>, env: Option>) -> Self { Self { - lua_path: lua_path.into().split(";").map(|x| x.to_owned()).collect(), - sources: Default::default(), + env: env.map(|x| x.into()), + path: path.map(|x| x.into().split(";").map(|x| x.to_owned()).collect()), } } - pub(crate) fn lua_path(&self) -> &Vec { - &self.lua_path + pub(crate) fn path(&self) -> Vec { + if let Some(path) = self.path.as_ref() { + path.clone() + } else { + std::env::var( + self.env + .clone() + .unwrap_or(DEFAULT_PATH_VARIABLE.to_string()), + ) + .ok() + .map(|x| x.split(";").map(|x| x.to_string()).collect()) + .unwrap_or(DEFAULT_SEARCH_PATHS.iter().map(|x| x.to_string()).collect()) + } } }