diff --git a/CHANGELOG.md b/CHANGELOG.md index 270e19b..54179d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- Fixed not being able to require files with multiple extensions, eg. `module.spec.luau` was not require-able using `require("module.spec")` - Fixed instances and `roblox` built-in library APIs erroring when used asynchronously/concurrently. ## `0.7.5` - July 22nd, 2023 diff --git a/src/lune/importer/require.rs b/src/lune/importer/require.rs index 4211a22..20048c6 100644 --- a/src/lune/importer/require.rs +++ b/src/lune/importer/require.rs @@ -6,7 +6,6 @@ use std::{ sync::Arc, }; -use dunce::canonicalize; use mlua::{prelude::*, Compiler as LuaCompiler}; use tokio::fs; use tokio::sync::Mutex as AsyncMutex; @@ -29,6 +28,19 @@ return yield() type RequireWakersVec<'lua> = Vec>>>; +fn append_extension_and_canonicalize( + path: impl Into, + ext: &'static str, +) -> Result { + let mut new = path.into(); + match new.extension() { + // FUTURE: There's probably a better way to do this than converting to a lossy string + Some(e) => new.set_extension(format!("{}.{ext}", e.to_string_lossy())), + None => new.set_extension(ext), + }; + dunce::canonicalize(new) +} + #[derive(Debug, Clone, Default)] struct RequireContext<'lua> { // NOTE: We need to use arc here so that mlua clones @@ -128,25 +140,28 @@ impl<'lua> RequireContext<'lua> { .join(&require_path); // Try to normalize and resolve relative path segments such as './' and '../' let file_path = match ( - canonicalize(path_relative_to_pwd.with_extension("luau")), - canonicalize(path_relative_to_pwd.with_extension("lua")), + append_extension_and_canonicalize(&path_relative_to_pwd, "luau"), + append_extension_and_canonicalize(&path_relative_to_pwd, "lua"), ) { (Ok(luau), _) => luau, (_, Ok(lua)) => lua, // If we did not find a luau/lua file at the wanted path, // we should also look for "init" files in directories - _ => match ( - canonicalize(path_relative_to_pwd.join("init").with_extension("luau")), - canonicalize(path_relative_to_pwd.join("init").with_extension("lua")), - ) { - (Ok(luau), _) => luau, - (_, Ok(lua)) => lua, - _ => { - return Err(LuaError::RuntimeError(format!( - "File does not exist at path '{require_path}'" - ))) + _ => { + let init_dir_path = path_relative_to_pwd.join("init"); + match ( + append_extension_and_canonicalize(&init_dir_path, "luau"), + append_extension_and_canonicalize(&init_dir_path, "lua"), + ) { + (Ok(luau), _) => luau, + (_, Ok(lua)) => lua, + _ => { + return Err(LuaError::RuntimeError(format!( + "File does not exist at path '{require_path}'" + ))); + } } - }, + } }; let absolute = file_path.to_string_lossy().to_string(); let relative = absolute.trim_start_matches(&self.pwd).to_string(); diff --git a/src/tests.rs b/src/tests.rs index b80f5bd..96a840c 100644 --- a/src/tests.rs +++ b/src/tests.rs @@ -69,6 +69,7 @@ create_tests! { require_children: "require/tests/children", require_init: "require/tests/init", require_invalid: "require/tests/invalid", + require_multi_ext: "require/tests/multi_ext", require_nested: "require/tests/nested", require_parents: "require/tests/parents", require_siblings: "require/tests/siblings", diff --git a/tests/require/tests/multi.ext.file.luau b/tests/require/tests/multi.ext.file.luau new file mode 100644 index 0000000..cb3159b --- /dev/null +++ b/tests/require/tests/multi.ext.file.luau @@ -0,0 +1,4 @@ +return { + Foo = "Bar", + Hello = "World", +} diff --git a/tests/require/tests/multi_ext.luau b/tests/require/tests/multi_ext.luau new file mode 100644 index 0000000..ec20042 --- /dev/null +++ b/tests/require/tests/multi_ext.luau @@ -0,0 +1 @@ +require("multi.ext.file")