mirror of
https://github.com/lune-org/lune.git
synced 2025-05-04 10:43:57 +01:00
Implement self alias for module requires
This commit is contained in:
parent
a673f80c95
commit
74375ff708
7 changed files with 56 additions and 5 deletions
|
@ -55,15 +55,45 @@ impl RequireContext {
|
||||||
This will resolve path segments such as `./`, `../`, ..., and
|
This will resolve path segments such as `./`, `../`, ..., and
|
||||||
if the resolved path is not an absolute path, will create an
|
if the resolved path is not an absolute path, will create an
|
||||||
absolute path by prepending the current working directory.
|
absolute path by prepending the current working directory.
|
||||||
|
|
||||||
|
If `resolve_as_self` is true, the given path should be a luau
|
||||||
|
module require path in the format of `@self/foo/bar/...` with the
|
||||||
|
`@self` prefix being stripped, and only `foo/bar/...` being passed.
|
||||||
*/
|
*/
|
||||||
pub fn resolve_paths(
|
pub fn resolve_paths(
|
||||||
source: impl AsRef<str>,
|
source: impl AsRef<str>,
|
||||||
path: impl AsRef<str>,
|
path: impl AsRef<str>,
|
||||||
|
resolve_as_self: bool,
|
||||||
) -> LuaResult<(PathBuf, PathBuf)> {
|
) -> LuaResult<(PathBuf, PathBuf)> {
|
||||||
let path = PathBuf::from(source.as_ref())
|
let source = PathBuf::from(source.as_ref());
|
||||||
|
let path = PathBuf::from(path.as_ref());
|
||||||
|
|
||||||
|
let is_init_module = {
|
||||||
|
let is_init = path
|
||||||
|
.file_stem()
|
||||||
|
.and_then(|stem| stem.to_str())
|
||||||
|
.is_some_and(|stem| stem.eq_ignore_ascii_case("init"));
|
||||||
|
let is_luau = is_init
|
||||||
|
&& path
|
||||||
|
.extension()
|
||||||
|
.and_then(|ext| ext.to_str())
|
||||||
|
.is_some_and(|ext| matches!(ext, "lua" | "luau"));
|
||||||
|
is_init && is_luau
|
||||||
|
};
|
||||||
|
|
||||||
|
let source = if is_init_module && !resolve_as_self {
|
||||||
|
source
|
||||||
|
.parent()
|
||||||
|
.ok_or_else(|| LuaError::runtime("Failed to get parent path of self"))?
|
||||||
|
.to_path_buf()
|
||||||
|
} else {
|
||||||
|
source
|
||||||
|
};
|
||||||
|
|
||||||
|
let path = source
|
||||||
.parent()
|
.parent()
|
||||||
.ok_or_else(|| LuaError::runtime("Failed to get parent path of source"))?
|
.ok_or_else(|| LuaError::runtime("Failed to get parent path of source"))?
|
||||||
.join(path.as_ref());
|
.join(path);
|
||||||
|
|
||||||
let abs_path = clean_path_and_make_absolute(&path);
|
let abs_path = clean_path_and_make_absolute(&path);
|
||||||
let rel_path = clean_path(path);
|
let rel_path = clean_path(path);
|
||||||
|
|
|
@ -80,13 +80,15 @@ async fn require(lua: Lua, (source, path): (LuaString, LuaString)) -> LuaResult<
|
||||||
|
|
||||||
if let Some(builtin_name) = path.strip_prefix("@lune/").map(str::to_ascii_lowercase) {
|
if let Some(builtin_name) = path.strip_prefix("@lune/").map(str::to_ascii_lowercase) {
|
||||||
library::require(lua, &context, &builtin_name)
|
library::require(lua, &context, &builtin_name)
|
||||||
|
} else if let Some(self_path) = path.strip_prefix("@self/") {
|
||||||
|
path::require(lua, &context, &source, self_path, true).await
|
||||||
} else if let Some(aliased_path) = path.strip_prefix('@') {
|
} else if let Some(aliased_path) = path.strip_prefix('@') {
|
||||||
let (alias, path) = aliased_path.split_once('/').ok_or(LuaError::runtime(
|
let (alias, path) = aliased_path.split_once('/').ok_or(LuaError::runtime(
|
||||||
"Require with custom alias must contain '/' delimiter",
|
"Require with custom alias must contain '/' delimiter",
|
||||||
))?;
|
))?;
|
||||||
alias::require(lua, &context, &source, alias, path).await
|
alias::require(lua, &context, &source, alias, path).await
|
||||||
} else if path.starts_with("./") || path.starts_with("../") {
|
} else if path.starts_with("./") || path.starts_with("../") {
|
||||||
path::require(lua, &context, &source, &path).await
|
path::require(lua, &context, &source, &path, false).await
|
||||||
} else {
|
} else {
|
||||||
Err(LuaError::runtime(
|
Err(LuaError::runtime(
|
||||||
"Require path must start with \"./\", \"../\" or \"@\"",
|
"Require path must start with \"./\", \"../\" or \"@\"",
|
||||||
|
|
|
@ -10,8 +10,9 @@ pub(super) async fn require(
|
||||||
ctx: &RequireContext,
|
ctx: &RequireContext,
|
||||||
source: &str,
|
source: &str,
|
||||||
path: &str,
|
path: &str,
|
||||||
|
resolve_as_self: bool,
|
||||||
) -> LuaResult<LuaMultiValue> {
|
) -> LuaResult<LuaMultiValue> {
|
||||||
let (abs_path, rel_path) = RequireContext::resolve_paths(source, path)?;
|
let (abs_path, rel_path) = RequireContext::resolve_paths(source, path, resolve_as_self)?;
|
||||||
require_abs_rel(lua, ctx, abs_path, rel_path).await
|
require_abs_rel(lua, ctx, abs_path, rel_path).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,4 +12,8 @@ module = require("./modules/modules")
|
||||||
assert(module.Foo == "Bar", "Required module did not contain correct values")
|
assert(module.Foo == "Bar", "Required module did not contain correct values")
|
||||||
assert(module.Hello == "World", "Required module did not contain correct values")
|
assert(module.Hello == "World", "Required module did not contain correct values")
|
||||||
|
|
||||||
|
module = require("./modules/self_alias")
|
||||||
|
assert(module.Foo == "Bar", "Required module did not contain correct values")
|
||||||
|
assert(module.Hello == "World", "Required module did not contain correct values")
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
local function test(path: string)
|
local function test(path: string)
|
||||||
local success, message = pcall(function()
|
local success, message = pcall(function()
|
||||||
local _ = require(path) :: any
|
local _ = require("./" .. path) :: any
|
||||||
end)
|
end)
|
||||||
if success then
|
if success then
|
||||||
error(string.format("Invalid require at path '%s' succeeded", path))
|
error(string.format("Invalid require at path '%s' succeeded", path))
|
||||||
|
|
10
tests/require/tests/modules/self_alias/init.luau
Normal file
10
tests/require/tests/modules/self_alias/init.luau
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
local outer = require("./module")
|
||||||
|
local inner = require("@self/module")
|
||||||
|
|
||||||
|
assert(type(outer) == "table", "Outer module is not a table")
|
||||||
|
assert(type(inner) == "table", "Inner module is not a table")
|
||||||
|
|
||||||
|
assert(outer.Foo == inner.Foo, "Outer and inner modules have different Foo values")
|
||||||
|
assert(inner.Bar == outer.Bar, "Outer and inner modules have different Bar values")
|
||||||
|
|
||||||
|
return inner
|
4
tests/require/tests/modules/self_alias/module.luau
Normal file
4
tests/require/tests/modules/self_alias/module.luau
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
return {
|
||||||
|
Foo = "Bar",
|
||||||
|
Hello = "World",
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue