Skip to content

Commit fee19c5

Browse files
committed
feat: Add health check.
Moves dependency checking from the bootstrapping step to the new health check. The health check will validate the state of plugin dependencies as well as external dependencies. Run the health check with: `:checkhealth diffview` (fixes #253)
1 parent f32a722 commit fee19c5

File tree

2 files changed

+98
-51
lines changed

2 files changed

+98
-51
lines changed

lua/diffview/bootstrap.lua

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,6 @@ local function err(msg)
99
vim.cmd("echohl NONE")
1010
end
1111

12-
local function exists_in_runtime(module_name)
13-
--#region From neovim/runtime/lua/vim/_init_packages.lua:
14-
local basename = module_name:gsub('%.', '/')
15-
local paths = { "lua/" .. basename .. ".lua", "lua/" .. basename .. "/init.lua" }
16-
17-
local found = vim.api.nvim__get_runtime(paths, false, { is_lua = true })
18-
if found[1] then
19-
return true
20-
end
21-
22-
local so_paths = {}
23-
for _, trail in ipairs(vim._so_trails) do
24-
local path = "lua" .. trail:gsub('?', basename) -- so_trails contains a leading slash
25-
table.insert(so_paths, path)
26-
end
27-
28-
found = vim.api.nvim__get_runtime(so_paths, false, { is_lua = true })
29-
if found[1] then
30-
return true
31-
end
32-
--#endregion
33-
34-
return false
35-
end
36-
37-
local function is_module_available(name)
38-
if package.loaded[name] then
39-
return true
40-
end
41-
42-
---@diagnostic disable-next-line: undefined-field
43-
if _G.__luacache and _G.__luacache.print_profile then
44-
-- WORKAROUND: If the user has impatient.nvim with profiling enabled: just
45-
-- do a normal require.
46-
-- @See [issue #144](https://github.com/sindrets/diffview.nvim/issues/144).
47-
local ok, _ = pcall(require, name)
48-
return ok
49-
end
50-
51-
return exists_in_runtime(name)
52-
end
53-
5412
_G.DiffviewGlobal = {
5513
bootstrap_done = true,
5614
bootstrap_ok = false,
@@ -64,15 +22,6 @@ if vim.fn.has("nvim-0.7") ~= 1 then
6422
return false
6523
end
6624

67-
-- Ensure dependencies
68-
if not is_module_available("plenary") then
69-
err(
70-
"Dependency 'plenary.nvim' is not installed! "
71-
.. "See ':h diffview.changelog-93' for more information."
72-
)
73-
return false
74-
end
75-
7625
_G.DiffviewGlobal = {
7726
---Debug Levels:
7827
---0: NOTHING

lua/diffview/health.lua

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
local health = vim.health or require("health")
2+
local config = require("diffview.config")
3+
4+
local M = {}
5+
6+
M.plugin_deps = {
7+
{
8+
name = "plenary",
9+
optional = false,
10+
},
11+
{
12+
name = "nvim-web-devicons",
13+
optional = true,
14+
},
15+
}
16+
17+
---@param cmd string|string[]
18+
---@return string[] stdout
19+
---@return integer code
20+
local function system_list(cmd)
21+
local out = vim.fn.systemlist(cmd)
22+
return out or {}, vim.v.shell_error
23+
end
24+
25+
local function lualib_available(name)
26+
local ok, _ = pcall(require, name)
27+
return ok
28+
end
29+
30+
function M.check()
31+
if vim.fn.has("nvim-0.7") == 0 then
32+
health.report_error("Diffview.nvim requires Neovim 0.7.0+")
33+
end
34+
35+
health.report_start("Checking plugin dependencies")
36+
37+
for _, plugin in ipairs(M.plugin_deps) do
38+
if lualib_available(plugin.name) then
39+
health.report_ok(plugin.name .. " installed.")
40+
else
41+
if plugin.optional then
42+
health.report_warn(("Optional dependency '%s' not found."):format(plugin.name))
43+
else
44+
health.report_error(("Dependency '%s' not found!"):format(plugin.name))
45+
end
46+
end
47+
end
48+
49+
health.report_start("Checking external dependencies")
50+
51+
-- Git
52+
;(function()
53+
local conf = config.get_config()
54+
local out, code = system_list(vim.tbl_flatten({ conf.git_cmd, "version" }))
55+
56+
if code ~= 0 or not out[1] then
57+
health.report_error(
58+
"Configured git command is not executable: " .. table.concat(conf.git_cmd, " "
59+
))
60+
return
61+
else
62+
health.report_ok("Git found.")
63+
end
64+
65+
local version_string = out[1]:match("git version (%S+)")
66+
67+
if not version_string then
68+
health.report_error("Could not determine git version!")
69+
return
70+
end
71+
72+
local current = {}
73+
local target = {
74+
major = 2,
75+
minor = 31,
76+
patch = 0,
77+
}
78+
local target_version_string = ("%d.%d.%d"):format(target.major, target.minor, target.patch)
79+
local parts = vim.split(version_string, "%.")
80+
current.major = tonumber(parts[1])
81+
current.minor = tonumber(parts[2])
82+
current.patch = tonumber(parts[3]) or 0
83+
84+
local cs = ("%08d%08d%08d"):format(current.major, current.minor, current.patch)
85+
local ts = ("%08d%08d%08d"):format(target.major, target.minor, target.patch)
86+
87+
if cs < ts then
88+
health.report_error(("Git version is outdated! Wanted: %s, current: %s"):format(
89+
target_version_string,
90+
version_string
91+
))
92+
else
93+
health.report_ok("Git is up-to-date.")
94+
end
95+
end)()
96+
end
97+
98+
return M

0 commit comments

Comments
 (0)