diff options
| author | Saikari <[email protected]> | 2026-01-31 06:12:36 +0300 |
|---|---|---|
| committer | Saikari <[email protected]> | 2026-01-31 06:12:36 +0300 |
| commit | 6e6ea966829029f9fce91a1270d76ab8c4b0332a (patch) | |
| tree | 1f08eeb4170e121002e38737419b8ffc8b04a9c2 | |
| parent | 4630ca802874f6d45e447a7ab79c1a54b03d866a (diff) | |
add error handling for os.execv and implement tests for shell command execution
| -rw-r--r-- | tests/projects/test_stdin/xmake.lua | 95 | ||||
| -rw-r--r-- | tests/projects/test_stdin/xmake_debug.lua | 29 | ||||
| -rw-r--r-- | xmake/plugins/lua/main.lua | 10 |
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 |
