Skip to content

Commit aa8ee67

Browse files
author
Marc Jakobi
committed
feat: add health checks
1 parent 387d4b7 commit aa8ee67

File tree

2 files changed

+106
-0
lines changed

2 files changed

+106
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1010

1111
### Added
1212

13+
- Health checks.
1314
- Use tree-sitter if the parser for Haskell is installed,
1415
without requiring the nvim-treesitter plugin.
1516

lua/haskell-snippets/health.lua

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
local health = {}
2+
3+
local h = vim.health or require('health')
4+
local start = h.start or h.report_start
5+
local ok = h.ok or h.report_ok
6+
local error = h.error or h.report_error
7+
local warn = h.warn or h.report_warn
8+
9+
---@class ExternalDependency
10+
---@field name string Name of the dependency
11+
---@field get_binaries fun():string[]Function that returns the binaries to check for
12+
---@field optional fun():boolean Function that returns whether the dependency is optional
13+
---@field url string URL (markdown)
14+
---@field info string Additional information
15+
---@field extra_checks function|nil Optional extra checks to perform if the dependency is installed
16+
17+
---@type ExternalDependency[]
18+
local external_dependencies = {
19+
{
20+
name = 'haskell-language-server',
21+
get_binaries = function()
22+
local _, HTConfig = pcall(require, 'haskell-tools.config.internal')
23+
local default = { 'haskell-language-server-wrapper', 'haskell-language-server' }
24+
if not HTConfig then
25+
return default
26+
end
27+
local Types = require('haskell-tools.types.internal')
28+
local cmd = Types.evaluate(HTConfig.hls.cmd)
29+
if not cmd or #cmd == 0 then
30+
return default
31+
end
32+
return { cmd[1] }
33+
end,
34+
optional = function()
35+
return true
36+
end,
37+
url = '[haskell-language-server](https://haskell-language-server.readthedocs.io)',
38+
info = 'Some snippets work better with LSP.',
39+
},
40+
}
41+
42+
---@param dep ExternalDependency
43+
---@return boolean is_installed
44+
---@return string|nil version
45+
local check_installed = function(dep)
46+
local binaries = dep.get_binaries()
47+
for _, binary in ipairs(binaries) do
48+
if vim.fn.executable(binary) == 1 then
49+
local handle = io.popen(binary .. ' --version')
50+
if handle then
51+
local binary_version, error_msg = handle:read('*a')
52+
handle:close()
53+
if error_msg then
54+
return true
55+
end
56+
return true, binary_version
57+
end
58+
return true
59+
end
60+
end
61+
return false
62+
end
63+
64+
---@param dep ExternalDependency
65+
local function check_external_dependency(dep)
66+
local installed, mb_version = check_installed(dep)
67+
if installed then
68+
local version = mb_version and mb_version:sub(0, mb_version:find('\n') - 1) or '(unknown version)'
69+
ok(('%s: found %s.'):format(dep.name, version))
70+
if dep.extra_checks then
71+
dep.extra_checks()
72+
end
73+
return
74+
end
75+
if dep.optional() then
76+
warn(([[
77+
%s: not found.
78+
Install %s for extended capabilities.
79+
%s
80+
]]):format(dep.name, dep.url, dep.info))
81+
else
82+
error(([[
83+
%s: not found.
84+
haskell-snippets.nvim requires %s.
85+
%s
86+
]]):format(dep.name, dep.url, dep.info))
87+
end
88+
end
89+
90+
function health.check()
91+
start('Checking external dependencies')
92+
for _, dep in ipairs(external_dependencies) do
93+
check_external_dependency(dep)
94+
end
95+
96+
start('Checking tree-sitter parsers')
97+
local success = pcall(vim.treesitter.get_string_parser, '', 'haskell')
98+
if not success then
99+
warn('The tree-sitter parser for Haskell is not installed.')
100+
else
101+
ok('The tree-sitter parser for Haskell is installed.')
102+
end
103+
end
104+
105+
return health

0 commit comments

Comments
 (0)