Add support for tilde home dir substitution in process.spawn

This commit is contained in:
Filip Tibell 2023-02-09 22:59:17 +01:00
parent 7699d06647
commit f18fe48008
No known key found for this signature in database
5 changed files with 110 additions and 14 deletions

View file

@ -7,11 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased ## 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 ### Changed
- `NetRequest` query parameters value has been changed to be a table of key-value pairs similar to `process.env`. - `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. 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 ## `0.3.0` - February 6th, 2023
### Added ### Added

63
Cargo.lock generated
View file

@ -161,6 +161,26 @@ dependencies = [
"zeroize", "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]] [[package]]
name = "encode_unicode" name = "encode_unicode"
version = "0.3.6" version = "0.3.6"
@ -310,6 +330,17 @@ dependencies = [
"slab", "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]] [[package]]
name = "h2" name = "h2"
version = "0.3.15" version = "0.3.15"
@ -575,6 +606,7 @@ dependencies = [
"anyhow", "anyhow",
"console", "console",
"dialoguer", "dialoguer",
"directories",
"hyper", "hyper",
"lazy_static", "lazy_static",
"mlua", "mlua",
@ -822,6 +854,17 @@ dependencies = [
"bitflags", "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]] [[package]]
name = "regex" name = "regex"
version = "1.7.1" version = "1.7.1"
@ -1118,6 +1161,26 @@ dependencies = [
"winapi-util", "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]] [[package]]
name = "tinyvec" name = "tinyvec"
version = "1.6.0" version = "1.6.0"

View file

@ -22,6 +22,7 @@ reqwest.workspace = true
console = "0.15.5" console = "0.15.5"
dialoguer = "0.10.3" dialoguer = "0.10.3"
directories = "4.0.1"
lazy_static = "1.4.0" lazy_static = "1.4.0"
pin-project = "1.0.12" pin-project = "1.0.12"
os_str_bytes = "6.4.1" os_str_bytes = "6.4.1"

View file

@ -1,5 +1,6 @@
use std::{collections::HashMap, env, path::PathBuf, process::Stdio}; use std::{collections::HashMap, env, path::PathBuf, process::Stdio};
use directories::UserDirs;
use mlua::prelude::*; use mlua::prelude::*;
use os_str_bytes::RawOsString; use os_str_bytes::RawOsString;
use tokio::process::Command; use tokio::process::Command;
@ -127,6 +128,12 @@ async fn process_spawn<'a>(
LuaValue::Nil => {} LuaValue::Nil => {}
LuaValue::String(s) => { LuaValue::String(s) => {
cwd = PathBuf::from(s.to_string_lossy().to_string()); 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() { if !cwd.exists() {
return Err(LuaError::RuntimeError( return Err(LuaError::RuntimeError(
"Invalid value for option 'cwd' - path does not exist".to_string(), "Invalid value for option 'cwd' - path does not exist".to_string(),
@ -218,7 +225,7 @@ async fn process_spawn<'a>(
cmd 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.current_dir(child_cwd);
cmd.envs(child_envs); cmd.envs(child_envs);
// Spawn the child process // Spawn the child process

View file

@ -54,20 +54,22 @@ process.spawn("ls", {}, {
local pwdAfter = process.spawn("pwd").stdout local pwdAfter = process.spawn("pwd").stdout
assert(pwdBefore == pwdAfter, "Current working directory changed after running child process") 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 homeDir1 = process.spawn("echo $HOME", nil, {
local echoResult = process.spawn("echo", { shell = true,
'"$TEST_VAR"', }).stdout
}, { local homeDir2 = process.spawn("pwd", nil, {
env = { TEST_VAR = echoMessage }, shell = true,
shell = "bash", cwd = "~",
stdio = "inherit", }).stdout
})
assert( assert(#homeDir1 > 0, "Home dir from echo was empty")
echoResult.stdout == (echoMessage .. "\n"), -- Note that echo adds a newline assert(#homeDir2 > 0, "Home dir from pwd was empty")
"Inheriting stdio did not return proper output" assert(homeDir1 == homeDir2, "Home dirs did not match when performing tilde substitution")
)
--[[ --[[
Spawning a process should not block any lua thread(s) Spawning a process should not block any lua thread(s)
@ -97,3 +99,18 @@ assert(
(sleepElapsed >= SLEEP_DURATION) and (sleepElapsed < SLEEP_DURATION * 1.5), (sleepElapsed >= SLEEP_DURATION) and (sleepElapsed < SLEEP_DURATION * 1.5),
"Coroutine yielded the main lua thread during process yield" "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"
)