diff options
Diffstat (limited to 'lua/mason-registry/sources/init.lua')
| -rw-r--r-- | lua/mason-registry/sources/init.lua | 208 |
1 files changed, 129 insertions, 79 deletions
diff --git a/lua/mason-registry/sources/init.lua b/lua/mason-registry/sources/init.lua index af1b9f6a..fd9cc573 100644 --- a/lua/mason-registry/sources/init.lua +++ b/lua/mason-registry/sources/init.lua @@ -1,6 +1,76 @@ -local _ = require "mason-core.functional" +---@class RegistrySource +---@field id string +---@field get_package fun(self: RegistrySource, pkg_name: string): Package? +---@field get_all_package_names fun(self: RegistrySource): string[] +---@field get_all_package_specs fun(self: RegistrySource): RegistryPackageSpec[] +---@field get_display_name fun(self: RegistrySource): string +---@field is_installed fun(self: RegistrySource): boolean +---@field install fun(self: RegistrySource): Result -local M = {} +---@alias RegistrySourceType '"github"' | '"lua"' | '"file"' + +---@class LazySource +---@field type RegistrySourceType +---@field id string +---@field init fun(id: string): RegistrySource +local LazySource = {} +LazySource.__index = LazySource + +---@param id string +function LazySource.GitHub(id) + local namespace, name = id:match "^(.+)/(.+)$" + if not namespace or not name then + error(("Failed to parse repository from GitHub registry: %q"):format(id), 0) + end + local name, version = unpack(vim.split(name, "@")) + local GitHubRegistrySource = require "mason-registry.sources.github" + return GitHubRegistrySource:new { + id = id, + namespace = namespace, + name = name, + version = version, + } +end + +---@param id string +function LazySource.Lua(id) + local LuaRegistrySource = require "mason-registry.sources.lua" + return LuaRegistrySource:new { + id = id, + mod = id, + } +end + +---@param id string +function LazySource.File(id) + local FileRegistrySource = require "mason-registry.sources.file" + return FileRegistrySource:new { + id = id, + path = id, + } +end + +---@param type RegistrySourceType +---@param id string +---@param init fun(id: string): RegistrySource +function LazySource:new(type, id, init) + local instance = setmetatable({}, self) + instance.type = type + instance.id = id + instance.init = init + return instance +end + +function LazySource:get() + if not self.instance then + self.instance = self.init(self.id) + end + return self.instance +end + +function LazySource:__tostring() + return ("LazySource(type=%s, id=%s)"):format(self.type, self.id) +end ---@param str string local function split_once_left(str, char) @@ -14,88 +84,46 @@ local function split_once_left(str, char) end ---@param registry_id string ----@return fun(): RegistrySource # Thunk to instantiate provider. local function parse(registry_id) local type, id = split_once_left(registry_id, ":") + assert(id, ("Malformed registry %q"):format(registry_id)) if type == "github" then - local namespace, name = id:match "^(.+)/(.+)$" - if not namespace or not name then - error(("Failed to parse repository from GitHub registry: %q."):format(registry_id), 0) - end - local name, version = unpack(vim.split(name, "@")) - return function() - local GitHubRegistrySource = require "mason-registry.sources.github" - return GitHubRegistrySource:new { - id = registry_id, - repo = ("%s/%s"):format(namespace, name), - namespace = namespace, - name = name, - version = version, - } - end + return LazySource:new(type, id, LazySource.GitHub) elseif type == "lua" then - return function() - local LuaRegistrySource = require "mason-registry.sources.lua" - return LuaRegistrySource:new { - id = registry_id, - mod = id, - } - end + return LazySource:new(type, id, LazySource.Lua) elseif type == "file" then - return function() - local FileRegistrySource = require "mason-registry.sources.file" - return FileRegistrySource:new { - path = id, - } - end - elseif type ~= nil then - error(("Unknown registry type %q: %q."):format(type, registry_id), 0) + return LazySource:new(type, id, LazySource.File) end - error(("Malformed registry id: %q."):format(registry_id), 0) + error(("Unknown registry type: %s"):format(type)) end ----@type ((fun(): RegistrySource) | RegistrySource)[] -local registries = {} +---@class LazySourceCollection +---@field list LazySource[] +local LazySourceCollection = {} +LazySourceCollection.__index = LazySourceCollection ----@param registry_ids string[] -function M.set_registries(registry_ids) - registries = {} - for _, registry in ipairs(registry_ids) do - local ok, err = pcall(function() - table.insert(registries, parse(registry)) - end) - if not ok then - local log = require "mason-core.log" - local notify = require "mason-core.notify" - log.fmt_error("Failed to parse registry %q: %s", registry, err) - notify(err, vim.log.levels.ERROR) - end - end +---@return LazySourceCollection +function LazySourceCollection:new() + local instance = {} + setmetatable(instance, self) + instance.list = {} + return instance end ----@param opts? { include_uninstalled?: boolean } -function M.iter(opts) - opts = opts or {} - local i = 1 - return function() - while i <= #registries do - local registry = registries[i] - if type(registry) == "function" then - -- unwrap thunk - registry = registry() - registries[i] = registry - end - i = i + 1 - if opts.include_uninstalled or registry:is_installed() then - return registry - end - end - end +---@param registry string +function LazySourceCollection:append(registry) + table.insert(self.list, parse(registry)) + return self +end + +---@param registry string +function LazySourceCollection:prepend(registry) + table.insert(self.list, 1, parse(registry)) + return self end ----@return boolean #Returns true if all sources are installed. -function M.is_installed() - for source in M.iter { include_uninstalled = true } do +function LazySourceCollection:is_all_installed() + for source in self:iterate { include_uninstalled = true } do if not source:is_installed() then return false end @@ -103,15 +131,37 @@ function M.is_installed() return true end ----@return string # The sha256 checksum of the currently registered sources. -function M.checksum() +function LazySourceCollection:checksum() ---@type string[] - local registry_ids = {} - for source in M.iter { include_uninstalled = true } do - table.insert(registry_ids, source.id) + local registry_ids = vim.tbl_map( + ---@param source LazySource + function(source) + return source.id + end, + self.list + ) + table.sort(registry_ids) + return vim.fn.sha256(table.concat(registry_ids, "")) +end + +---@param opts? { include_uninstalled?: boolean } +function LazySourceCollection:iterate(opts) + opts = opts or {} + + local idx = 1 + return function() + while idx <= #self.list do + local source = self.list[idx]:get() + idx = idx + 1 + if opts.include_uninstalled or source:is_installed() then + return source + end + end end - local checksum = _.compose(vim.fn.sha256, _.join "", _.sort_by(_.identity)) - return checksum(registry_ids) end -return M +function LazySourceCollection:__tostring() + return ("LazySourceCollection(list={%s})"):format(table.concat(vim.tbl_map(tostring, self.list), ", ")) +end + +return LazySourceCollection |
