diff options
| author | William Boman <william@redwill.se> | 2025-05-19 05:58:01 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-19 05:58:01 +0200 |
| commit | 3501b0f96d9f2f878b1947cf3614bc02d053a0c0 (patch) | |
| tree | 5f9025e2df9652346fcd74b7186be1c5a6366367 | |
| parent | fix(spawn): fix calling vim.fn when inside fast event loop on Windows (#1950) (diff) | |
| download | mason-3501b0f96d9f2f878b1947cf3614bc02d053a0c0.tar mason-3501b0f96d9f2f878b1947cf3614bc02d053a0c0.tar.gz mason-3501b0f96d9f2f878b1947cf3614bc02d053a0c0.tar.bz2 mason-3501b0f96d9f2f878b1947cf3614bc02d053a0c0.tar.lz mason-3501b0f96d9f2f878b1947cf3614bc02d053a0c0.tar.xz mason-3501b0f96d9f2f878b1947cf3614bc02d053a0c0.tar.zst mason-3501b0f96d9f2f878b1947cf3614bc02d053a0c0.zip | |
fix(registry): ensure there's no duplicate registry entries (#1957)
| -rw-r--r-- | lua/mason-registry/init.lua | 4 | ||||
| -rw-r--r-- | lua/mason-registry/sources/file.lua | 5 | ||||
| -rw-r--r-- | lua/mason-registry/sources/github.lua | 5 | ||||
| -rw-r--r-- | lua/mason-registry/sources/init.lua | 52 | ||||
| -rw-r--r-- | lua/mason-registry/sources/lua.lua | 5 | ||||
| -rw-r--r-- | tests/mason-registry/sources/collection_spec.lua | 21 |
6 files changed, 88 insertions, 4 deletions
diff --git a/lua/mason-registry/init.lua b/lua/mason-registry/init.lua index 713335f0..535e6b57 100644 --- a/lua/mason-registry/init.lua +++ b/lua/mason-registry/init.lua @@ -103,16 +103,16 @@ end ---@param callback? fun(success: boolean, updated_registries: RegistrySource[]) function Registry.update(callback) - log.debug "Updating the registry." local a = require "mason-core.async" local installer = require "mason-registry.installer" local noop = function() end a.run(function() if installer.channel then - log.trace "Registry update already in progress." + log.debug "Registry update already in progress." return installer.channel:receive():get_or_throw() else + log.debug "Updating the registry." Registry:emit("update:start", Registry.sources) return installer .install(Registry.sources, function(finished, all) diff --git a/lua/mason-registry/sources/file.lua b/lua/mason-registry/sources/file.lua index 34c855c0..663efaaa 100644 --- a/lua/mason-registry/sources/file.lua +++ b/lua/mason-registry/sources/file.lua @@ -189,6 +189,11 @@ function FileRegistrySource:serialize() } end +---@param other FileRegistrySource +function FileRegistrySource:is_same_location(other) + return vim.fn.expand(self.spec.path) == vim.fn.expand(other.spec.path) +end + function FileRegistrySource:__tostring() return ("FileRegistrySource(path=%s)"):format(self.spec.path) end diff --git a/lua/mason-registry/sources/github.lua b/lua/mason-registry/sources/github.lua index 5cc69023..597e7d84 100644 --- a/lua/mason-registry/sources/github.lua +++ b/lua/mason-registry/sources/github.lua @@ -171,6 +171,11 @@ function GitHubRegistrySource:serialize() } end +---@param other GitHubRegistrySource +function GitHubRegistrySource:is_same_location(other) + return self.spec.namespace == other.spec.namespace and self.spec.name == other.spec.name +end + function GitHubRegistrySource:__tostring() if self.spec.version then return ("GitHubRegistrySource(repo=%s, version=%s)"):format(self.repo, self.spec.version) diff --git a/lua/mason-registry/sources/init.lua b/lua/mason-registry/sources/init.lua index c08a46a5..765d4904 100644 --- a/lua/mason-registry/sources/init.lua +++ b/lua/mason-registry/sources/init.lua @@ -1,3 +1,5 @@ +local log = require "mason-core.log" + ---@class RegistrySource ---@field id string ---@field get_package fun(self: RegistrySource, pkg_name: string): Package? @@ -7,6 +9,7 @@ ---@field is_installed fun(self: RegistrySource): boolean ---@field install fun(self: RegistrySource): Result ---@field serialize fun(self: RegistrySource): InstallReceiptRegistry +---@field is_same_location fun(self: RegistrySource, other: RegistrySource): boolean ---@alias RegistrySourceType '"github"' | '"lua"' | '"file"' @@ -69,6 +72,18 @@ function LazySource:get() return self.instance end +---@param other LazySource +function LazySource:is_same_location(other) + if self.type == other.type then + return self:get():is_same_location(other:get()) + end + return false +end + +function LazySource:get_full_id() + return ("%s:%s"):format(self.type, self.id) +end + function LazySource:__tostring() return ("LazySource(type=%s, id=%s)"):format(self.type, self.id) end @@ -113,16 +128,40 @@ end ---@param registry string function LazySourceCollection:append(registry) - table.insert(self.list, parse(registry)) + self:unique_insert(parse(registry)) return self end ---@param registry string function LazySourceCollection:prepend(registry) - table.insert(self.list, 1, parse(registry)) + self:unique_insert(parse(registry), 1) return self end +---@param source LazySource +---@param idx? integer +function LazySourceCollection:unique_insert(source, idx) + idx = idx or #self.list + 1 + if idx > 1 then + for i = 1, math.min(idx, #self.list) do + if self.list[i]:is_same_location(source) then + log.fmt_warn( + "Ignoring duplicate registry entry %s (duplicate of %s)", + source:get_full_id(), + self.list[i]:get_full_id() + ) + return + end + end + end + for i = #self.list, idx, -1 do + if self.list[i]:is_same_location(source) then + table.remove(self.list, i) + end + end + table.insert(self.list, idx, source) +end + function LazySourceCollection:is_all_installed() for source in self:iterate { include_uninstalled = true } do if not source:is_installed() then @@ -171,6 +210,15 @@ function LazySourceCollection:to_list(opts) return list end +---@param idx integer +function LazySourceCollection:get(idx) + return self.list[idx] +end + +function LazySourceCollection:size() + return #self.list +end + function LazySourceCollection:__tostring() return ("LazySourceCollection(list={%s})"):format(table.concat(vim.tbl_map(tostring, self.list), ", ")) end diff --git a/lua/mason-registry/sources/lua.lua b/lua/mason-registry/sources/lua.lua index 8b4aac33..40e728b6 100644 --- a/lua/mason-registry/sources/lua.lua +++ b/lua/mason-registry/sources/lua.lua @@ -88,6 +88,11 @@ function LuaRegistrySource:serialize() } end +---@param other LuaRegistrySource +function LuaRegistrySource:is_same_location(other) + return self.id == other.id +end + function LuaRegistrySource:__tostring() return ("LuaRegistrySource(mod=%s)"):format(self.spec.mod) end diff --git a/tests/mason-registry/sources/collection_spec.lua b/tests/mason-registry/sources/collection_spec.lua new file mode 100644 index 00000000..b603c868 --- /dev/null +++ b/tests/mason-registry/sources/collection_spec.lua @@ -0,0 +1,21 @@ +local LazySourceCollection = require "mason-registry.sources" + +describe("LazySourceCollection", function() + it("should dedupe registries on append/prepend", function() + local coll = LazySourceCollection:new() + + coll:append "github:mason-org/mason-registry" + coll:prepend "github:mason-org/mason-registry@2025-05-16" + coll:prepend "github:my-own/registry" + coll:prepend "lua:registry" + coll:append "lua:registry" + coll:append "file:~/registry" + coll:append "file:$HOME/registry" + + assert.equals(4, coll:size()) + assert.same("lua:registry", coll:get(1):get_full_id()) + assert.same("github:my-own/registry", coll:get(2):get_full_id()) + assert.same("github:mason-org/mason-registry@2025-05-16", coll:get(3):get_full_id()) + assert.same("file:~/registry", coll:get(4):get_full_id()) + end) +end) |
