Skip to content

Commit

Permalink
feat(experimental): API for installing rockspec dependencies
Browse files Browse the repository at this point in the history
  • Loading branch information
mrcjkb committed Sep 3, 2024
1 parent 79123d6 commit 06a30ca
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 19 deletions.
7 changes: 5 additions & 2 deletions doc/rocks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -390,8 +390,11 @@ MutRocksTomlRef *MutRocksTomlRef*
rock_handler.on_success.Opts *rock_handler.on_success.Opts*

Fields: ~
{action} ("install"|"prune")
{rock} (Rock)
{action} ("install"|"prune")
{rock} (Rock)
The rock stub to install or prune.
{dependencies?} (string[])
The dependency constraints (e.g. { 'foo >= 1.0.0', }).


rock_handler_callback *rock_handler_callback*
Expand Down
5 changes: 5 additions & 0 deletions lua/rocks/api/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,12 @@ end

---@class rock_handler.on_success.Opts
---@field action 'install' | 'prune'
---
---The rock stub to install or prune.
---@field rock Rock
---
---The dependency constraints (e.g. { 'foo >= 1.0.0', }).
---@field dependencies? string[]

---@alias rock_handler_callback fun(on_progress: fun(message: string), on_error: fun(message: string), on_success?: fun(opts: rock_handler.on_success.Opts))
---@brief [[
Expand Down
2 changes: 2 additions & 0 deletions lua/rocks/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ source = {
dir = 'luarocks-stub-548853648d7cff7e0d959ff95209e8aa97a793bc',
}
dependencies = %s
build = {
type = "builtin",
modules = {}
Expand Down
39 changes: 26 additions & 13 deletions lua/rocks/operations/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,10 @@ end

---Removes a rock, and recursively removes its dependencies
---if they are no longer needed.
---@type async fun(name: string, keep: string[], progress_handle?: ProgressHandle): boolean
---@type async fun(name: string, keep?: string[], progress_handle?: ProgressHandle): boolean
helpers.remove_recursive = nio.create(function(name, keep, progress_handle)
---@diagnostic disable-next-line: invisible
keep = keep or nio.fn.keys(config.get_user_rocks())
---@cast name string
local dependencies = state.rock_dependencies(name)
local future = helpers.remove(name, progress_handle)
Expand All @@ -202,16 +204,24 @@ helpers.remove_recursive = nio.create(function(name, keep, progress_handle)
return false
end
local removable_rocks = state.query_removable_rocks()
local removable_dependencies = vim.iter(dependencies)
:filter(function(rock_name)
return vim.list_contains(removable_rocks, rock_name) and not vim.list_contains(keep, rock_name)
end)
:totable()
for _, dep in pairs(removable_dependencies) do
if vim.list_contains(removable_rocks, dep.name) then
success = success and helpers.remove_recursive(dep.name, keep, progress_handle)
---@type rock_name[]
local removable_dependencies = vim.iter(dependencies):fold({}, function(acc, rock_name)
if vim.list_contains(removable_rocks, rock_name) and not vim.list_contains(keep, rock_name) then
table.insert(acc, rock_name)
end
end
return acc
end)
success = vim.iter(removable_dependencies):fold(
true,
---@param acc boolean
---@param dep rock_name
function(acc, dep)
if vim.list_contains(removable_rocks, dep) then
acc = acc and helpers.remove_recursive(dep, keep, progress_handle)
end
return acc
end
)
return success
end, 3)

Expand Down Expand Up @@ -341,7 +351,11 @@ helpers.manage_rock_stub = nio.create(function(opts)
if opts.action == "install" then
local rock = opts.rock
log.info(("Installing stub %s"):format(vim.inspect(rock)))
local rockspec_content = constants.STUB_ROCKSPEC_TEMPLATE:format(rock.name, rock.version)
local rockspec_content = constants.STUB_ROCKSPEC_TEMPLATE:format(
rock.name,
rock.version,
opts.dependencies and vim.inspect(opts.dependencies) or "{}"
)
nio.scheduler()
local tempdir = vim.fn.tempname()
local ok = fs.mkdir_p(tempdir)
Expand All @@ -367,8 +381,7 @@ helpers.manage_rock_stub = nio.create(function(opts)
)
future.wait()
elseif opts.action == "prune" then
local future = helpers.remove(opts.rock.name)
pcall(future.wait)
helpers.remove_recursive(opts.rock.name)
end
end)

Expand Down
5 changes: 1 addition & 4 deletions lua/rocks/operations/prune.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,7 @@ prune.prune = function(rock_name)
end
local success = true -- initialised for handlers
if helpers.is_installed(rock_name) then
local user_rock_names =
---@diagnostic disable-next-line: invisible
nio.fn.keys(vim.tbl_deep_extend("force", user_config.rocks or {}, user_config.plugins or {}))
success = helpers.remove_recursive(rock_name, user_rock_names, progress_handle)
success = helpers.remove_recursive(rock_name, nil, progress_handle)
end
-- NOTE: We always delegate to handlers, even if the rock is installed,
-- so we can allow them to manage luarocks packages.
Expand Down
6 changes: 6 additions & 0 deletions spec/operations/helpers_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,17 +56,23 @@ describe("operations.helpers", function()
helpers.manage_rock_stub({
rock = { name = "stub.nvim", version = "1.0.0" },
action = "install",
dependencies = { "pathlib.nvim == 2.2.3" },
})
installed_rocks = state.installed_rocks()
assert.same({
name = "stub.nvim",
version = "1.0.0",
}, installed_rocks["stub.nvim"])
assert.same({
name = "pathlib.nvim",
version = "2.2.3",
}, installed_rocks["pathlib.nvim"])
helpers.manage_rock_stub({
rock = { name = "stub.nvim", version = "1.0.0" },
action = "prune",
})
installed_rocks = state.installed_rocks()
assert.is_nil(installed_rocks["stub.nvim"])
assert.is_nil(installed_rocks["pathlib.nvim"])
end)
end)

0 comments on commit 06a30ca

Please sign in to comment.