From e6aab108215571875f9eef6047343140de12d5d7 Mon Sep 17 00:00:00 2001 From: William Boman Date: Sat, 11 Dec 2021 14:35:48 +0100 Subject: better healthchecks with min version check --- lua/nvim-lsp-installer/health/init.lua | 94 ++++++++++++++++++++++++++++------ 1 file changed, 77 insertions(+), 17 deletions(-) (limited to 'lua') diff --git a/lua/nvim-lsp-installer/health/init.lua b/lua/nvim-lsp-installer/health/init.lua index 29f7df7f..8fed9b75 100644 --- a/lua/nvim-lsp-installer/health/init.lua +++ b/lua/nvim-lsp-installer/health/init.lua @@ -13,11 +13,12 @@ local M = {} ---@alias HealthCheckResult ---| '"success"' ---| '"version-mismatch"' ----| '"not-installed"' +---| '"not-available"' ---@class HealthCheck ---@field public result HealthCheckResult ---@field public version string|nil +---@field public reason string|nil ---@field public name string local HealthCheck = {} HealthCheck.__index = HealthCheck @@ -38,12 +39,23 @@ local function mk_healthcheck(callback) stdio_sink = stdio.sink, }, function(success) if success then - local version = success - and vim.split( - table.concat(opts.use_stderr and stdio.buffers.stderr or stdio.buffers.stdout, ""), - "\n" - )[1] - or nil + local version = vim.split( + table.concat(opts.use_stderr and stdio.buffers.stderr or stdio.buffers.stdout, ""), + "\n" + )[1] + + if opts.check then + local version_check = opts.check(version) + if version_check then + callback(HealthCheck.new { + result = "version-mismatch", + reason = version_check, + version = version, + name = opts.name, + }) + return + end + end callback(HealthCheck.new { result = "success", @@ -52,7 +64,7 @@ local function mk_healthcheck(callback) }) else callback(HealthCheck.new { - result = "not-installed", -- ... we assume + result = "not-available", version = nil, name = opts.name, }) @@ -74,27 +86,75 @@ function M.check() -- We report on info level because we don't verify version compatibility yet health.report_info(("**%s**: `%s`"):format(healthcheck.name, healthcheck.version)) elseif healthcheck.result == "version-mismatch" then - health.report_warn(("**%s**: version mismatch `%s`"):format(healthcheck.name, healthcheck.version)) - elseif healthcheck.result == "not-installed" then - health.report_error(("**%s**: not installed"):format(healthcheck.name)) + health.report_warn( + ("**%s**: unsupported version `%s`. %s"):format( + healthcheck.name, + healthcheck.version, + healthcheck.reason + ) + ) + elseif healthcheck.result == "not-available" then + health.report_error(("**%s**: not available"):format(healthcheck.name)) end end )) local checks = Data.list_not_nil( - check { cmd = "go", args = { "version" }, name = "Go" }, + check { + cmd = "go", + args = { "version" }, + name = "Go", + check = function(version) + -- Parses output such as "go version go1.17.3 darwin/arm64" into major, minor, patch components + local _, _, major, minor = version:find "go(%d+)%.(%d+)%.(%d+)" + -- Due to https://go.dev/doc/go-get-install-deprecation + if not (tonumber(major) >= 1 and tonumber(minor) >= 17) then + return "Go version must be >= 1.17." + end + end, + }, check { cmd = "ruby", args = { "--version" }, name = "Ruby" }, check { cmd = gem.gem_cmd, args = { "--version" }, name = "RubyGem" }, check { cmd = composer.composer_cmd, args = { "--version" }, name = "Composer" }, check { cmd = "php", args = { "--version" }, name = "PHP" }, - check { cmd = npm.npm_command, args = { "--version" }, name = "npm" }, - check { cmd = "node", args = { "--version" }, name = "node" }, - check { cmd = "python", use_stderr = true, args = { "--version" }, name = "python" }, + check { + cmd = npm.npm_command, + args = { "--version" }, + name = "npm", + check = function(version) + -- Parses output such as "8.1.2" into major, minor, patch components + local _, _, major = version:find "(%d+)%.(%d+)%.(%d+)" + -- Based off of general observations of feature parity + if tonumber(major) < 6 then + return "npm version must be >= 6" + end + end, + }, + check { + cmd = "node", + args = { "--version" }, + name = "node", + check = function(version) + -- Parses output such as "v16.3.1" into major, minor, patch + local _, _, major = version:find "v(%d+)%.(%d+)%.(%d+)" + if tonumber(major) < 14 then + return "Node version must be >= 14" + end + end, + }, + when(platform.is_win, check { cmd = "python", use_stderr = true, args = { "--version" }, name = "python" }), + when(platform.is_win, check { cmd = "python", args = { "-m", "pip", "--version" }, name = "pip" }), check { cmd = "python3", args = { "--version" }, name = "python3" }, + check { cmd = "python3", args = { "-m", "pip", "--version" }, name = "pip3" }, check { cmd = "javac", args = { "-version" }, name = "java" }, check { cmd = "wget", args = { "--version" }, name = "wget" }, check { cmd = "curl", args = { "--version" }, name = "curl" }, - check { cmd = "gzip", args = { "--version" }, name = "gzip", use_stderr = true }, + check { + cmd = "gzip", + args = { "--version" }, + name = "gzip", + use_stderr = platform.is_mac, -- Apple gzip prints version string to stderr + }, check { cmd = "tar", args = { "--version" }, name = "tar" }, when( vim.g.python3_host_prog, @@ -110,7 +170,7 @@ function M.check() c() end - vim.wait(10000, function() + vim.wait(5000, function() return completed >= #checks end, 50) end -- cgit v1.2.3-70-g09d2