From 6a2f5061d5951611b3bf17e62e81cda82c100dba Mon Sep 17 00:00:00 2001
From: Erica Marigold <hi@devcomp.xyz>
Date: Sun, 9 Jun 2024 21:54:56 +0530
Subject: [PATCH] chore(types + tests): update types and tests for exec

---
 .lune/hello_lune.luau                        |  2 +-
 crates/lune-std-process/src/stream.rs        | 12 ++++-----
 scripts/generate_compression_test_files.luau |  4 +--
 test.lua                                     | 26 ++++++++++++--------
 tests/datetime/formatLocalTime.luau          |  2 +-
 tests/process/exec/stdio.luau                |  2 +-
 types/process.luau                           | 10 +++++---
 7 files changed, 32 insertions(+), 26 deletions(-)

diff --git a/.lune/hello_lune.luau b/.lune/hello_lune.luau
index 197fe32..c50fd7b 100644
--- a/.lune/hello_lune.luau
+++ b/.lune/hello_lune.luau
@@ -129,7 +129,7 @@ end
 ]]
 
 print("Sending 4 pings to google 🌏")
-local result = process.spawn("ping", {
+local result = process.exec("ping", {
 	"google.com",
 	"-c 4",
 })
diff --git a/crates/lune-std-process/src/stream.rs b/crates/lune-std-process/src/stream.rs
index 74b3106..fe6bd8b 100644
--- a/crates/lune-std-process/src/stream.rs
+++ b/crates/lune-std-process/src/stream.rs
@@ -11,18 +11,16 @@ pub struct ChildProcessReader<R: AsyncRead>(pub R);
 pub struct ChildProcessWriter<W: AsyncWrite>(pub W);
 
 impl<R: AsyncRead + Unpin> ChildProcessReader<R> {
-    pub async fn read(&mut self) -> LuaResult<Vec<u8>> {
-        let mut buf = BytesMut::with_capacity(CHUNK_SIZE);
+    pub async fn read(&mut self, chunk_size: Option<usize>) -> LuaResult<Vec<u8>> {
+        let mut buf = BytesMut::with_capacity(chunk_size.unwrap_or(CHUNK_SIZE));
         self.0.read_buf(&mut buf).await?;
 
         Ok(buf.to_vec())
     }
 
     pub async fn read_to_end(&mut self) -> LuaResult<Vec<u8>> {
-        // FIXME: This yields, but should rather only return the stdout
-        // till present moment instead, so we should have our own logic
-        // instead of using read_to_end
         let mut buf = vec![];
+
         self.0.read_to_end(&mut buf).await?;
         Ok(buf)
     }
@@ -30,8 +28,8 @@ impl<R: AsyncRead + Unpin> ChildProcessReader<R> {
 
 impl<R: AsyncRead + Unpin + 'static> LuaUserData for ChildProcessReader<R> {
     fn add_methods<'lua, M: LuaUserDataMethods<'lua, Self>>(methods: &mut M) {
-        methods.add_async_method_mut("read", |lua, this, ()| async {
-            Ok(lua.create_buffer(this.read().await?))
+        methods.add_async_method_mut("read", |lua, this, chunk_size: Option<usize>| async move {
+            Ok(lua.create_buffer(this.read(chunk_size).await?))
         });
 
         methods.add_async_method_mut("readToEnd", |lua, this, ()| async {
diff --git a/scripts/generate_compression_test_files.luau b/scripts/generate_compression_test_files.luau
index 954929a..ce7ac82 100644
--- a/scripts/generate_compression_test_files.luau
+++ b/scripts/generate_compression_test_files.luau
@@ -108,7 +108,7 @@ local BIN_ZLIB = if process.os == "macos" then "/opt/homebrew/bin/pigz" else "pi
 
 local function checkInstalled(program: string, args: { string }?)
 	print("Checking if", program, "is installed")
-	local result = process.spawn(program, args)
+	local result = process.exec(program, args)
 	if not result.ok then
 		stdio.ewrite(string.format("Program '%s' is not installed\n", program))
 		process.exit(1)
@@ -123,7 +123,7 @@ checkInstalled(BIN_ZLIB, { "--version" })
 -- Run them to generate files
 
 local function run(program: string, args: { string }): string
-	local result = process.spawn(program, args)
+	local result = process.exec(program, args)
 	if not result.ok then
 		stdio.ewrite(string.format("Command '%s' failed\n", program))
 		if #result.stdout > 0 then
diff --git a/test.lua b/test.lua
index fa5e8ab..42a8621 100644
--- a/test.lua
+++ b/test.lua
@@ -1,16 +1,22 @@
 local process = require("@lune/process")
 local stdio = require("@lune/stdio")
+local task = require("@lune/task")
+local child = process.spawn("echo", { "lsp" })
+task.wait(1)
 
-local child = process.spawn("luau-lsp", { "lsp" })
 
-while true do
-    child.stdin:write("hello world")
-    local buf = child.stdout:read()
+stdio.write(buffer.tostring(child.stdout:readToEnd()))
+stdio.write(buffer.tostring(child.stdout:readToEnd()))
+stdio.write(buffer.tostring(child.stdout:readToEnd()))
 
-    if buffer.len(buf) == 0 then
-        break
-    end
+-- while true do
+--     child.stdin:write("hello world")
+--     local buf = child.stdout:read()
 
-    stdio.write(buffer.tostring(buf) .. "\n")
-    -- stdio.write(buffer.tostring(child.stderr:read() .. child.stderr:read() .. child.stderr:read() .. child.stderr:read()))
-end
\ No newline at end of file
+--     if buffer.len(buf) == 0 then
+--         break
+--     end
+
+--     stdio.write(buffer.tostring(buf) .. "\n")
+--     -- stdio.write(buffer.tostring(child.stderr:read() .. child.stderr:read() .. child.stderr:read() .. child.stderr:read()))
+-- end
\ No newline at end of file
diff --git a/tests/datetime/formatLocalTime.luau b/tests/datetime/formatLocalTime.luau
index 4e2f657..8bd000c 100644
--- a/tests/datetime/formatLocalTime.luau
+++ b/tests/datetime/formatLocalTime.luau
@@ -31,7 +31,7 @@ if not runLocaleTests then
 	return
 end
 
-local dateCmd = process.spawn("bash", { "-c", "date +\"%A, %d %B %Y\" --date='@1693068988'" }, {
+local dateCmd = process.exec("bash", { "-c", "date +\"%A, %d %B %Y\" --date='@1693068988'" }, {
 	env = {
 		LC_ALL = "fr_FR.UTF-8 ",
 	},
diff --git a/tests/process/exec/stdio.luau b/tests/process/exec/stdio.luau
index d4ef388..524713b 100644
--- a/tests/process/exec/stdio.luau
+++ b/tests/process/exec/stdio.luau
@@ -10,7 +10,7 @@ local echoResult = process.exec("echo", {
 }, {
 	env = { TEST_VAR = echoMessage },
 	shell = if IS_WINDOWS then "powershell" else "bash",
-	stdio = "inherit",
+	stdio = "inherit" :: process.SpawnOptionsStdioKind, -- FIXME: This should just work without a cast?
 })
 
 -- Windows uses \r\n (CRLF) and unix uses \n (LF)
diff --git a/types/process.luau b/types/process.luau
index 5fd2e8b..a60f1d9 100644
--- a/types/process.luau
+++ b/types/process.luau
@@ -41,7 +41,7 @@ export type SpawnOptions = {
 	* `stdin` - Optional standard input to pass to executed child process
 ]=]
 export type ExecuteOptions = SpawnOptions & {
-	stdio: (SpawnOptionsStdio | SpawnOptionsStdioKind)?,
+	stdio: (SpawnOptionsStdioKind | SpawnOptionsStdio)?,
 	stdin: string?, -- TODO: Remove this since it is now available in stdio above, breaking change
 }
 
@@ -56,12 +56,13 @@ local ChildProcessReader = {}
 --[=[
 	@within ChildProcessReader
 
-	Reads a chunk of data (8 bytes at a time) from the reader into a buffer.
-	Returns a buffer of size 0 if there is no more data to read.
+	Reads a chunk of data (specified length or a default of 8 bytes at a time) from 
+	the reader into a buffer. Returns a buffer of size 0 if there is no more data to 
+	read.
 
 	@return The buffer containing the data read from the reader
 ]=]
-function ChildProcessReader:read(): buffer
+function ChildProcessReader:read(chunkSize: number?): buffer
 	return nil :: any
 end
 
@@ -69,6 +70,7 @@ end
 	@within ChildProcessReader
 
 	Reads all the data currently present in the reader into a buffer.
+	This function will yield until the process exits.
 
 	@return The buffer containing the data read from the reader
 ]=]