From 25955893e029f74bd13749b0e95b40ccb9c32199 Mon Sep 17 00:00:00 2001 From: Alex Orlenko Date: Mon, 23 Jun 2025 15:49:37 +0100 Subject: [PATCH] (Luau Require) Resolve Lua file path relative to the current directory and unrelated to Rust source file location. When a Lua file is required inside a Rust file (in a chunk), we should resolve the Lua file relative to the current directory, instead of relative to the Rust chunk path. The Rust file location is an internal information that does not exist when the compiled binary runs. Fixes #605 --- src/luau/require.rs | 6 ++++-- tests/luau/require.rs | 42 ++++++++++++++++++++++++++---------------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/src/luau/require.rs b/src/luau/require.rs index ebb7468..167d04a 100644 --- a/src/luau/require.rs +++ b/src/luau/require.rs @@ -200,9 +200,11 @@ impl Require for TextRequirer { let chunk_path = Self::normalize_path(chunk_name.as_ref()); if chunk_path.extension() == Some("rs".as_ref()) { + // Special case for Rust source files, reset to the current directory + let chunk_filename = chunk_path.file_name().unwrap(); let cwd = env::current_dir().map_err(|_| NavigateError::NotFound)?; - self.abs_path = Self::normalize_path(&cwd.join(&chunk_path)); - self.rel_path = chunk_path; + self.abs_path = Self::normalize_path(&cwd.join(chunk_filename)); + self.rel_path = ([Component::CurDir, Component::Normal(chunk_filename)].into_iter()).collect(); self.module_path = PathBuf::new(); return Ok(()); diff --git a/tests/luau/require.rs b/tests/luau/require.rs index 7d2ec58..da8c4f1 100644 --- a/tests/luau/require.rs +++ b/tests/luau/require.rs @@ -105,63 +105,69 @@ fn test_require_without_config() { let lua = Lua::new(); // RequireSimpleRelativePath - let res = run_require(&lua, "./require/without_config/dependency").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/dependency").unwrap(); assert_eq!("result from dependency", get_str(&res, 1)); // RequireSimpleRelativePathWithinPcall - let res = run_require_pcall(&lua, "./require/without_config/dependency").unwrap(); + let res = run_require_pcall(&lua, "./tests/luau/require/without_config/dependency").unwrap(); assert!(res[0].as_boolean().unwrap()); assert_eq!("result from dependency", get_str(&res[1], 1)); // RequireRelativeToRequiringFile - let res = run_require(&lua, "./require/without_config/module").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/module").unwrap(); assert_eq!("result from dependency", get_str(&res, 1)); assert_eq!("required into module", get_str(&res, 2)); // RequireLua - let res = run_require(&lua, "./require/without_config/lua_dependency").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/lua_dependency").unwrap(); assert_eq!("result from lua_dependency", get_str(&res, 1)); // RequireInitLuau - let res = run_require(&lua, "./require/without_config/luau").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/luau").unwrap(); assert_eq!("result from init.luau", get_str(&res, 1)); // RequireInitLua - let res = run_require(&lua, "./require/without_config/lua").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/lua").unwrap(); assert_eq!("result from init.lua", get_str(&res, 1)); // RequireSubmoduleUsingSelfIndirectly - let res = run_require(&lua, "./require/without_config/nested_module_requirer").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/nested_module_requirer").unwrap(); assert_eq!("result from submodule", get_str(&res, 1)); // RequireSubmoduleUsingSelfDirectly - let res = run_require(&lua, "./require/without_config/nested").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/nested").unwrap(); assert_eq!("result from submodule", get_str(&res, 1)); // CannotRequireInitLuauDirectly - let res = run_require(&lua, "./require/without_config/nested/init"); + let res = run_require(&lua, "./tests/luau/require/without_config/nested/init"); assert!(res.is_err()); assert!((res.unwrap_err().to_string()).contains("could not resolve child component \"init\"")); // RequireNestedInits - let res = run_require(&lua, "./require/without_config/nested_inits_requirer").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/nested_inits_requirer").unwrap(); assert_eq!("result from nested_inits/init", get_str(&res, 1)); assert_eq!("required into module", get_str(&res, 2)); // RequireWithFileAmbiguity - let res = run_require(&lua, "./require/without_config/ambiguous_file_requirer"); + let res = run_require( + &lua, + "./tests/luau/require/without_config/ambiguous_file_requirer", + ); assert!(res.is_err()); assert!((res.unwrap_err().to_string()) .contains("could not resolve child component \"dependency\" (ambiguous)")); // RequireWithDirectoryAmbiguity - let res = run_require(&lua, "./require/without_config/ambiguous_directory_requirer"); + let res = run_require( + &lua, + "./tests/luau/require/without_config/ambiguous_directory_requirer", + ); assert!(res.is_err()); assert!((res.unwrap_err().to_string()) .contains("could not resolve child component \"dependency\" (ambiguous)")); // CheckCachedResult - let res = run_require(&lua, "./require/without_config/validate_cache").unwrap(); + let res = run_require(&lua, "./tests/luau/require/without_config/validate_cache").unwrap(); assert!(res.is_table()); } @@ -170,15 +176,19 @@ fn test_require_with_config() { let lua = Lua::new(); // RequirePathWithAlias - let res = run_require(&lua, "./require/with_config/src/alias_requirer").unwrap(); + let res = run_require(&lua, "./tests/luau/require/with_config/src/alias_requirer").unwrap(); assert_eq!("result from dependency", get_str(&res, 1)); // RequirePathWithParentAlias - let res = run_require(&lua, "./require/with_config/src/parent_alias_requirer").unwrap(); + let res = run_require(&lua, "./tests/luau/require/with_config/src/parent_alias_requirer").unwrap(); assert_eq!("result from other_dependency", get_str(&res, 1)); // RequirePathWithAliasPointingToDirectory - let res = run_require(&lua, "./require/with_config/src/directory_alias_requirer").unwrap(); + let res = run_require( + &lua, + "./tests/luau/require/with_config/src/directory_alias_requirer", + ) + .unwrap(); assert_eq!("result from subdirectory_dependency", get_str(&res, 1)); // RequireAliasThatDoesNotExist