diff --git a/Cargo.lock b/Cargo.lock index 951790c..3e3a753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1554,8 +1554,6 @@ dependencies = [ "lune-utils", "mlua", "mlua-luau-scheduler 0.0.1", - "path-clean", - "pathdiff", "tokio", ] @@ -1648,8 +1646,11 @@ dependencies = [ name = "lune-utils" version = "0.8.3" dependencies = [ + "dunce", "mlua", "once_cell", + "path-clean", + "pathdiff", ] [[package]] diff --git a/crates/lune-std/Cargo.toml b/crates/lune-std/Cargo.toml index 883cdc0..2293e35 100644 --- a/crates/lune-std/Cargo.toml +++ b/crates/lune-std/Cargo.toml @@ -39,9 +39,6 @@ task = ["dep:lune-std-task"] mlua = "0.9.7" mlua-luau-scheduler = "0.0.1" -path-clean = "1.0" -pathdiff = "0.2" - tokio = { version = "1", default-features = false, features = ["fs"] } lune-utils = { version = "0.8.3", path = "../lune-utils" } diff --git a/crates/lune-std/src/globals/require/alias.rs b/crates/lune-std/src/globals/require/alias.rs index 0818f88..38a822a 100644 --- a/crates/lune-std/src/globals/require/alias.rs +++ b/crates/lune-std/src/globals/require/alias.rs @@ -2,7 +2,7 @@ use mlua::prelude::*; use lune_utils::{ luaurc::LuauRc, - paths::{make_absolute_and_clean, CWD}, + path::{clean_path_and_make_absolute, diff_path, get_current_dir}, }; use super::context::*; @@ -19,7 +19,7 @@ where { let alias = alias.to_ascii_lowercase(); - let parent = make_absolute_and_clean(source) + let parent = clean_path_and_make_absolute(source) .parent() .expect("how did a root path end up here..") .to_path_buf(); @@ -66,7 +66,7 @@ where // We now have our aliased path, our path require function just needs it // in a slightly different format with both absolute + relative to cwd let abs_path = luaurc.find_alias(&alias).unwrap().join(path); - let rel_path = pathdiff::diff_paths(&abs_path, CWD.as_path()).ok_or_else(|| { + let rel_path = diff_path(&abs_path, get_current_dir()).ok_or_else(|| { LuaError::runtime(format!("failed to find relative path for alias '{alias}'")) })?; diff --git a/crates/lune-std/src/globals/require/context.rs b/crates/lune-std/src/globals/require/context.rs index 102b804..8e2ded3 100644 --- a/crates/lune-std/src/globals/require/context.rs +++ b/crates/lune-std/src/globals/require/context.rs @@ -15,6 +15,8 @@ use tokio::{ }, }; +use lune_utils::path::{clean_path, clean_path_and_make_absolute}; + use crate::library::LuneStandardLibrary; /** @@ -64,12 +66,8 @@ impl RequireContext { .ok_or_else(|| LuaError::runtime("Failed to get parent path of source"))? .join(path.as_ref()); - let rel_path = path_clean::clean(path); - let abs_path = if rel_path.is_absolute() { - rel_path.to_path_buf() - } else { - CWD.join(&rel_path) - }; + let abs_path = clean_path_and_make_absolute(path); + let rel_path = clean_path(path); Ok((abs_path, rel_path)) } diff --git a/crates/lune-utils/Cargo.toml b/crates/lune-utils/Cargo.toml index b31ea42..e3a2fed 100644 --- a/crates/lune-utils/Cargo.toml +++ b/crates/lune-utils/Cargo.toml @@ -13,4 +13,7 @@ workspace = true [dependencies] mlua = { version = "0.9.7", features = ["async"] } +dunce = "1.0" once_cell = "1.17" +path-clean = "1.0" +pathdiff = "0.2" diff --git a/crates/lune-utils/src/lib.rs b/crates/lune-utils/src/lib.rs index cd9136e..38738cc 100644 --- a/crates/lune-utils/src/lib.rs +++ b/crates/lune-utils/src/lib.rs @@ -3,5 +3,7 @@ mod table_builder; mod version_string; +pub mod path; + pub use self::table_builder::TableBuilder; pub use self::version_string::get_version_string; diff --git a/crates/lune-utils/src/path.rs b/crates/lune-utils/src/path.rs new file mode 100644 index 0000000..a510e22 --- /dev/null +++ b/crates/lune-utils/src/path.rs @@ -0,0 +1,81 @@ +use std::{ + env::{current_dir, current_exe}, + path::{Path, PathBuf}, + sync::Arc, +}; + +use once_cell::sync::Lazy; +use path_clean::PathClean; + +static CWD: Lazy> = Lazy::new(create_cwd); +static EXE: Lazy> = Lazy::new(create_exe); + +fn create_cwd() -> Arc { + let cwd = current_dir().expect("failed to find current working directory"); + dunce::canonicalize(cwd) + .expect("failed to canonicalize current working directory") + .into() +} + +fn create_exe() -> Arc { + let exe = current_exe().expect("failed to find current executable"); + dunce::canonicalize(exe) + .expect("failed to canonicalize current executable") + .into() +} + +/** + Gets the current working directory as an absolute path. + + This absolute path is canonicalized and does not contain any `.` or `..` + components, and it is also in a friendly (non-UNC) format. +*/ +#[must_use] +pub fn get_current_dir() -> Arc { + Arc::clone(&CWD) +} + +/** + Gets the path to the current executable as an absolute path. + + This absolute path is canonicalized and does not contain any `.` or `..` + components, and it is also in a friendly (non-UNC) format. +*/ +#[must_use] +pub fn get_current_exe() -> Arc { + Arc::clone(&EXE) +} + +/** + Diffs two paths against each other. + + See the [`pathdiff`] crate for more information on what diffing paths does. +*/ +pub fn diff_path(path: impl AsRef, base: impl AsRef) -> Option { + pathdiff::diff_paths(path, base) +} + +/** + Cleans a path. + + See the [`path_clean`] crate for more information on what cleaning a path does. +*/ +pub fn clean_path(path: impl AsRef) -> PathBuf { + path.as_ref().clean() +} + +/** + Makes a path absolute and then cleans it. + + Relative paths are resolved against the current working directory. + + See the [`path_clean`] crate for more information on what cleaning a path does. +*/ +pub fn clean_path_and_make_absolute(path: impl AsRef) -> PathBuf { + let path = path.as_ref(); + if path.is_relative() { + CWD.join(path).clean() + } else { + path.clean() + } +}