diff options
| -rw-r--r-- | lua/mason-core/installer/InstallRunner.lua | 1 | ||||
| -rw-r--r-- | lua/mason-core/package/AbstractPackage.lua | 14 | ||||
| -rw-r--r-- | lua/mason-core/package/init.lua | 5 | ||||
| -rw-r--r-- | lua/mason-core/receipt.lua | 27 | ||||
| -rw-r--r-- | lua/mason-registry/sources/file.lua | 9 | ||||
| -rw-r--r-- | lua/mason-registry/sources/github.lua | 13 | ||||
| -rw-r--r-- | lua/mason-registry/sources/init.lua | 1 | ||||
| -rw-r--r-- | lua/mason-registry/sources/lua.lua | 9 | ||||
| -rw-r--r-- | lua/mason-registry/sources/util.lua | 17 | ||||
| -rw-r--r-- | tests/fixtures/receipts/2.0.json | 10 | ||||
| -rw-r--r-- | tests/mason-core/installer/InstallRunner_spec.lua | 5 | ||||
| -rw-r--r-- | tests/mason-core/receipt_spec.lua | 10 |
12 files changed, 102 insertions, 19 deletions
diff --git a/lua/mason-core/installer/InstallRunner.lua b/lua/mason-core/installer/InstallRunner.lua index da9e775d..93225e11 100644 --- a/lua/mason-core/installer/InstallRunner.lua +++ b/lua/mason-core/installer/InstallRunner.lua @@ -106,6 +106,7 @@ function InstallRunner:execute(opts, callback) try(self:acquire_lock(opts.force)) context.receipt:with_start_time(vim.loop.gettimeofday()) + context.receipt:with_registry(context.package.registry:serialize()) -- 1. initialize working directory try(context.cwd:initialize()) diff --git a/lua/mason-core/package/AbstractPackage.lua b/lua/mason-core/package/AbstractPackage.lua index b490fc87..d0fde00d 100644 --- a/lua/mason-core/package/AbstractPackage.lua +++ b/lua/mason-core/package/AbstractPackage.lua @@ -16,6 +16,7 @@ local Semaphore = require("mason-core.async.control").Semaphore ---@class AbstractPackage : EventEmitter ---@field name string ---@field spec RegistryPackageSpec +---@field registry RegistrySource ---@field private install_handle InstallHandle? The currently associated installation handle. ---@field private uninstall_handle InstallHandle? The currently associated uninstallation handle. local AbstractPackage = {} @@ -33,13 +34,24 @@ AbstractPackage.DEFAULT_INSTALL_OPTS = { } ---@param spec RegistryPackageSpec -function AbstractPackage:new(spec) +---@param reg RegistrySource +function AbstractPackage:new(spec, reg) local instance = EventEmitter.new(self) instance.name = spec.name -- for convenient access instance.spec = spec + instance.registry = reg return instance end +---@param spec RegistryPackageSpec +---@param reg RegistrySource +function AbstractPackage:update(spec, reg) + self.name = spec.name -- shouldn't be necessary but might as well + self.spec = spec + self.registry = reg + return self +end + ---@return boolean function AbstractPackage:is_installing() return self:get_install_handle() diff --git a/lua/mason-core/package/init.lua b/lua/mason-core/package/init.lua index 11171aaf..c4ec520f 100644 --- a/lua/mason-core/package/init.lua +++ b/lua/mason-core/package/init.lua @@ -105,10 +105,11 @@ local function validate_spec(spec) end ---@param spec RegistryPackageSpec -function Package:new(spec) +---@param reg RegistrySource +function Package:new(spec, reg) validate_spec(spec) ---@type Package - local instance = AbstractPackage.new(self, spec) + local instance = AbstractPackage.new(self, spec, reg) instance.local_semaphore = Semaphore:new(1) return instance end diff --git a/lua/mason-core/receipt.lua b/lua/mason-core/receipt.lua index ecd20a2c..42a7e882 100644 --- a/lua/mason-core/receipt.lua +++ b/lua/mason-core/receipt.lua @@ -12,13 +12,16 @@ local M = {} ---@field share? table<string, string> ---@field opt? table<string, string> +---@alias InstallReceiptRegistry { proto: '"github"' | '"lua"' | '"file"' } + ---@class InstallReceipt ----@field public name string ----@field public schema_version InstallReceiptSchemaVersion ----@field public metrics {start_time:integer, completion_time:integer} ----@field public source InstallReceiptSource ----@field public links InstallReceiptLinks ----@field public install_options PackageInstallOpts +---@field name string +---@field schema_version InstallReceiptSchemaVersion +---@field metrics {start_time:integer, completion_time:integer} +---@field source InstallReceiptSource +---@field links InstallReceiptLinks +---@field install_options PackageInstallOpts +---@field registry InstallReceiptRegistry local InstallReceipt = {} InstallReceipt.__index = InstallReceipt @@ -70,6 +73,10 @@ function InstallReceipt:get_raw_source() end end +function InstallReceipt:get_registry() + return self.registry +end + function InstallReceipt:get_install_options() return self.install_options end @@ -148,12 +155,19 @@ function InstallReceiptBuilder:with_start_time(seconds, microseconds) return self end +---@param registry InstallReceiptRegistry +function InstallReceiptBuilder:with_registry(registry) + self.registry = registry + return self +end + function InstallReceiptBuilder:build() assert(self.name, "name is required") assert(self.start_time, "start_time is required") assert(self.completion_time, "completion_time is required") assert(self.source, "source is required") assert(self.install_options, "install_options is required") + assert(self.registry, "registry is required") return InstallReceipt:new { name = self.name, schema_version = "2.0", @@ -163,6 +177,7 @@ function InstallReceiptBuilder:build() }, install_options = self.install_options, source = self.source, + registry = self.registry, links = self.links, } end diff --git a/lua/mason-registry/sources/file.lua b/lua/mason-registry/sources/file.lua index d81fcc9c..34c855c0 100644 --- a/lua/mason-registry/sources/file.lua +++ b/lua/mason-registry/sources/file.lua @@ -44,7 +44,7 @@ function FileRegistrySource:reload(specs) self.buffer = _.assoc("specs", specs, self.buffer or {}) self.buffer.instances = _.compose( _.index_by(_.prop "name"), - _.map(util.hydrate_package(self.buffer.instances or {})) + _.map(util.hydrate_package(self, self.buffer.instances or {})) )(self:get_all_package_specs()) return self.buffer end @@ -182,6 +182,13 @@ function FileRegistrySource:get_display_name() end end +function FileRegistrySource:serialize() + return { + proto = "file", + path = self.id, + } +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 ceb503dc..5cc69023 100644 --- a/lua/mason-registry/sources/github.lua +++ b/lua/mason-registry/sources/github.lua @@ -61,7 +61,7 @@ function GitHubRegistrySource:reload() if not self:is_installed() then return end - self.buffer = _.compose(_.index_by(_.prop "name"), _.map(util.hydrate_package(self.buffer or {})))( + self.buffer = _.compose(_.index_by(_.prop "name"), _.map(util.hydrate_package(self, self.buffer or {})))( self:get_all_package_specs() ) return self.buffer @@ -160,6 +160,17 @@ function GitHubRegistrySource:get_display_name() end end +function GitHubRegistrySource:serialize() + local info = self:get_info() + return { + proto = "github", + namespace = self.spec.namespace, + name = self.spec.name, + version = info.version, + checksums = info.checksums, + } +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 ccc501fe..c08a46a5 100644 --- a/lua/mason-registry/sources/init.lua +++ b/lua/mason-registry/sources/init.lua @@ -6,6 +6,7 @@ ---@field get_display_name fun(self: RegistrySource): string ---@field is_installed fun(self: RegistrySource): boolean ---@field install fun(self: RegistrySource): Result +---@field serialize fun(self: RegistrySource): InstallReceiptRegistry ---@alias RegistrySourceType '"github"' | '"lua"' | '"file"' diff --git a/lua/mason-registry/sources/lua.lua b/lua/mason-registry/sources/lua.lua index e2144a83..8b4aac33 100644 --- a/lua/mason-registry/sources/lua.lua +++ b/lua/mason-registry/sources/lua.lua @@ -33,7 +33,7 @@ function LuaRegistrySource:reload(specs) self.buffer = _.assoc("specs", specs, self.buffer or {}) self.buffer.instances = _.compose( _.index_by(_.prop "name"), - _.map(util.hydrate_package(self.buffer.instances or {})) + _.map(util.hydrate_package(self, self.buffer.instances or {})) )(self:get_all_package_specs()) return self.buffer end @@ -81,6 +81,13 @@ function LuaRegistrySource:get_display_name() end end +function LuaRegistrySource:serialize() + return { + proto = "lua", + mod = self.id, + } +end + function LuaRegistrySource:__tostring() return ("LuaRegistrySource(mod=%s)"):format(self.spec.mod) end diff --git a/lua/mason-registry/sources/util.lua b/lua/mason-registry/sources/util.lua index ed399156..9efa1420 100644 --- a/lua/mason-registry/sources/util.lua +++ b/lua/mason-registry/sources/util.lua @@ -18,9 +18,10 @@ function M.map_registry_spec(spec) return Optional.of(spec) end +---@param registry RegistrySource ---@param buffer table<string, Package> ---@param spec RegistryPackageSpec -M.hydrate_package = _.curryN(function(buffer, spec) +M.hydrate_package = _.curryN(function(registry, buffer, spec) -- hydrate Pkg.Lang/License index _.each(function(lang) local _ = Package.Lang[lang] @@ -29,13 +30,15 @@ M.hydrate_package = _.curryN(function(buffer, spec) local _ = Package.License[lang] end, spec.licenses) - local pkg = buffer[spec.name] - if pkg then + local existing_instance = buffer[spec.name] + if existing_instance then -- Apply spec to the existing Package instances. This is important as to not have lingering package instances. - pkg.spec = spec - return pkg + existing_instance:update(spec, registry) + return existing_instance end - return Package:new(spec) -end, 2) + + local new_instance = Package:new(spec, registry) + return new_instance +end, 3) return M diff --git a/tests/fixtures/receipts/2.0.json b/tests/fixtures/receipts/2.0.json index b0c9e2f1..12e9808d 100644 --- a/tests/fixtures/receipts/2.0.json +++ b/tests/fixtures/receipts/2.0.json @@ -26,5 +26,15 @@ "debug": false, "strict": false, "force": false + }, + "registry": { + "name": "mason-registry", + "version": "2025-05-03-lawful-clave", + "checksums": { + "registry.json": "4ae083fe8e50d0bea5382be05c7ede8d2def55ff2b6b89dc129b153039d9f2a2", + "registry.json.zip": "2116d5db7676afe7052de329db4dfbf656054d8c35ce12414eb9d58561b2fde9" + }, + "proto": "github", + "namespace": "mason-org" } } diff --git a/tests/mason-core/installer/InstallRunner_spec.lua b/tests/mason-core/installer/InstallRunner_spec.lua index 0ff7a40f..48abb77a 100644 --- a/tests/mason-core/installer/InstallRunner_spec.lua +++ b/tests/mason-core/installer/InstallRunner_spec.lua @@ -268,6 +268,7 @@ describe("InstallRunner ::", function() test_helpers.sync_runner_execute(runner, {}) local receipt_file = location:package "dummy/mason-receipt.json" + assert.is_true(fs.sync.file_exists(receipt_file)) assert.is_true(match.tbl_containing { name = "dummy", @@ -277,6 +278,10 @@ describe("InstallRunner ::", function() completion_time = match.is_number(), start_time = match.is_number(), }, + registry = match.same { + proto = "lua", + mod = "dummy-registry.index", + }, source = match.same { id = "pkg:mason/dummy@1.0.0", type = "registry+v1", diff --git a/tests/mason-core/receipt_spec.lua b/tests/mason-core/receipt_spec.lua index 4436233b..1acdfba3 100644 --- a/tests/mason-core/receipt_spec.lua +++ b/tests/mason-core/receipt_spec.lua @@ -67,6 +67,16 @@ describe("receipt ::", function() opt = {}, share = {}, }, receipt:get_links()) + assert.same({ + name = "mason-registry", + version = "2025-05-03-lawful-clave", + checksums = { + ["registry.json"] = "4ae083fe8e50d0bea5382be05c7ede8d2def55ff2b6b89dc129b153039d9f2a2", + ["registry.json.zip"] = "2116d5db7676afe7052de329db4dfbf656054d8c35ce12414eb9d58561b2fde9", + }, + proto = "github", + namespace = "mason-org", + }, receipt:get_registry()) assert.is_true(receipt:is_schema_min "2.0") end) |
