aboutsummaryrefslogtreecommitdiffstats
path: root/lua
diff options
context:
space:
mode:
Diffstat (limited to 'lua')
-rw-r--r--lua/mason-core/async/init.lua3
-rw-r--r--lua/mason-core/installer/registry/init.lua2
-rw-r--r--lua/mason-registry/init.lua82
-rw-r--r--lua/mason-registry/sources/init.lua23
-rw-r--r--lua/mason/api/command.lua2
-rw-r--r--lua/mason/ui/init.lua1
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