Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: search rocks-binaries-dev server if version is dev or scm #194

Merged
merged 2 commits into from
Mar 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 42 additions & 1 deletion lua/rocks/cache.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,15 @@ local cache = {}

local luarocks = require("rocks.luarocks")
local state = require("rocks.state")
local constants = require("rocks.constants")
local nio = require("nio")

---@type { [string]: Rock[] } | nil
---@type { [rock_name]: Rock[] } | nil
local _cached_rocks = nil

---@type { [rock_name]: Rock[] } | nil
local _cached_dev_binaries = nil

---Used for completions only
---@type string[] | nil
local _removable_rock_cache = nil
Expand Down Expand Up @@ -84,4 +88,41 @@ cache.invalidate_removable_rocks = function()
_removable_rock_cache = nil
end

---Search the cache for rocks-binaries-dev rocks.
---Repopulates the cache and runs a second search if not found
---@type async fun(rock_name: string, version: string?)
cache.search_binary_dev_rocks = nio.create(function(rock_name, version)
---@cast rock_name rock_name
---@cast version string
local function search_cache()
local rocks
if _cached_dev_binaries then
rocks = _cached_dev_binaries[rock_name]
end
return rocks
and vim.iter(rocks):any(function(rock)
---@cast rock Rock
if version == "dev" then
version = "scm"
end
return not version or rock.version == version
end)
end
local found = search_cache()
if found then
return found
end
local future = nio.control.future()
luarocks.search_all(function(result)
if not vim.tbl_isempty(result) then
_cached_dev_binaries = result
end
future.set(true)
end, {
servers = constants.ROCKS_BINARIES_DEV,
})
future.wait()
return search_cache()
end, 2)

return cache
21 changes: 21 additions & 0 deletions lua/rocks/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ constants.DEFAULT_CONFIG = string.format(
---@type string
constants.ROCKS_NVIM = "rocks.nvim"

---@alias server_url string
---@alias only_server_url string

--- WARNING: The servers are prioritised by luarocks in the reverse order
--- in which they are passed
---@type server_url[]
constants.ROCKS_SERVERS = {
"https://luarocks.org/manifests/neorocks/",
"https://nvim-neorocks.github.io/rocks-binaries/",
}

---@type only_server_url
constants.ROCKS_BINARIES_DEV = "https://nvim-neorocks.github.io/rocks-binaries-dev/"

---@type server_url[]
constants.DEV_SERVERS = {
constants.ROCKS_BINARIES_DEV,
}

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

return constants

--- constants.lua
46 changes: 35 additions & 11 deletions lua/rocks/luarocks.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,28 @@ local log = require("rocks.log")
local nio = require("nio")

---@class LuarocksCliOpts: vim.SystemOpts
---@field servers? server_url[] | only_server_url
---@field synchronized? boolean Whether to wait for and acquire a lock (recommended for file system IO, default: `true`)

local lock = nio.control.future()
lock.set(true) -- initialise as unlocked

--- --only-server if `servers` is a `string`, otherwise --server for each element
---@param servers server_url[]|only_server_url|nil
---@return string[]
local function mk_server_args(servers)
if type(servers) == "string" then
---@cast servers string
return { ("--only-server='%s'"):format(servers) }
end
return vim.iter(servers or {})
:map(function(server)
---@cast server string
return ("--server='%s'"):format(server)
end)
:totable()
end

---@param args string[] luarocks CLI arguments
---@param on_exit (function|nil) Called asynchronously when the luarocks command exits.
--- asynchronously. Receives SystemCompleted object, see return of SystemObj:wait().
Expand Down Expand Up @@ -58,37 +75,44 @@ luarocks.cli = function(args, on_exit, opts)
LUAROCKS_CONFIG = "",
TREE_SITTER_LANGUAGE_VERSION = tostring(vim.treesitter.language_version),
})
local luarocks_cmd = vim.list_extend({
local luarocks_cmd = {
config.luarocks_binary,
"--lua-version=" .. constants.LUA_VERSION,
"--tree=" .. config.rocks_path,
-- WARNING: The servers are prioritised by luarocks in the reverse order
-- in which they are passed
"--server='https://luarocks.org/manifests/neorocks'",
"--server='https://nvim-neorocks.github.io/rocks-binaries/'",
}, args)
}
luarocks_cmd = vim.list_extend(luarocks_cmd, mk_server_args(opts.servers))
luarocks_cmd = vim.list_extend(luarocks_cmd, args)
log.info(luarocks_cmd)
return vim.system(luarocks_cmd, opts, on_exit_wrapped)
end

---@class LuarocksSearchOpts
---@field dev? boolean Include dev manifest? Default: false
---@field servers? server_url[]|only_server_url Optional servers. Defaults to constants.ROCKS_SERVERS

---Search luarocks.org for all packages.
---@type async fun(callback: fun(rocks_table: { [string]: Rock } ))
luarocks.search_all = nio.create(function(callback)
---@type async fun(callback: fun(rocks_table: { [string]: Rock } ), opts?: LuarocksSearchOpts)
luarocks.search_all = nio.create(function(callback, opts)
---@cast opts LuarocksSearchOpts | nil
local rocks_table = vim.empty_dict()
---@cast rocks_table { [string]: Rock }
local future = nio.control.future()
luarocks.cli({ "search", "--porcelain", "--all", "--dev" }, function(obj)
local cmd = { "search", "--porcelain", "--all" }
if opts and opts.dev then
table.insert(cmd, "--dev")
end
luarocks.cli(cmd, function(obj)
---@cast obj vim.SystemCompleted
future.set(obj)
end, { text = true, synchronized = false })
end, { text = true, synchronized = false, servers = opts and opts.servers or constants.ALL_SERVERS })
---@type vim.SystemCompleted
local obj = future.wait()
local result = obj.stdout
if obj.code ~= 0 or not result then
callback(vim.empty_dict())
return
end
for name, version in result:gmatch("(%S+)%s+(%S+)%srockspec%s+[^\n]+") do
for name, version in result:gmatch("(%S+)%s+(%S+)%s+[^\n]+") do
if name ~= "lua" then
local rock_list = rocks_table[name] or vim.empty_dict()
---@cast rock_list Rock[]
Expand Down
15 changes: 13 additions & 2 deletions lua/rocks/operations/helpers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
---@brief ]]

local luarocks = require("rocks.luarocks")
local constants = require("rocks.constants")
local config = require("rocks.config.internal")
local runtime = require("rocks.runtime")
local adapter = require("rocks.adapter")
Expand Down Expand Up @@ -45,10 +46,18 @@ helpers.install = function(rock_spec, progress_handle)
"install",
name,
}
local servers = {}
vim.list_extend(servers, constants.ROCKS_SERVERS)
if version then
-- If specified version is dev then install the `scm-1` version of the rock
if version == "dev" or version == "scm" then
table.insert(install_cmd, 2, "--dev")
if cache.search_binary_dev_rocks(rock_spec.name, version) then
-- Rock found on rocks-binaries-dev
table.insert(servers, constants.ROCKS_BINARIES_DEV)
else
-- Search dev manifest
table.insert(install_cmd, 2, "--dev")
end
else
table.insert(install_cmd, version)
end
Expand Down Expand Up @@ -84,7 +93,9 @@ helpers.install = function(rock_spec, progress_handle)

future.set(installed_rock)
end
end)
end, {
servers = servers,
})
return {
wait = future.wait,
wait_sync = function()
Expand Down
4 changes: 2 additions & 2 deletions lua/rocks/operations/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,9 @@ operations.add = function(arg_list, rock_name, version)
user_rocks.plugins = plugins
end

-- Set installed version as `scm-1` if development version has been installed
-- Set installed version as `scm` if development version has been installed
if version == "dev" then
installed_rock.version = "scm-1"
installed_rock.version = "scm"
end
local user_rock = user_rocks.plugins[rock_name]
if user_rock and user_rock.version then
Expand Down
3 changes: 2 additions & 1 deletion lua/rocks/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
local state = {}

local luarocks = require("rocks.luarocks")
local constants = require("rocks.constants")
local log = require("rocks.log")
local nio = require("nio")

Expand Down Expand Up @@ -66,7 +67,7 @@ state.outdated_rocks = nio.create(function()
else
future.set(obj.stdout)
end
end, { text = true })
end, { text = true, servers = constants.ALL_SERVERS })

local installed_rock_list = future.wait()

Expand Down
Loading