Initial commit
This commit is contained in:
9
lua/cave/python/init.lua
Normal file
9
lua/cave/python/init.lua
Normal file
@@ -0,0 +1,9 @@
|
||||
---@class cave.Python
|
||||
local Python = {
|
||||
Interpreter = require "cave.python.interpreter",
|
||||
Module = require "cave.python.module",
|
||||
Runnable = require "cave.python.runnable",
|
||||
Script = require "cave.python.script",
|
||||
}
|
||||
|
||||
return Python
|
||||
236
lua/cave/python/interpreter.lua
Normal file
236
lua/cave/python/interpreter.lua
Normal file
@@ -0,0 +1,236 @@
|
||||
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
|
||||
69
lua/cave/python/module.lua
Normal file
69
lua/cave/python/module.lua
Normal file
@@ -0,0 +1,69 @@
|
||||
local Runnable = require "cave.python.runnable"
|
||||
local Context = require "cave.context"
|
||||
local Meta = require "cave.meta"
|
||||
|
||||
local Str = Meta.String
|
||||
local validate = Meta.validate
|
||||
|
||||
---@class cave.Python.Module : cave.Python.Runnable
|
||||
---@field name string
|
||||
local Module = Meta.derive("Python.Module", Runnable)
|
||||
|
||||
function Module:module() return self end
|
||||
|
||||
---@class cave.Python.Module.Factory : cave.Python.Runnable.Factory
|
||||
---@field name_ string
|
||||
local Factory = Meta.derive("Python.Module.Factory", Runnable.Factory)
|
||||
|
||||
---@param name string
|
||||
---@param context cave.Context
|
||||
function Factory:init(name, context)
|
||||
Runnable.Factory.init(self, context)
|
||||
self.name_ = name
|
||||
end
|
||||
|
||||
---@param other cave.Python.Module.Factory
|
||||
function Factory:copy_from(other)
|
||||
Runnable.Factory.copy_from(self, other)
|
||||
self.name_ = other.name_
|
||||
end
|
||||
|
||||
---@param name string
|
||||
---@param context cave.Context
|
||||
---@return cave.Python.Module.Factory
|
||||
function Factory.new(name, context)
|
||||
validate { name = { name, Str }, context = { context, Context } }
|
||||
local factory = setmetatable({}, Factory)
|
||||
factory:init(name, context)
|
||||
return factory
|
||||
end
|
||||
|
||||
---@return cave.Python.Module.Factory
|
||||
function Factory:copy()
|
||||
local factory = setmetatable({}, Factory)
|
||||
factory:copy_from(self)
|
||||
return factory
|
||||
end
|
||||
|
||||
---@return string
|
||||
function Factory:get_id() return self.id_ or self:get_name() end
|
||||
|
||||
---@return string
|
||||
function Factory:get_name() return self.name_ end
|
||||
|
||||
---@param module cave.Python.Module
|
||||
function Factory:init_module(module)
|
||||
self:init_runnable(module)
|
||||
module.name = self:get_name()
|
||||
end
|
||||
|
||||
---@return cave.Python.Module
|
||||
function Factory:build()
|
||||
local module = setmetatable({}, Module)
|
||||
self:init_module(module)
|
||||
return module
|
||||
end
|
||||
|
||||
Module.Factory = Factory
|
||||
|
||||
return Module
|
||||
31
lua/cave/python/runnable.lua
Normal file
31
lua/cave/python/runnable.lua
Normal file
@@ -0,0 +1,31 @@
|
||||
local Meta = require "cave.meta"
|
||||
local Task = require "cave.task"
|
||||
|
||||
---@class cave.Python.Runnable : cave.Task
|
||||
local Runnable = Meta.derive("Python.Runnable", Task)
|
||||
|
||||
---@return cave.Python.Script?
|
||||
---@return cave.Python.Module?
|
||||
function Runnable:concrete() return self:script(), self:module() end
|
||||
|
||||
---@return cave.Python.Script?
|
||||
function Runnable:script() end
|
||||
|
||||
---@return cave.Python.Module?
|
||||
function Runnable:module() end
|
||||
|
||||
---@class cave.Python.Runnable.Factory : cave.Task.Factory
|
||||
local Factory = Meta.derive("Python.Runnable.Factory", Task.Factory)
|
||||
|
||||
---@return cave.Python.Runnable
|
||||
function Factory:build() error "Not implemented" end
|
||||
|
||||
---@return cave.Python.Runnable
|
||||
function Factory:copy() error "Not implemented" end
|
||||
|
||||
---@param runnable cave.Python.Runnable
|
||||
function Factory:init_runnable(runnable) self:init_task(runnable) end
|
||||
|
||||
Runnable.Factory = Factory
|
||||
|
||||
return Runnable
|
||||
76
lua/cave/python/script.lua
Normal file
76
lua/cave/python/script.lua
Normal file
@@ -0,0 +1,76 @@
|
||||
local Runnable = require "cave.python.runnable"
|
||||
local Meta = require "cave.meta"
|
||||
local Path = require "cave.path"
|
||||
local Context = require "cave.context"
|
||||
|
||||
local validate = Meta.validate
|
||||
|
||||
---@class cave.Python.Script : cave.Python.Runnable
|
||||
---@field file cave.Path
|
||||
local Script = Meta.derive("Python.Script", Runnable)
|
||||
|
||||
---@return cave.Python.Script
|
||||
function Script:script() return self end
|
||||
|
||||
---@return string
|
||||
function Script:valid_file()
|
||||
assert(self.file:is_file())
|
||||
return self.file:tostring()
|
||||
end
|
||||
|
||||
---@class cave.Python.Script.Factory : cave.Python.Runnable.Factory
|
||||
---@field file_ cave.Path
|
||||
local Factory = Meta.derive("Python.Script.Factory", Runnable.Factory)
|
||||
|
||||
---@param file cave.Path
|
||||
---@param context cave.Context
|
||||
function Factory:init(file, context)
|
||||
Runnable.Factory.init(self, context)
|
||||
self.file_ = file
|
||||
end
|
||||
|
||||
---@param other cave.Python.Script.Factory
|
||||
function Factory:copy_from(other)
|
||||
Runnable.Factory.copy_from(self, other)
|
||||
self.file_ = other.file_:copy()
|
||||
end
|
||||
|
||||
---@param file cave.Path
|
||||
---@param context cave.Context
|
||||
---@return cave.Python.Script.Factory
|
||||
function Factory.new(file, context)
|
||||
validate { file = { file, Path }, context = { context, Context } }
|
||||
local factory = setmetatable({}, Factory)
|
||||
factory:init(file, context)
|
||||
return factory
|
||||
end
|
||||
|
||||
---@return cave.Python.Script.Factory
|
||||
function Factory:copy()
|
||||
local factory = setmetatable({}, Factory)
|
||||
factory:copy_from(self)
|
||||
return factory
|
||||
end
|
||||
|
||||
---@return string
|
||||
function Factory:get_id() return self.id_ or ("[%s]"):format(self:get_file()) end
|
||||
|
||||
---@return cave.Path
|
||||
function Factory:get_file() return self.file_ end
|
||||
|
||||
---@param script cave.Python.Script
|
||||
function Factory:init_script(script)
|
||||
self:init_runnable(script)
|
||||
script.file = self:get_file()
|
||||
end
|
||||
|
||||
---@return cave.Python.Script
|
||||
function Factory:build()
|
||||
local script = setmetatable({}, Script)
|
||||
self:init_script(script)
|
||||
return script
|
||||
end
|
||||
|
||||
Script.Factory = Factory
|
||||
|
||||
return Script
|
||||
Reference in New Issue
Block a user