Skip to content

Commit

Permalink
feat(api): a way to recognise plugins managed by extensions as depend…
Browse files Browse the repository at this point in the history
…encies
  • Loading branch information
mrcjkb committed Aug 2, 2024
1 parent fa760c5 commit 5f37dde
Show file tree
Hide file tree
Showing 9 changed files with 100 additions and 10 deletions.
11 changes: 10 additions & 1 deletion doc/rocks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,23 @@ MutRocksTomlRef *MutRocksTomlRef*
{string} (unknown)


rock_handler.on_success.Opts *rock_handler.on_success.Opts*

Fields: ~
{action} ("install"|"prune")
{rock} (Rock)


rock_handler_callback *rock_handler_callback*

Type: ~
fun(report_progress:fun(message:string),report_error:fun(message:string))
fun(on_progress:fun(message:string),on_error:fun(message:string),on_success?:fun(opts:rock_handler.on_success.Opts))


An async callback that handles an operation on a rock.

- The `on_success` callback is optional for backward compatibility.

RockHandler *RockHandler*

Fields: ~
Expand Down
8 changes: 7 additions & 1 deletion lua/rocks/api/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,15 @@ end
---@field plugins? rock_config_table
---@field [string] unknown

---@alias rock_handler_callback fun(report_progress: fun(message: string), report_error: fun(message: string))
---@class rock_handler.on_success.Opts
---@field action 'install' | 'prune'
---@field rock Rock

---@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 [[
---An async callback that handles an operation on a rock.
---
--- - The `on_success` callback is optional for backward compatibility.
---@brief ]]

---@class RockHandler
Expand Down
15 changes: 15 additions & 0 deletions lua/rocks/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,21 @@ constants.DEV_SERVERS = {

constants.ALL_SERVERS = vim.list_extend(constants.DEV_SERVERS, constants.ROCKS_SERVERS)

constants.STUB_ROCKSPEC_TEMPLATE = [==[
package = "%s"
version = "%s-1"
source = {
url = 'https://github.com/nvim-neorocks/luarocks-stub/archive/548853648d7cff7e0d959ff95209e8aa97a793bc.zip',
dir = 'luarocks-stub-548853648d7cff7e0d959ff95209e8aa97a793bc',
}
build = {
type = "builtin",
modules = {}
}
]==]

return constants

--- constants.lua
2 changes: 1 addition & 1 deletion lua/rocks/operations/add.lua
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ add.add = function(arg_list, callback, opts)
message = message,
})
end
handler(report_progress, report_error)
handler(report_progress, report_error, helpers.manage_rock_stub)
fs.write_file_await(config.config_path, "w", tostring(user_rocks))
nio.scheduler()
progress_handle:finish()
Expand Down
10 changes: 6 additions & 4 deletions lua/rocks/operations/handlers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

local handlers = {}

local helpers = require("rocks.operations.helpers")

---@type RockHandler[]
local _handlers = {}

Expand Down Expand Up @@ -80,13 +82,13 @@ end

---Tell external handlers to prune their rocks
---@param user_rocks table<rock_name, RockSpec>
---@param report_progress fun(message: string)
---@param report_error fun(message: string)
handlers.prune_user_rocks = function(user_rocks, report_progress, report_error)
---@param on_progress fun(message: string)
---@param on_error fun(message: string)
handlers.prune_user_rocks = function(user_rocks, on_progress, on_error)
for _, handler in pairs(_handlers) do
local callback = type(handler.get_prune_callback) == "function" and handler.get_prune_callback(user_rocks)
if callback then
callback(report_progress, report_error)
callback(on_progress, on_error, helpers.manage_rock_stub)
end
end
end
Expand Down
38 changes: 38 additions & 0 deletions lua/rocks/operations/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -319,4 +319,42 @@ function helpers.postInstall()
end
end

---Installs or removes a rock stub so that luarocks will recognise rocks installed by
---extensions like rocks-git and rocks-dev as dependencies
---@param opts rock_handler.on_success.Opts
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)
nio.scheduler()
local tempdir = vim.fn.tempname()
local ok = fs.mkdir_p(tempdir)
if not ok then
log.error(("Could not create temp directory for rock stub %s rockspec"):format(vim.inspect(rock)))
return
end
local rockspec_file = ("%s-%s-1.rockspec"):format(rock.name, rock.version)
local rockspec_path = vim.fs.joinpath(tempdir, rockspec_file)
fs.write_file_await(rockspec_path, "w", rockspec_content)
-- XXX For now, we ignore failures and only log them
local future = nio.control.future()
luarocks.cli(
{ "install", rockspec_file },
---@param sc vim.SystemCompleted
function(sc)
if sc.code ~= 0 then
log.error(("Failed to install stub from rockspec %s"):format(rockspec_path))
end
future.set(true)
end,
{ cwd = tempdir }
)
future.wait()
elseif opts.action == "prune" then
local future = helpers.remove(opts.rock.name)
pcall(future.wait)
end
end)

return helpers
4 changes: 2 additions & 2 deletions lua/rocks/operations/sync.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ operations.sync = function(user_rocks, on_complete)
-- Sync actions handled by external modules that have registered handlers
for _, callback in pairs(sync_status.external_actions) do
ct = ct + 1
callback(report_progress, report_error)
callback(report_progress, report_error, helpers.manage_rock_stub)
end

-- rocks.nvim sync handlers should be installed now.
Expand All @@ -145,7 +145,7 @@ operations.sync = function(user_rocks, on_complete)
ct = ct + 1
local callback = handlers.get_sync_handler_callback(spec)
if callback then
callback(report_progress, report_error)
callback(report_progress, report_error, helpers.manage_rock_stub)
else
report_error(("Failed to install %s: %s"):format(spec.name, skipped_rock.reason))
end
Expand Down
2 changes: 1 addition & 1 deletion lua/rocks/operations/update.lua
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ update.update = function(on_complete, opts)
message = message,
})
end
handler(report_progress, report_error)
handler(report_progress, report_error, helpers.manage_rock_stub)
progress_handle:report({
percentage = get_percentage(ct, total_update_count),
})
Expand Down
20 changes: 20 additions & 0 deletions spec/operations/helpers_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ vim.env.PLENARY_TEST_TIMEOUT = 60000
describe("operations.helpers", function()
local helpers = require("rocks.operations.helpers")
local config = require("rocks.config.internal")
local state = require("rocks.state")
vim.system({ "mkdir", "-p", config.rocks_path }):wait()
nio.tests.it("install/remove", function()
helpers.install({ name = "plenary.nvim" }).wait()
Expand Down Expand Up @@ -48,4 +49,23 @@ describe("operations.helpers", function()
assert.is_nil(result.baz)
assert.same("foo 7.0.0 -> 8.0.0", tostring(result.foo))
end)
nio.tests.it("Install rock stub", function()
local installed_rocks = state.installed_rocks()
assert.is_nil(installed_rocks["stub.nvim"])
helpers.manage_rock_stub({
rock = { name = "stub.nvim", version = "1.0.0" },
action = "install",
})
installed_rocks = state.installed_rocks()
assert.same({
name = "stub.nvim",
version = "1.0.0",
}, installed_rocks["stub.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"])
end)
end)

0 comments on commit 5f37dde

Please sign in to comment.