From 8960e33e797b55b7769947ec02b08aa3e291b1a4 Mon Sep 17 00:00:00 2001 From: William Boman Date: Mon, 3 Mar 2025 16:50:31 +0100 Subject: refactor(registry)!: add events "update:success", "update:start", "update:progress" and "update:failed" --- lua/mason-registry/init.lua | 10 ++- lua/mason-registry/installer.lua | 21 ++++-- lua/mason/ui/components/header.lua | 6 +- lua/mason/ui/components/main/package_list.lua | 21 +++--- lua/mason/ui/instance.lua | 104 ++++++++++++++------------ 5 files changed, 92 insertions(+), 70 deletions(-) diff --git a/lua/mason-registry/init.lua b/lua/mason-registry/init.lua index ad8eef5a..bd35f073 100644 --- a/lua/mason-registry/init.lua +++ b/lua/mason-registry/init.lua @@ -113,10 +113,16 @@ function Registry.update(callback) log.trace "Registry update already in progress." return installer.channel:receive():get_or_throw() else + Registry:emit("update:start", Registry.sources) return installer - .install(Registry.sources) + .install(Registry.sources, function(finished, all) + Registry:emit("update:progress", finished, all) + end) :on_success(function(updated_registries) - Registry:emit("update", updated_registries) + Registry:emit("update:success", updated_registries) + end) + :on_failure(function(errors) + Registry:emit("update:failed", errors) end) :get_or_throw() end diff --git a/lua/mason-registry/installer.lua b/lua/mason-registry/installer.lua index 5abbcd74..a5c9fe92 100644 --- a/lua/mason-registry/installer.lua +++ b/lua/mason-registry/installer.lua @@ -32,24 +32,35 @@ end ---@async ---@param sources LazySourceCollection +---@param on_progress fun(finished: RegistrySource[], all: RegistrySource[]) ---@return Result # Result -function M.install(sources) +function M.install(sources, on_progress) log.debug("Installing registries.", sources) assert(not M.channel, "Cannot install when channel is active.") M.channel = OneShotChannel:new() + local finished_registries = {} + local registries = sources:to_list { include_uninstalled = true } + local results = { a.wait_all(_.map( ---@param source RegistrySource function(source) return function() log.trace("Installing registry.", source) - return source:install():map(_.always(source)):map_err(function(err) - return ("%s failed to install: %s"):format(source, err) - end) + return source + :install() + :map(_.always(source)) + :map_err(function(err) + return ("%s failed to install: %s"):format(source, err) + end) + :on_success(function() + table.insert(finished_registries, source) + on_progress(finished_registries, registries) + end) end end, - sources:to_list { include_uninstalled = true } + registries )), } diff --git a/lua/mason/ui/components/header.lua b/lua/mason/ui/components/header.lua index e8f89a52..1e5b2f10 100644 --- a/lua/mason/ui/components/header.lua +++ b/lua/mason/ui/components/header.lua @@ -29,7 +29,7 @@ return function(state) { p.Comment "https://github.com/williamboman/mason.nvim" }, }, }), - Ui.When(not state.packages.new_versions_check.is_checking and #uninstalled_registries > 0, function() + Ui.When(not state.info.registry_update.in_progress and #uninstalled_registries > 0, function() return Ui.CascadingStyleNode({ "INDENT" }, { Ui.EmptyLine(), Ui.HlTextNode { @@ -49,7 +49,7 @@ return function(state) }) end), Ui.When( - not state.packages.new_versions_check.is_checking and state.info.registry_update_error, + not state.info.registry_update.in_progress and state.info.registry_update.error, Ui.CascadingStyleNode({ "INDENT" }, { Ui.HlTextNode { { @@ -57,7 +57,7 @@ return function(state) }, { p.none " ", - p.Comment(state.info.registry_update_error), + p.Comment(state.info.registry_update.error), }, }, Ui.EmptyLine(), diff --git a/lua/mason/ui/components/main/package_list.lua b/lua/mason/ui/components/main/package_list.lua index 8d1dc803..55cbe41c 100644 --- a/lua/mason/ui/components/main/package_list.lua +++ b/lua/mason/ui/components/main/package_list.lua @@ -186,19 +186,14 @@ local get_outdated_packages_preview = _.if_else( ---@param state InstallerUiState local function Installed(state) return Ui.Node { - Ui.Keybind( - settings.current.ui.keymaps.check_outdated_packages, - "CHECK_NEW_VISIBLE_PACKAGE_VERSIONS", - nil, - true - ), + Ui.Keybind(settings.current.ui.keymaps.check_outdated_packages, "UPDATE_REGISTRY", nil, true), PackageListContainer { state = state, heading = Ui.Node { Ui.HlTextNode(p.heading "Installed"), - Ui.When(state.packages.new_versions_check.is_checking, function() - local new_versions_check = state.packages.new_versions_check - local styling = new_versions_check.percentage_complete == 1 and p.highlight_block or p.muted_block + Ui.When(state.info.registry_update.in_progress, function() + local styling = state.info.registry_update.percentage_complete == 1 and p.highlight_block + or p.muted_block local is_all_registries_installed = _.all(_.prop "is_installed", state.info.registries) local registry_count = #state.info.registries local text @@ -212,12 +207,14 @@ local function Installed(state) end return Ui.VirtualTextNode { text, - styling(("%-4s"):format(math.floor(new_versions_check.percentage_complete * 100) .. "%")), - styling((" "):rep(new_versions_check.percentage_complete * 15)), + styling( + ("%-4s"):format(math.floor(state.info.registry_update.percentage_complete * 100) .. "%") + ), + styling((" "):rep(state.info.registry_update.percentage_complete * 15)), } end), Ui.When( - not state.packages.new_versions_check.is_checking and #state.packages.outdated_packages > 0, + not state.info.registry_update.in_progress and #state.packages.outdated_packages > 0, function() return Ui.VirtualTextNode { p.muted "Press ", diff --git a/lua/mason/ui/instance.lua b/lua/mason/ui/instance.lua index 3035d6c6..3b5f82be 100644 --- a/lua/mason/ui/instance.lua +++ b/lua/mason/ui/instance.lua @@ -60,8 +60,12 @@ local INITIAL_STATE = { used_disk_space = nil, ---@type { name: string, is_installed: boolean }[] registries = {}, - ---@type string? - registry_update_error = nil, + registry_update = { + ---@type string? + error = nil, + in_progress = false, + percentage_complete = 0, + }, }, view = { is_searching = false, @@ -79,10 +83,6 @@ local INITIAL_STATE = { packages = { ---@type Package[] outdated_packages = {}, - new_versions_check = { - is_checking = false, - percentage_complete = 0, - }, ---@type Package[] all = {}, ---@type table @@ -439,7 +439,6 @@ local function toggle_expand_package(event) end) end ----@async ---@param pkg Package local function check_new_package_version(pkg) local installed_version = pkg:get_installed_version() @@ -460,30 +459,8 @@ local function check_new_package_version(pkg) end end ----@async local function check_new_package_versions() local state = get_state() - if state.packages.new_versions_check.is_checking then - return - end - - mutate_state(function(state) - state.packages.outdated_packages = {} - state.packages.new_versions_check.is_checking = true - state.packages.new_versions_check.percentage_complete = 0 - end) - - do - local success, err = a.wait(registry.update) - mutate_state(function(state) - state.packages.new_versions_check.percentage_complete = 1 - if not success then - state.info.registry_update_error = tostring(_.gsub("\n", " ", err)) - else - state.info.registry_update_error = nil - end - end) - end local outdated_packages = {} @@ -500,15 +477,6 @@ local function check_new_package_versions() end end end) - - a.sleep(1000) - mutate_state(function(state) - state.packages.outdated_packages = outdated_packages - state.packages.new_versions_check.is_checking = false - state.packages.new_versions_check.current = 0 - state.packages.new_versions_check.total = 0 - state.packages.new_versions_check.percentage_complete = 0 - end) end local function toggle_json_schema(event) @@ -579,7 +547,9 @@ end local effects = { ["CHECK_NEW_PACKAGE_VERSION"] = a.scope(_.compose(_.partial(pcall, check_new_package_version), _.prop "payload")), - ["CHECK_NEW_VISIBLE_PACKAGE_VERSIONS"] = a.scope(check_new_package_versions), + ["UPDATE_REGISTRY"] = function() + registry.update() + end, ["CLEAR_LANGUAGE_FILTER"] = clear_filter, ["CLEAR_SEARCH_MODE"] = clear_search_mode, ["CLOSE_WINDOW"] = window.close, @@ -710,25 +680,63 @@ local function setup_packages(packages) end) end +registry:on("update:failed", function(errors) + mutate_state(function(state) + state.info.registry_update.percentage_complete = 0 + state.info.registry_update.in_progress = false + state.info.registry_update.error = table.concat(errors, " - ") + end) +end) + +registry:on("update:success", function() + setup_packages(registry.get_all_packages()) + update_registry_info() + check_new_package_versions() + + -- Wait with resetting the state in order to keep displaying the update message + vim.defer_fn(function() + mutate_state(function(state) + if state.info.registry_update.percentage_complete ~= 1 then + -- New update was started already, don't reset state + return + end + state.info.registry_update.in_progress = false + state.info.registry_update.percentage_complete = 0 + end) + end, 1000) +end) + +registry:on("update:start", function() + mutate_state(function(state) + state.packages.outdated_packages = {} + state.info.registry_update.error = nil + state.info.registry_update.in_progress = true + state.info.registry_update.percentage_complete = 0 + end) +end) + +registry:on("update:progress", function(finished, all) + mutate_state(function(state) + state.info.registry_update.percentage_complete = #finished / #all + end) +end) + update_registry_info() if registry.sources:is_all_installed() then setup_packages(registry.get_all_packages()) end if settings.current.ui.check_outdated_packages_on_open then - a.run(check_new_package_versions, function() end) + registry.update() else - registry.refresh(function() - setup_packages(registry.get_all_packages()) - update_registry_info() + registry.refresh(function(success, updated_registries) + if success and #updated_registries == 0 then + setup_packages(registry.get_all_packages()) + update_registry_info() + end end) end -registry:on("update", function() - setup_packages(registry.get_all_packages()) - update_registry_info() -end) - window.init { effects = effects, border = settings.current.ui.border, -- cgit v1.2.3-70-g09d2