diff options
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/mason-core/async/init.lua | 3 | ||||
| -rw-r--r-- | lua/mason-core/installer/registry/init.lua | 2 | ||||
| -rw-r--r-- | lua/mason-registry/init.lua | 82 | ||||
| -rw-r--r-- | lua/mason-registry/sources/init.lua | 23 | ||||
| -rw-r--r-- | lua/mason/api/command.lua | 2 | ||||
| -rw-r--r-- | lua/mason/ui/init.lua | 1 |
6 files changed, 97 insertions, 16 deletions
diff --git a/lua/mason-core/async/init.lua b/lua/mason-core/async/init.lua index 3c88eef0..0b327218 100644 --- a/lua/mason-core/async/init.lua +++ b/lua/mason-core/async/init.lua @@ -125,7 +125,8 @@ exports.run_blocking = function(suspend_fn, ...) end, ...) if - vim.wait(60 * 60 * 1000, function() -- the wait time is completely arbitrary + resolved + or vim.wait(60 * 60 * 1000, function() -- the wait time is completely arbitrary return resolved == true end, 50) then diff --git a/lua/mason-core/installer/registry/init.lua b/lua/mason-core/installer/registry/init.lua index 5968987b..f03f3e31 100644 --- a/lua/mason-core/installer/registry/init.lua +++ b/lua/mason-core/installer/registry/init.lua @@ -5,7 +5,6 @@ local _ = require "mason-core.functional" local a = require "mason-core.async" local link = require "mason-core.installer.registry.link" local log = require "mason-core.log" -local semver = require "mason-core.semver" local M = {} @@ -71,6 +70,7 @@ local function coalesce_source(source, version) local version_override = source.version_overrides[i] local version_type, constraint = unpack(_.split(":", version_override.constraint)) if version_type == "semver" then + local semver = require "mason-core.semver" local version_match = Result.try(function(try) local requested_version = try(semver.parse(version)) if _.starts_with("<=", constraint) then diff --git a/lua/mason-registry/init.lua b/lua/mason-registry/init.lua index 4568c54d..19a24d60 100644 --- a/lua/mason-registry/init.lua +++ b/lua/mason-registry/init.lua @@ -7,6 +7,7 @@ local path = require "mason-core.path" local sources = require "mason-registry.sources" ---@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_display_name fun(self: RegistrySource): string @@ -118,12 +119,33 @@ function M.get_all_packages() return get_packages(M.get_all_package_names()) end ----@param cb fun(success: boolean, err: any?) -function M.update(cb) +local STATE_FILE = path.concat { vim.fn.stdpath "cache", "mason-registry-update" } + +---@param time integer +local function get_store_age(time) + local checksum = sources.checksum() + if fs.sync.file_exists(STATE_FILE) then + local parse_state_file = + _.compose(_.evolve { timestamp = tonumber }, _.zip_table { "checksum", "timestamp" }, _.split "\n") + local state = parse_state_file(fs.sync.read_file(STATE_FILE)) + if checksum == state.checksum then + return math.abs(time - state.timestamp) + end + end + return time +end + +---@async +---@param time integer +local function update_store_timestamp(time) + fs.async.write_file(STATE_FILE, _.join("\n", { sources.checksum(), tostring(time) })) +end + +---@param callback? fun(success: boolean, updated_registries: RegistrySource[]) +function M.update(callback) local a = require "mason-core.async" local Result = require "mason-core.result" - - a.run(function() + return a.run(function() return Result.try(function(try) local updated_sources = {} for source in sources.iter { include_uninstalled = true } do @@ -135,23 +157,55 @@ function M.update(cb) end) end return updated_sources + end):on_success(function(updated_sources) + if #updated_sources > 0 then + M:emit("update", updated_sources) + end end) - end, function(success, sources_or_err) - if not success then - cb(success, sources_or_err) + end, function(success, result) + if not callback then return end - sources_or_err - :on_success(function(updated_sources) - if #updated_sources > 0 then - M:emit("update", updated_sources) - end - cb(true, updated_sources) + if not success then + return callback(false, result) + end + result + :on_success(function(value) + callback(true, value) end) :on_failure(function(err) - cb(false, err) + callback(false, err) end) end) end +local REGISTRY_STORE_TTL = 86400 -- 24 hrs + +---@param cb? fun() +function M.refresh(cb) + local a = require "mason-core.async" + + ---@async + local function refresh() + if vim.in_fast_event() then + a.scheduler() + end + local is_outdated = get_store_age(os.time()) > REGISTRY_STORE_TTL + if is_outdated or not sources.is_installed() then + if a.wait(M.update) then + if vim.in_fast_event() then + a.scheduler() + end + update_store_timestamp(os.time()) + end + end + end + + if not cb then + a.run_blocking(refresh) + else + a.run(refresh, cb) + end +end + return M diff --git a/lua/mason-registry/sources/init.lua b/lua/mason-registry/sources/init.lua index 0e5e0d29..0739f40b 100644 --- a/lua/mason-registry/sources/init.lua +++ b/lua/mason-registry/sources/init.lua @@ -1,3 +1,5 @@ +local _ = require "mason-core.functional" + local M = {} ---@param registry_id string @@ -72,4 +74,25 @@ function M.iter(opts) end end +---@return boolean #Returns true if all sources are installed. +function M.is_installed() + for source in M.iter { include_uninstalled = true } do + if not source:is_installed() then + return false + end + end + return true +end + +---@return string # The sha256 checksum of the currently registered sources. +function M.checksum() + ---@type string[] + local registry_ids = {} + for source in M.iter { include_uninstalled = true } do + table.insert(registry_ids, source.id) + end + local checksum = _.compose(vim.fn.sha256, _.join "", _.sort_by(_.identity)) + return checksum(registry_ids) +end + return M diff --git a/lua/mason/api/command.lua b/lua/mason/api/command.lua index fadb9ac4..4be13d86 100644 --- a/lua/mason/api/command.lua +++ b/lua/mason/api/command.lua @@ -211,12 +211,14 @@ vim.api.nvim_create_user_command("MasonLog", MasonLog, { _G.mason_completion = { available_package_completion = function() local registry = require "mason-registry" + registry.refresh() local package_names = registry.get_all_package_names() table.sort(package_names) return table.concat(package_names, "\n") end, installed_package_completion = function() local registry = require "mason-registry" + registry.refresh() local package_names = registry.get_installed_package_names() table.sort(package_names) return table.concat(package_names, "\n") diff --git a/lua/mason/ui/init.lua b/lua/mason/ui/init.lua index bbe534ad..340434eb 100644 --- a/lua/mason/ui/init.lua +++ b/lua/mason/ui/init.lua @@ -7,6 +7,7 @@ end function M.open() local api = require "mason.ui.instance" + require("mason-registry").refresh(function() end) api.window.open() end |
