From f18fe48008dbafc3f73e7f1f26417cba7e69942d Mon Sep 17 00:00:00 2001 From: Filip Tibell Date: Thu, 9 Feb 2023 22:59:17 +0100 Subject: [PATCH] Add support for tilde home dir substitution in process.spawn --- CHANGELOG.md | 8 ++++ Cargo.lock | 63 +++++++++++++++++++++++++++++ packages/lib/Cargo.toml | 1 + packages/lib/src/globals/process.rs | 9 ++++- tests/process/spawn.luau | 43 ++++++++++++++------ 5 files changed, 110 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8bc539..450071f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added + +- Setting `cwd` in the options for `process.spawn` to a path starting with a tilde (`~`) will now use a path relative to the platform-specific home / user directory. + ### Changed - `NetRequest` query parameters value has been changed to be a table of key-value pairs similar to `process.env`. If any query parameter is specified more than once in the request url, the value chosen will be the last one that was specified. +### Fixed + +- Fixed `process.spawn` blocking all lua threads if the spawned child process yields. + ## `0.3.0` - February 6th, 2023 ### Added diff --git a/Cargo.lock b/Cargo.lock index 8b57198..35cfacd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -161,6 +161,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "directories" +version = "4.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + [[package]] name = "encode_unicode" version = "0.3.6" @@ -310,6 +330,17 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + [[package]] name = "h2" version = "0.3.15" @@ -575,6 +606,7 @@ dependencies = [ "anyhow", "console", "dialoguer", + "directories", "hyper", "lazy_static", "mlua", @@ -822,6 +854,17 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" +dependencies = [ + "getrandom", + "redox_syscall", + "thiserror", +] + [[package]] name = "regex" version = "1.7.1" @@ -1118,6 +1161,26 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "thiserror" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a9cd18aa97d5c45c6603caea1da6628790b37f7a34b6ca89522331c5180fed0" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fb327af4685e4d03fa8cbcf1716380da910eeb2bb8be417e7f9fd3fb164f36f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "tinyvec" version = "1.6.0" diff --git a/packages/lib/Cargo.toml b/packages/lib/Cargo.toml index 5bab490..80e93f2 100644 --- a/packages/lib/Cargo.toml +++ b/packages/lib/Cargo.toml @@ -22,6 +22,7 @@ reqwest.workspace = true console = "0.15.5" dialoguer = "0.10.3" +directories = "4.0.1" lazy_static = "1.4.0" pin-project = "1.0.12" os_str_bytes = "6.4.1" diff --git a/packages/lib/src/globals/process.rs b/packages/lib/src/globals/process.rs index ac03491..8952425 100644 --- a/packages/lib/src/globals/process.rs +++ b/packages/lib/src/globals/process.rs @@ -1,5 +1,6 @@ use std::{collections::HashMap, env, path::PathBuf, process::Stdio}; +use directories::UserDirs; use mlua::prelude::*; use os_str_bytes::RawOsString; use tokio::process::Command; @@ -127,6 +128,12 @@ async fn process_spawn<'a>( LuaValue::Nil => {} LuaValue::String(s) => { cwd = PathBuf::from(s.to_string_lossy().to_string()); + // Substitute leading tilde (~) for the actual home dir + if cwd.starts_with("~") { + if let Some(user_dirs) = UserDirs::new() { + cwd = user_dirs.home_dir().join(cwd.strip_prefix("~").unwrap()) + } + }; if !cwd.exists() { return Err(LuaError::RuntimeError( "Invalid value for option 'cwd' - path does not exist".to_string(), @@ -218,7 +225,7 @@ async fn process_spawn<'a>( cmd } }; - // FUTURE: Implement and test for tilde (~) to home dir substitution in child_cwd + // Set dir to run in and env variables cmd.current_dir(child_cwd); cmd.envs(child_envs); // Spawn the child process diff --git a/tests/process/spawn.luau b/tests/process/spawn.luau index 042210b..2449a06 100644 --- a/tests/process/spawn.luau +++ b/tests/process/spawn.luau @@ -54,20 +54,22 @@ process.spawn("ls", {}, { local pwdAfter = process.spawn("pwd").stdout assert(pwdBefore == pwdAfter, "Current working directory changed after running child process") --- Inheriting stdio & environment variables should work +--[[ + Setting the cwd on a child process should properly + replace any leading ~ with the users real home dir +]] -local echoMessage = "Hello from child process!" -local echoResult = process.spawn("echo", { - '"$TEST_VAR"', -}, { - env = { TEST_VAR = echoMessage }, - shell = "bash", - stdio = "inherit", -}) -assert( - echoResult.stdout == (echoMessage .. "\n"), -- Note that echo adds a newline - "Inheriting stdio did not return proper output" -) +local homeDir1 = process.spawn("echo $HOME", nil, { + shell = true, +}).stdout +local homeDir2 = process.spawn("pwd", nil, { + shell = true, + cwd = "~", +}).stdout + +assert(#homeDir1 > 0, "Home dir from echo was empty") +assert(#homeDir2 > 0, "Home dir from pwd was empty") +assert(homeDir1 == homeDir2, "Home dirs did not match when performing tilde substitution") --[[ Spawning a process should not block any lua thread(s) @@ -97,3 +99,18 @@ assert( (sleepElapsed >= SLEEP_DURATION) and (sleepElapsed < SLEEP_DURATION * 1.5), "Coroutine yielded the main lua thread during process yield" ) + +-- Inheriting stdio & environment variables should work + +local echoMessage = "Hello from child process!" +local echoResult = process.spawn("echo", { + '"$TEST_VAR"', +}, { + env = { TEST_VAR = echoMessage }, + shell = "bash", + stdio = "inherit", +}) +assert( + echoResult.stdout == (echoMessage .. "\n"), -- Note that echo adds a newline + "Inheriting stdio did not return proper output" +)