237 lines
6.8 KiB
Lua
237 lines
6.8 KiB
Lua
local Context = require "cave.context"
|
|
local Meta = require "cave.meta"
|
|
local Module = require "cave.python.module"
|
|
local Path = require "cave.path"
|
|
local Runnable = require "cave.python.runnable"
|
|
local Script = require "cave.python.script"
|
|
local Task = require "cave.task"
|
|
|
|
local List = Meta.List
|
|
local Map = Meta.Map
|
|
local Str = Meta.String
|
|
local validate = Meta.validate
|
|
|
|
---@class cave.Python.Interpreter
|
|
---@field id string
|
|
---@field path cave.Path
|
|
---@field args string[]
|
|
---@field env table<string, string>
|
|
---@field runnables table<string, cave.Python.Runnable>
|
|
---@field context cave.Context
|
|
local Interpreter = Meta.derive "Python.Interpreter"
|
|
|
|
---@return string
|
|
function Interpreter:valid_path() return self.path:executable():tostring() end
|
|
|
|
---@return overseer.TemplateDefinition[]
|
|
function Interpreter:templates()
|
|
local templates = {}
|
|
for _, runnable in pairs(self.runnables) do
|
|
vim.list_extend(templates, { self:run_template(runnable), self:debug_template(runnable) })
|
|
end
|
|
return templates
|
|
end
|
|
|
|
---@param runnable cave.Python.Runnable
|
|
---@return overseer.TemplateDefinition
|
|
function Interpreter:run_template(runnable)
|
|
local name = ("python.%s.run.%s"):format(self.id, runnable.id)
|
|
local script, module = runnable:concrete()
|
|
local args = vim.list_extend({}, self.args)
|
|
vim.list_extend(
|
|
args,
|
|
(script and { script:valid_file() }) or (module and { "-m", module.name }) or error "Unsupported runnable"
|
|
)
|
|
vim.list_extend(args, runnable.args)
|
|
local template_definition = {
|
|
name = name,
|
|
builder = function()
|
|
---@type overseer.TaskDefinition
|
|
local task_definition = {
|
|
name = name,
|
|
cmd = { self:valid_path() },
|
|
args = args,
|
|
env = vim.tbl_extend("keep", runnable.env, self.env),
|
|
cwd = runnable:valid_cwd(),
|
|
components = { { "defaults" } },
|
|
}
|
|
return task_definition
|
|
end,
|
|
params = {},
|
|
tags = { Task.Tag.Run },
|
|
}
|
|
return template_definition
|
|
end
|
|
|
|
---@param runnable cave.Python.Runnable
|
|
---@return overseer.TemplateDefinition
|
|
function Interpreter:debug_template(runnable)
|
|
local name = ("python.%s.debug.%s"):format(self.id, runnable.id)
|
|
local template_definition = {}
|
|
template_definition.builder = function()
|
|
local script, module = runnable:concrete()
|
|
|
|
---@type DebugpyLaunchConfig
|
|
local dap_config = {
|
|
name = name,
|
|
type = "python",
|
|
request = "launch",
|
|
module = module and module.name,
|
|
program = script and script:valid_file(),
|
|
cwd = runnable:valid_cwd(),
|
|
args = runnable.args,
|
|
env = vim.tbl_extend("keep", runnable.env, self.env),
|
|
python = vim.list_extend({ self:valid_path() }, self.args),
|
|
}
|
|
|
|
if vim.tbl_isempty(dap_config.env) then dap_config.env = nil end
|
|
|
|
---@type overseer.TaskDefinition
|
|
local task_definition = {
|
|
name = name,
|
|
cmd = {},
|
|
components = { { "defaults" }, { "dap", config = dap_config } },
|
|
}
|
|
return task_definition
|
|
end
|
|
template_definition.params = {}
|
|
template_definition.tags = { Task.Tag.Debug }
|
|
template_definition.name = name
|
|
return template_definition
|
|
end
|
|
|
|
---@class cave.Python.Interpreter.Factory
|
|
---@field id_ string?
|
|
---@field path_ cave.Path?
|
|
---@field args_ string[]
|
|
---@field env_ table<string, string>
|
|
---@field runnables_ cave.Python.Runnable.Factory[]
|
|
---@field context_ cave.Context
|
|
local Factory = Meta.derive "Python.Interpreter.Factory"
|
|
|
|
---@param context cave.Context
|
|
function Factory:init(context)
|
|
self.args_ = {}
|
|
self.env_ = {}
|
|
self.runnables_ = {}
|
|
self.context_ = context
|
|
end
|
|
|
|
---@param context cave.Context
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory.new(context)
|
|
validate { context = { context, Context } }
|
|
local factory = setmetatable({}, Factory)
|
|
factory:init(context)
|
|
return factory
|
|
end
|
|
|
|
---@return string
|
|
function Factory:get_id() return self.id_ or "python" end
|
|
|
|
---@return cave.Path
|
|
function Factory:get_path() return self.path_ or Path.new "python" end
|
|
|
|
---@return string[]
|
|
function Factory:get_args() return self.args_ end
|
|
|
|
---@return table<string, string>
|
|
function Factory:get_env() return self.env_ end
|
|
|
|
---@return cave.Python.Runnable.Factory[]
|
|
function Factory:get_runnables() return self.runnables_ end
|
|
|
|
---@param id string
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory:id(id)
|
|
validate { id = { id, Str } }
|
|
self.id_ = id
|
|
return self
|
|
end
|
|
|
|
---@param path_like cave.PathLike
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory:path(path_like)
|
|
validate { path_like = { path_like, Path.Like } }
|
|
self.path_ = Path.like(path_like)
|
|
return self
|
|
end
|
|
|
|
---@param args string[]
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory:args(args)
|
|
validate { args = { args, List(Str) } }
|
|
vim.list_extend(self.args_, args)
|
|
return self
|
|
end
|
|
|
|
---@param arg string
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory:arg(arg) return self:args { arg } end
|
|
|
|
---@param env table<string, string>
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory:env(env)
|
|
validate { env = { env, Map(Str, Str) } }
|
|
vim.tbl_extend("error", self.env_, env)
|
|
return self
|
|
end
|
|
|
|
---@param name string
|
|
---@return cave.Python.Module.Factory
|
|
function Factory:module(name)
|
|
validate { name = { name, Str } }
|
|
local module_factory = Module.Factory.new(name, self.context_)
|
|
table.insert(self.runnables_, module_factory)
|
|
return module_factory
|
|
end
|
|
|
|
---@param file_path_like cave.PathLike
|
|
---@return cave.Python.Script.Factory
|
|
function Factory:script(file_path_like)
|
|
validate { file = { file_path_like, Path.Like } }
|
|
local file = Path.like(file_path_like)
|
|
local script_factory = Script.Factory.new(file, self.context_)
|
|
table.insert(self.runnables_, script_factory)
|
|
return script_factory
|
|
end
|
|
|
|
---@param runnables cave.Python.Runnable.Factory[]
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory:runnables(runnables)
|
|
validate { runnables = { runnables, List(Runnable.Factory) } }
|
|
for _, runnable in ipairs(runnables) do
|
|
table.insert(self.runnables_, runnable:copy())
|
|
end
|
|
return self
|
|
end
|
|
|
|
---@param runnable cave.Python.Runnable.Factory
|
|
---@return cave.Python.Interpreter.Factory
|
|
function Factory:runnable(runnable) return self:runnables { runnable } end
|
|
|
|
---@param interpreter cave.Python.Interpreter
|
|
function Factory:init_interpreter(interpreter)
|
|
interpreter.id = self:get_id()
|
|
interpreter.path = self:get_path()
|
|
interpreter.args = self:get_args()
|
|
interpreter.env = self:get_env()
|
|
interpreter.runnables = {}
|
|
for _, runnable_factory in pairs(self:get_runnables()) do
|
|
local runnable = runnable_factory:build()
|
|
assert(interpreter.runnables[runnable.id] == nil)
|
|
interpreter.runnables[runnable.id] = runnable
|
|
end
|
|
end
|
|
|
|
---@return cave.Python.Interpreter
|
|
function Factory:build()
|
|
local interpreter = setmetatable({}, Interpreter)
|
|
self:init_interpreter(interpreter)
|
|
return interpreter
|
|
end
|
|
|
|
Interpreter.Factory = Factory
|
|
|
|
return Interpreter
|