aboutsummaryrefslogtreecommitdiffstats
path: root/lua/mason-registry
diff options
context:
space:
mode:
Diffstat (limited to 'lua/mason-registry')
-rw-r--r--lua/mason-registry/init.lua6
-rw-r--r--lua/mason-registry/sources/github.lua1
-rw-r--r--lua/mason-registry/sources/init.lua17
-rw-r--r--lua/mason-registry/sources/synthesized.lua109
4 files changed, 128 insertions, 5 deletions
diff --git a/lua/mason-registry/init.lua b/lua/mason-registry/init.lua
index 535e6b57..5806c30a 100644
--- a/lua/mason-registry/init.lua
+++ b/lua/mason-registry/init.lua
@@ -49,7 +49,6 @@ function Registry.get_installed_package_names()
directories[#directories + 1] = entry.name
end
end
- -- TODO: validate that entry is a mason package
return directories
end
@@ -68,7 +67,10 @@ function Registry.get_all_package_names()
end
function Registry.get_all_packages()
- return vim.tbl_map(Registry.get_package, Registry.get_all_package_names())
+ local _ = require "mason-core.functional"
+ local packages =
+ _.uniq_by(_.identity, _.concat(Registry.get_all_package_names(), Registry.get_installed_package_names()))
+ return vim.tbl_map(Registry.get_package, packages)
end
function Registry.get_all_package_specs()
diff --git a/lua/mason-registry/sources/github.lua b/lua/mason-registry/sources/github.lua
index 597e7d84..2b177bdd 100644
--- a/lua/mason-registry/sources/github.lua
+++ b/lua/mason-registry/sources/github.lua
@@ -1,5 +1,4 @@
local InstallLocation = require "mason-core.installer.InstallLocation"
-local Optional = require "mason-core.optional"
local Result = require "mason-core.result"
local _ = require "mason-core.functional"
local fetch = require "mason-core.fetch"
diff --git a/lua/mason-registry/sources/init.lua b/lua/mason-registry/sources/init.lua
index 765d4904..f468a8ef 100644
--- a/lua/mason-registry/sources/init.lua
+++ b/lua/mason-registry/sources/init.lua
@@ -11,7 +11,7 @@ local log = require "mason-core.log"
---@field serialize fun(self: RegistrySource): InstallReceiptRegistry
---@field is_same_location fun(self: RegistrySource, other: RegistrySource): boolean
----@alias RegistrySourceType '"github"' | '"lua"' | '"file"'
+---@alias RegistrySourceType '"github"' | '"lua"' | '"file"' | '"synthesized"'
---@class LazySource
---@field type RegistrySourceType
@@ -54,6 +54,11 @@ function LazySource.File(id)
}
end
+function LazySource.Synthesized()
+ local SynthesizedSource = require "mason-registry.sources.synthesized"
+ return SynthesizedSource:new()
+end
+
---@param type RegistrySourceType
---@param id string
---@param init fun(id: string): RegistrySource
@@ -115,6 +120,7 @@ end
---@class LazySourceCollection
---@field list LazySource[]
+---@field synthesized LazySource
local LazySourceCollection = {}
LazySourceCollection.__index = LazySourceCollection
@@ -123,6 +129,7 @@ function LazySourceCollection:new()
local instance = {}
setmetatable(instance, self)
instance.list = {}
+ instance.synthesized = LazySource:new("synthesized", "synthesized", LazySource.Synthesized)
return instance
end
@@ -184,7 +191,7 @@ function LazySourceCollection:checksum()
return vim.fn.sha256(table.concat(registry_ids, ""))
end
----@param opts? { include_uninstalled?: boolean }
+---@param opts? { include_uninstalled?: boolean, include_synthesized?: boolean }
function LazySourceCollection:iterate(opts)
opts = opts or {}
@@ -197,6 +204,12 @@ function LazySourceCollection:iterate(opts)
return source
end
end
+
+ -- We've exhausted the true registry sources, fall back to the synthesized registry source.
+ if idx == #self.list + 1 and opts.include_synthesized ~= false then
+ idx = idx + 1
+ return self.synthesized:get()
+ end
end
end
diff --git a/lua/mason-registry/sources/synthesized.lua b/lua/mason-registry/sources/synthesized.lua
new file mode 100644
index 00000000..75638cd6
--- /dev/null
+++ b/lua/mason-registry/sources/synthesized.lua
@@ -0,0 +1,109 @@
+local Package = require "mason-core.package"
+local Result = require "mason-core.result"
+local _ = require "mason-core.functional"
+local InstallReceipt = require("mason-core.receipt").InstallReceipt
+local InstallLocation = require "mason-core.installer.InstallLocation"
+local fs = require "mason-core.fs"
+local log = require "mason-core.log"
+
+---@class SynthesizedRegistrySource : RegistrySource
+---@field buffer table<string, Package>
+local SynthesizedRegistrySource = {}
+SynthesizedRegistrySource.__index = SynthesizedRegistrySource
+
+function SynthesizedRegistrySource:new()
+ ---@type SynthesizedRegistrySource
+ local instance = {}
+ setmetatable(instance, self)
+ instance.buffer = {}
+ return instance
+end
+
+function SynthesizedRegistrySource:is_installed()
+ return true
+end
+
+---@return RegistryPackageSpec[]
+function SynthesizedRegistrySource:get_all_package_specs()
+ return {}
+end
+
+---@param pkg_name string
+---@param receipt InstallReceipt
+---@return Package
+function SynthesizedRegistrySource:load_package(pkg_name, receipt)
+ local installed_version = receipt:get_installed_package_version()
+ local source = {
+ id = ("pkg:mason/%s@%s"):format(pkg_name, installed_version or "N%2FA"), -- N%2FA = N/A
+ install = function()
+ error("This package can no longer be installed because it has been removed from the registry.", 0)
+ end,
+ }
+ ---@type RegistryPackageSpec
+ local spec = {
+ schema = "registry+v1",
+ name = pkg_name,
+ description = "",
+ categories = {},
+ languages = {},
+ homepage = "",
+ licenses = {},
+ deprecation = {
+ since = receipt:get_installed_package_version() or "N/A",
+ message = "This package has been removed from the registry.",
+ },
+ source = source,
+ }
+ local existing_pkg = self.buffer[pkg_name]
+ if existing_pkg then
+ existing_pkg:update(spec, self)
+ return existing_pkg
+ else
+ local pkg = Package:new(spec, self)
+ self.buffer[pkg_name] = pkg
+ return pkg
+ end
+end
+
+---@param pkg_name string
+---@return Package?
+function SynthesizedRegistrySource:get_package(pkg_name)
+ local receipt_path = InstallLocation.global():receipt(pkg_name)
+ if fs.sync.file_exists(receipt_path) then
+ local ok, receipt_json = pcall(vim.json.decode, fs.sync.read_file(receipt_path))
+ if ok then
+ local receipt = InstallReceipt.from_json(receipt_json)
+ return self:load_package(pkg_name, receipt)
+ else
+ log.error("Failed to decode package receipt", pkg_name, receipt_json)
+ end
+ end
+end
+
+function SynthesizedRegistrySource:get_all_package_names()
+ return vim.tbl_keys(self.buffer)
+end
+
+---@async
+function SynthesizedRegistrySource:install()
+ return Result.success()
+end
+
+function SynthesizedRegistrySource:get_display_name()
+ return "SynthesizedRegistrySource"
+end
+
+function SynthesizedRegistrySource:serialize()
+ return {}
+end
+
+---@param other SynthesizedRegistrySource
+function SynthesizedRegistrySource:is_same_location(other)
+ return true
+end
+
+function SynthesizedRegistrySource:__tostring()
+ return "SynthesizedRegistrySource"
+end
+
+return SynthesizedRegistrySource