118 lines
2.9 KiB
Lua
118 lines
2.9 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
|
|
local nowait = false
|
|
|
|
-- 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)
|
|
if not connected and %s then m.off() end
|
|
end
|
|
]], host, port, host, port, nowait and "true" or "false")
|
|
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 {}
|
|
|
|
-- TODO spawn the mobdebugger
|
|
|
|
-- 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)
|
|
return proc.luaproc:read_stdout()
|
|
end
|
|
|
|
-- Read the stderr
|
|
function LDB:read_stderr(proc)
|
|
return proc.luaproc:read_stderr()
|
|
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
|