1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
local a = require "nvim-lsp-installer.core.async"
local Result = require "nvim-lsp-installer.core.result"
local process = require "nvim-lsp-installer.process"
local pip3 = require "nvim-lsp-installer.installers.pip3"
local gem = require "nvim-lsp-installer.installers.gem"
local cargo_check = require "nvim-lsp-installer.jobs.outdated-servers.cargo"
local gem_check = require "nvim-lsp-installer.jobs.outdated-servers.gem"
local pip3_check = require "nvim-lsp-installer.jobs.outdated-servers.pip3"
local spawn = require "nvim-lsp-installer.core.async.spawn"
local M = {}
local ServerVersion = {}
ServerVersion.__index = ServerVersion
---@param field_name string
local function version_in_receipt(field_name)
---@param receipt InstallReceipt
---@return Result
return function(_, receipt)
return Result.success(receipt.primary_source[field_name])
end
end
local function noop()
return Result.failure "Unable to detect version."
end
---@type Record<InstallReceiptSourceType, fun(server: Server, receipt: InstallReceipt): Result>
local version_checker = {
["npm"] = function(server, receipt)
return spawn.npm({
"ls",
"--json",
cwd = server.root_dir,
}):map_catching(function(result)
local npm_packages = vim.json.decode(result.stdout)
return npm_packages.dependencies[receipt.primary_source.package].version
end)
end,
["pip3"] = function(server, receipt)
return spawn.python3({
"-m",
"pip",
"list",
"--format",
"json",
cwd = server.root_dir,
env = process.graft_env(pip3.env(server.root_dir)),
}):map_catching(function(result)
local pip_packages = vim.json.decode(result.stdout)
local normalized_pip_package = pip3_check.normalize_package(receipt.primary_source.package)
for _, pip_package in ipairs(pip_packages) do
if pip_package.name == normalized_pip_package then
return pip_package.version
end
end
error "Unable to find pip package."
end)
end,
["gem"] = function(server, receipt)
return spawn.gem({
"list",
cwd = server.root_dir,
env = process.graft_env(gem.env(server.root_dir)),
}):map_catching(function(result)
local gems = gem_check.parse_gem_list_output(result.stdout)
if gems[receipt.primary_source.package] then
return gems[receipt.primary_source.package]
else
error "Failed to find gem package version."
end
end)
end,
["cargo"] = function(server, receipt)
return spawn.cargo({
"install",
"--list",
"--root",
server.root_dir,
cwd = server.root_dir,
}):map_catching(function(result)
local crates = cargo_check.parse_installed_crates(result.stdout)
a.scheduler() -- needed because vim.fn.* call
local package = vim.fn.fnamemodify(receipt.primary_source.package, ":t")
if crates[package] then
return crates[package]
else
error "Failed to find cargo package version."
end
end)
end,
["git"] = function(server)
return spawn.git({
"rev-parse",
"--short",
"HEAD",
cwd = server.root_dir,
}):map_catching(function(result)
return vim.trim(result.stdout)
end)
end,
["opam"] = noop,
["dotnet"] = noop,
["r_package"] = noop,
["github_release_file"] = version_in_receipt "release",
["github_tag"] = version_in_receipt "tag",
["jdtls"] = version_in_receipt "version",
}
--- Async function.
---@param server Server
---@return Result
function M.check_server_version(server)
local receipt = server:get_receipt()
if not receipt then
return Result.failure "Unable to retrieve installation receipt."
end
local version_check = version_checker[receipt.primary_source.type] or noop
local ok, result = pcall(version_check, server, receipt)
if ok then
return result
else
return Result.failure(result)
end
end
return M
|