diff --git a/lua/lsp/package.lua b/lua/lsp/package.lua index a20b071..bde33e3 100644 --- a/lua/lsp/package.lua +++ b/lua/lsp/package.lua @@ -73,7 +73,7 @@ function M.validate(config) end if not o then - utils.err(("Invalid config for post_install step: %s"):format(r)) + utils.err(("Invalid config for post_install step: %s"):format(r), "LSP") return false end @@ -88,7 +88,10 @@ function M.validate(config) end if not ok then - utils.err(("Invalid config for %s:\n%s"):format(config.name or config[1] or config, resp)) + utils.err( + ("Invalid config for %s:\n%s"):format(config.name or config[1] or config, resp), + "LSP" + ) return false end @@ -97,7 +100,7 @@ end --- Run post installation steps ---@param pkg Package -function M:run_post_install(pkg) +function M:post_install(pkg) ---@param step PostInstallStep ---@param msg string local function log_err(step, msg) @@ -109,13 +112,13 @@ function M:run_post_install(pkg) cmd, msg ), - "lsp.package:run_post_install" + "LSP" ) end if self.config.post_install then for _, step in ipairs(self.config.post_install) do - utils.info("running post install step") + utils.info("running post install step", "LSP") local cwd = pkg:get_install_path() local args = step.cmd local prog = table.remove(args, 1) @@ -139,7 +142,7 @@ function M:run_post_install(pkg) log_err(step, table.concat(job:stderr_result(), "\n")) return end - utils.info("post install step done") + utils.info("post install step done", "LSP") end), }) job:start() @@ -147,32 +150,21 @@ function M:run_post_install(pkg) end end ---- Perform installation ----@param on_done fun(success: boolean)? -function M:mason_install(on_done) - local registry = require("mason-registry") - local ok, pkg = pcall(registry.get_package, self.config.name) - if not ok then - utils.err(pkg) - - if on_done then - on_done(false) - end - - return +--- Handle installation +---@param pkg Package +---@param old_version? string +---@param new_version? string +---@param on_done? fun(success: boolean) +function M:handle_install(pkg, old_version, new_version, on_done) + local version_str = "" + if old_version and new_version then + version_str = (" %s -> %s"):format(old_version, new_version) + elseif new_version then + version_str = " " .. new_version end - if pkg:is_installed() then - if on_done then - on_done(true) - end - - return - end - - utils.info(("Installing %s"):format(self.config.name)) - local handle = pkg:install({ version = self.config.version }) - + utils.info(("Installing %s%s"):format(self.config.name, version_str), "LSP") + local handle = pkg:install({ version = new_version }) local err handle:on( "stderr", @@ -187,11 +179,8 @@ function M:mason_install(on_done) local is_installed = pkg:is_installed() if is_installed then - utils.info( - ("Successfully installed %s"):format(self.config.name), - "lsp.package:mason_install" - ) - self:run_post_install(pkg) + utils.info(("Successfully installed %s"):format(self.config.name), "LSP") + self:post_install(pkg) else if err then err = ":\n" .. err @@ -199,10 +188,7 @@ function M:mason_install(on_done) err = "" end - utils.err( - ("Failed to install %s%s"):format(self.config.name, err), - "lsp.package:mason_install" - ) + utils.err(("Failed to install %s%s"):format(self.config.name, err), "LSP") end if on_done then @@ -212,6 +198,68 @@ function M:mason_install(on_done) ) end +--- Perform installation +---@param on_done fun(success: boolean)? +function M:install(on_done) + local registry = require("mason-registry") + local success, result = pcall(registry.get_package, self.config.name) + + if not success then + utils.err(("Failed to get package %s:\n%s"):format(self.config.name, result), "LSP") + + if on_done then + on_done(false) + end + + return + end + + local pkg = result + + if not pkg:is_installed() then + self:handle_install(pkg, nil, self.config.version, on_done) + elseif self.config.version then + pkg:get_installed_version(function(ok, version_or_err) + if not ok then + utils.err( + ("Failed to check currently installed version for %s:\n%s"):format( + self.config.name, + version_or_err + ), + "LSP" + ) + elseif self.config.version ~= version_or_err then + self:handle_install(pkg, version_or_err, self.config.version, on_done) + return + end + + if on_done then + on_done(ok) + end + end) + else + pkg:check_new_version(function(update_available, res) + local ok = type(res) == "table" or res == "Package is not outdated." + + if not ok then + utils.err( + ("Failed to check for update for %s:\n%s"):format(self.config.name, res), + "LSP" + ) + elseif update_available then + self:handle_install(pkg, res.current_version, res.latest_version, on_done) + return + end + + if on_done then + on_done(ok) + end + end) + + return + end +end + --- Install package dependencies ---@param on_done fun(success: boolean)? function M:install_dependencies(on_done) @@ -234,18 +282,18 @@ function M:install_dependencies(on_done) end for _, dep in ipairs(self.dependencies) do - dep:install(handle_result) + dep:install_with_dependencies(handle_result) end end --- Install package and any defined dependencies ---@param on_done fun(success: boolean)? -function M:install(on_done) +function M:install_with_dependencies(on_done) --- Handle install result ---@param success boolean local function handle_result(success) if success then - self:mason_install(on_done) + self:install(on_done) elseif on_done then on_done(success) end @@ -255,7 +303,7 @@ function M:install(on_done) if self.dependencies and #self.dependencies ~= 0 then self:install_dependencies(handle_result) else - self:mason_install(on_done) + self:install(on_done) end end) end diff --git a/lua/lsp/server.lua b/lua/lsp/server.lua index 92cde35..5ee9ec0 100644 --- a/lua/lsp/server.lua +++ b/lua/lsp/server.lua @@ -248,7 +248,7 @@ function M:install(on_done) end end - self.mason:install(handle_result) + self.mason:install_with_dependencies(handle_result) end --- Setup LSP server