Skip to content

Commit

Permalink
feat(lib/process): update run function
Browse files Browse the repository at this point in the history
  • Loading branch information
rcarriga committed Jun 21, 2022
1 parent e8d7fa2 commit ba0a03c
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 10 deletions.
54 changes: 44 additions & 10 deletions lua/neotest/lib/process/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,62 @@ local async = require("neotest.async")

local M = {}

---Runs a process using libuv. This is designed for a simple, quick async alternative to io.popen and so will wait until
---the process exits to read the stdout/stderr. Do not use this for long running jobs or for large outputs.
---Use vim.jobstart instead.
---@async
---@return integer
---@param command string[]
---@param args table
---@field stdout bool Read stdout
---@field stderr bool Read stderr
---@return integer, table Exit code and table containing stdout/stderr keys if requested
function M.run(command, args)
args = args or {}
local stdin = vim.loop.new_pipe()
local stdout = vim.loop.new_pipe()
local stderr = vim.loop.new_pipe()
local result_code = async.wrap(vim.loop.spawn, 3)(command[1], {
local result_code
local send_exit, await_exit = async.control.channel.oneshot()

local handle, _ = vim.loop.spawn(command[1], {
stdio = { stdin, stdout, stderr },
detached = false,
args = #command > 1 and vim.list_slice(command, 2, #command) or nil,
})
}, function(code)
result_code = code
send_exit()
end)

await_exit()
handle:close()

local stdout_data, stderr_data
if args.stdout then
local send_read, await_read = async.control.channel.oneshot()
stdout:read_start(function(err, data)
assert(not err, err)
stdout_data = data
send_read()
end)
await_read()
end
if args.stderr then
local send_read, await_read = async.control.channel.oneshot()
stderr:read_start(function(err, data)
assert(not err, err)
stderr_data = data
send_read()
end)
await_read()
end

stdin:close()
stdout:close()
stderr:close()
if args.on_stdout then
stdout:read_start(args.on_stdout)
end
if args.on_stderr then
stderr:read_start(args.on_stderr)
end
return result_code
return result_code, {
stdout = stdout_data,
stderr = stderr_data,
}
end

return M
28 changes: 28 additions & 0 deletions tests/unit/lib/process/init_spec.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
local async = require("neotest.async")
local a = async.tests
local lib = require("neotest.lib")

describe("process lib", function()
describe("running a process", function()
a.it("returns exit code", function()
local result = lib.process.run({ "sh", "-c", "exit 12" })
assert.equal(12, result)
end)
a.it("records stdout", function()
local _, data = lib.process.run({ "printf", "hello" }, { stdout = true })
assert.equal("hello", data.stdout)
end)
a.it("doesn't records stdout", function()
local _, data = lib.process.run({ "printf", "hello" })
assert.Nil(data.stdout)
end)
a.it("records stderr", function()
local _, data = lib.process.run({ "sh", "-c", "printf hello >& 2" }, { stderr = true })
assert.equal("hello", data.stderr)
end)
a.it("doesn't record stderr", function()
local _, data = lib.process.run({ "sh", "-c", "printf hello >& 2" })
assert.Nil(data.stderr)
end)
end)
end)

0 comments on commit ba0a03c

Please sign in to comment.