Files
jpdebug/runners/luadebug.lua

116 lines
2.8 KiB
Lua

local core = require "core"
local process = require "process"
-- tiny helpers
local function dirname(p) return p:match("^(.*)[/\\]") or "" end
local function join(a, b) return (a:sub(-1) == "/" and a or (a .. "/")) .. b end
-- returns absolute path to the plugin root (…/jpdebug)
local function get_plugin_root()
-- debug.getinfo(1, "S").source gives "@/full/path/to/this/file.lua"
local src = debug.getinfo(1, "S").source
if src:sub(1, 1) == "@" then src = src:sub(2) end
local here = dirname(src) -- …/jpdebug/runners
return dirname(here) -- …/jpdebug
end
-- Main lua process spawner
local function spawn_lua_process(entry, lua, cwd, env)
local host = "localhost"
local port = 8172
-- Resolve vendor/?.lua so "require('mobdebug')" finds the bundled file
local vendor_glob = join(get_plugin_root(), "vendor/?.lua")
-- Build the inline lua launcher
local dbg_call = string.format([[
local ok, m = pcall(require, "mobdebug"); if ok then
print("Connecting to "..%q..":"..tostring(%d))
local connected = m.start(%q, %d)
end
]], host, port, host, port)
local launcher = string.format([[
package.path = %q .. ";" .. package.path
%s
dofile(%q)
]], vendor_glob, dbg_call, entry)
-- Spawn the process
local cmd = {}
if type(lua) == "table" then
for i=1, #lua do table.insert(cmd, lua[i]) end
else
table.insert(cmd, lua)
end
table.insert(cmd, "-e")
table.insert(cmd, launcher)
local proc = process.start(cmd, {
cwd = cwd,
env = env,
stdout = process.REDIRECT_PIPE,
stderr = process.REDIRECT_PIPE,
})
return proc
end
---@class LDB
local LDB = {
name = "luadebug"
}
---@param target table Target table
---@param name string Name of the target to run
---@praam debuginfo table Debugging information
---@return process|nil
function LDB:run(target, name, debuginfo)
if target.entry == nil then
core.error("[jpdebug][luadebug] target.entry is required")
return
end
local entry = target.entry
local lua = target.lua or "lua"
local cwd = target.cwd or "."
local env = target.env or {}
-- spawn the main lua process
local proc = spawn_lua_process(entry, lua, cwd, env)
if proc == nil then
core.error("[jpdebug][luadebug] Failed to start "..entry)
return nil
end
return {
luaproc=proc
}
end
-- Wait untill it ends, possibly with timeout
function LDB:wait(proc, time)
return proc.luaproc:wait(time)
end
-- Read the stdout, returns nil if process has stopped
function LDB:read_stdout(proc)
local sl = proc.luaproc:read_stdout()
return sl
end
-- Read the stderr
function LDB:read_stderr(proc)
local sl = proc.luaproc:read_stderr()
return sl
end
-- Kill the process
function LDB:kill(proc)
proc.luaproc:kill()
end
-- Terminate the process
function LDB:terminate(proc)
proc.luaproc:terminate()
end
return LDB