From e8530f4059279a0d6b5e5f8891d04ffb1ade29a3 Mon Sep 17 00:00:00 2001 From: William Boman Date: Mon, 3 Jan 2022 15:12:53 +0100 Subject: [PATCH] write install receipts (#379) --- lua/nvim-lsp-installer/core/fetch.lua | 59 ++++++++ lua/nvim-lsp-installer/core/receipt.lua | 134 ++++++++++++++++++ lua/nvim-lsp-installer/data.lua | 10 -- .../installers/composer.lua | 36 +---- lua/nvim-lsp-installer/installers/context.lua | 73 +++------- lua/nvim-lsp-installer/installers/dotnet.lua | 51 +++++++ lua/nvim-lsp-installer/installers/gem.lua | 15 +- lua/nvim-lsp-installer/installers/go.lua | 19 ++- lua/nvim-lsp-installer/installers/init.lua | 16 ++- lua/nvim-lsp-installer/installers/npm.lua | 5 + lua/nvim-lsp-installer/installers/pip3.lua | 5 + lua/nvim-lsp-installer/server.lua | 18 +++ .../servers/ansiblels/init.lua | 9 ++ .../servers/arduino_language_server/init.lua | 6 + lua/nvim-lsp-installer/servers/bicep/init.lua | 3 + lua/nvim-lsp-installer/servers/ccls/init.lua | 12 +- .../servers/clangd/init.lua | 3 + .../servers/clojure_lsp/init.lua | 3 + .../servers/codeqlls/init.lua | 3 + .../servers/csharp_ls/init.lua | 31 +--- .../servers/dartls/init.lua | 14 +- .../servers/denols/init.lua | 3 + .../servers/elixirls/init.lua | 3 + .../servers/erlangls/init.lua | 5 +- .../servers/fsautocomplete/init.lua | 31 +--- .../servers/groovyls/init.lua | 8 ++ lua/nvim-lsp-installer/servers/hls/init.lua | 3 + lua/nvim-lsp-installer/servers/jdtls/init.lua | 30 +++- .../servers/kotlin_language_server/init.lua | 3 + .../servers/lemminx/init.lua | 3 + lua/nvim-lsp-installer/servers/ltex/init.lua | 3 + .../servers/omnisharp/init.lua | 3 + .../servers/phpactor/init.lua | 6 + .../servers/powershell_es/init.lua | 3 + .../servers/puppet/init.lua | 3 + .../servers/quick_lint_js/init.lua | 9 +- .../servers/rescriptls/init.lua | 3 + .../servers/rust_analyzer/init.lua | 3 + .../servers/serve_d/init.lua | 3 + .../servers/solang/init.lua | 3 + lua/nvim-lsp-installer/servers/solc/init.lua | 25 ++-- .../servers/sourcekit/init.lua | 14 +- .../servers/spectral/init.lua | 3 + .../servers/sumneko_lua/init.lua | 3 + lua/nvim-lsp-installer/servers/taplo/init.lua | 5 + .../servers/terraformls/init.lua | 3 + .../servers/texlab/init.lua | 3 + .../servers/tflint/init.lua | 3 + .../servers/vala_ls/init.lua | 3 + lua/nvim-lsp-installer/servers/zk/init.lua | 3 + lua/nvim-lsp-installer/servers/zls/init.lua | 3 + 51 files changed, 522 insertions(+), 199 deletions(-) create mode 100644 lua/nvim-lsp-installer/core/fetch.lua create mode 100644 lua/nvim-lsp-installer/core/receipt.lua create mode 100644 lua/nvim-lsp-installer/installers/dotnet.lua diff --git a/lua/nvim-lsp-installer/core/fetch.lua b/lua/nvim-lsp-installer/core/fetch.lua new file mode 100644 index 0000000000..3e601cb653 --- /dev/null +++ b/lua/nvim-lsp-installer/core/fetch.lua @@ -0,0 +1,59 @@ +local log = require "nvim-lsp-installer.log" +local process = require "nvim-lsp-installer.process" +local platform = require "nvim-lsp-installer.platform" + +---@param url string The url to fetch. +---@param callback fun(err: string|nil, raw_data: string) +local function fetch(url, callback) + local stdio = process.in_memory_sink() + log.fmt_debug("Fetching URL %s", url) + local on_exit = function(success) + if success then + log.fmt_debug("Successfully fetched URL %s", url) + callback(nil, table.concat(stdio.buffers.stdout, "")) + else + local stderr = table.concat(stdio.buffers.stderr, "") + log.fmt_warn("Failed to fetch URL %s. stderr=%s", url, stderr) + callback(("Failed to fetch url %q.\n%s"):format(url, stderr), nil) + end + end + + local job_variants = { + process.lazy_spawn("wget", { + args = { "-nv", "-O", "-", url }, + stdio_sink = stdio.sink, + }), + process.lazy_spawn("curl", { + args = { "-fsSL", url }, + stdio_sink = stdio.sink, + }), + } + + if platform.is_win then + local ps_script = { + "$ProgressPreference = 'SilentlyContinue'", + ("Write-Output (iwr -UseBasicParsing -Uri %q).Content"):format(url), + } + table.insert( + job_variants, + 1, + process.lazy_spawn("powershell.exe", { + args = { "-NoProfile", "-Command", table.concat(ps_script, ";") }, + stdio_sink = stdio.sink, + env = process.graft_env({}, { "PSMODULEPATH" }), + }) + ) + end + + process.attempt { + jobs = job_variants, + on_iterate = function() + log.debug "Flushing stdout/stderr buffers." + stdio.buffers.stdout = {} + stdio.buffers.stderr = {} + end, + on_finish = on_exit, + } +end + +return fetch diff --git a/lua/nvim-lsp-installer/core/receipt.lua b/lua/nvim-lsp-installer/core/receipt.lua new file mode 100644 index 0000000000..5808dfeb1c --- /dev/null +++ b/lua/nvim-lsp-installer/core/receipt.lua @@ -0,0 +1,134 @@ +local M = {} + +---@alias InstallerReceiptSource table + +---@class InstallReceiptBuilder +---@field private secondary_sources InstallerReceiptSource[] +---@field private epoch_time number +local InstallReceiptBuilder = {} +InstallReceiptBuilder.__index = InstallReceiptBuilder + +function InstallReceiptBuilder.new() + return setmetatable({ + secondary_sources = {}, + }, InstallReceiptBuilder) +end + +---@param name string +function InstallReceiptBuilder:with_name(name) + self.name = name + return self +end + +---@alias InstallerReceiptSchemaVersion +---| '"1.0"' + +---@param version InstallerReceiptSchemaVersion +function InstallReceiptBuilder:with_schema_version(version) + self.schema_version = version + return self +end + +---@param source InstallerReceiptSource +function InstallReceiptBuilder:with_primary_source(source) + self.primary_source = source + return self +end + +---@param source InstallerReceiptSource +function InstallReceiptBuilder:with_secondary_source(source) + table.insert(self.secondary_sources, source) + return self +end + +---@param seconds integer +---@param microseconds integer +local function to_ms(seconds, microseconds) + return (seconds * 1000) + math.floor(microseconds / 1000) +end + +---vim.loop.gettimeofday() +---@param seconds integer +---@param microseconds integer +function InstallReceiptBuilder:with_completion_time(seconds, microseconds) + self.completion_time = to_ms(seconds, microseconds) + return self +end + +---vim.loop.gettimeofday() +---@param seconds integer +---@param microseconds integer +function InstallReceiptBuilder:with_start_time(seconds, microseconds) + self.start_time = to_ms(seconds, microseconds) + return self +end + +function InstallReceiptBuilder:build() + assert(self.name, "name is required") + assert(self.schema_version, "schema_version is required") + assert(self.start_time, "start_time is required") + assert(self.completion_time, "completion_time is required") + assert(self.primary_source, "primary_source is required") + return { + name = self.name, + schema_version = self.schema_version, + metrics = { + start_time = self.start_time, + completion_time = self.completion_time, + }, + primary_source = self.primary_source, + secondary_sources = self.secondary_sources, + } +end + +---@param type string +local function package_source(type) + ---@param package string + return function(package) + return { type = type, package = package } + end +end + +InstallReceiptBuilder.npm = package_source "npm" +InstallReceiptBuilder.pip3 = package_source "pip3" +InstallReceiptBuilder.gem = package_source "gem" +InstallReceiptBuilder.go = package_source "go" +InstallReceiptBuilder.dotnet = package_source "dotnet" + +InstallReceiptBuilder.unmanaged = { type = "unmanaged" } + +---@param dependency string +function InstallReceiptBuilder.system(dependency) + return { type = "system", dependency = dependency } +end + +---@param remote_url string +---@param revision string +function InstallReceiptBuilder.git_remote(remote_url, revision) + return { type = "git", remote = remote_url, revision = revision } +end + +---@param ctx ServerInstallContext +---@param opts UseGithubReleaseOpts|nil +function InstallReceiptBuilder.github_release_file(ctx, opts) + opts = opts or {} + return { + type = "github_release_file", + repo = ctx.github_repo, + file = ctx.github_release_file, + release = ctx.requested_server_version, + tag_name_pattern = opts.tag_name_pattern, + } +end + +function InstallReceiptBuilder.github_tag(ctx) + return { + type = "github_tag", + repo = ctx.github_repo, + tag = ctx.requested_server_version, + } +end + +M.InstallReceiptBuilder = InstallReceiptBuilder + +return M diff --git a/lua/nvim-lsp-installer/data.lua b/lua/nvim-lsp-installer/data.lua index dc14ef01fd..3c736c76ca 100644 --- a/lua/nvim-lsp-installer/data.lua +++ b/lua/nvim-lsp-installer/data.lua @@ -122,16 +122,6 @@ function Data.list_any(list, predicate) return false end ----@param data string @The JSON data to decode/deserialize. ----@return table -function Data.json_decode(data) - if vim.json and vim.json.decode then - return vim.json.decode(data) - else - return vim.fn.json_decode(data) - end -end - ---@generic T : fun(...) ---@param fn T ---@param cache_key_generator fun(...): string | nil diff --git a/lua/nvim-lsp-installer/installers/composer.lua b/lua/nvim-lsp-installer/installers/composer.lua index c0e8fe0a13..1e8a171724 100644 --- a/lua/nvim-lsp-installer/installers/composer.lua +++ b/lua/nvim-lsp-installer/installers/composer.lua @@ -1,6 +1,3 @@ -local path = require "nvim-lsp-installer.path" -local fs = require "nvim-lsp-installer.fs" -local Data = require "nvim-lsp-installer.data" local installers = require "nvim-lsp-installer.installers" local std = require "nvim-lsp-installer.installers.std" local platform = require "nvim-lsp-installer.platform" @@ -21,37 +18,10 @@ local function ensure_composer(installer) } end ----@param packages string[] @The Gem packages to install. The first item in this list will be the recipient of the server version, should the user request a specific one. -function M.packages(packages) - return ensure_composer( - ---@type ServerInstallerFunction - function(_, callback, context) - local c = process.chain { - cwd = context.install_dir, - stdio_sink = context.stdio_sink, - } - - if not (fs.file_exists(path.concat { context.install_dir, "composer.json" })) then - c.run(M.composer_cmd, { "init", "--no-interaction", "--stability=dev" }) - c.run(M.composer_cmd, { "config", "prefer-stable", "true" }) - end - - local pkgs = Data.list_copy(packages or {}) - if context.requested_server_version then - -- The "head" package is the recipient for the requested version. It's.. by design... don't ask. - pkgs[1] = ("%s:%s"):format(pkgs[1], context.requested_server_version) - end - - c.run(M.composer_cmd, vim.list_extend({ "require" }, pkgs)) - c.spawn(callback) - end - ) -end - function M.install() return ensure_composer( ---@type ServerInstallerFunction - function(_, callback, context) + function(_, callback, ctx) process.spawn(M.composer_cmd, { args = { "install", @@ -60,8 +30,8 @@ function M.install() "--optimize-autoloader", "--classmap-authoritative", }, - cwd = context.install_dir, - stdio_sink = context.stdio_sink, + cwd = ctx.install_dir, + stdio_sink = ctx.stdio_sink, }, callback) end ) diff --git a/lua/nvim-lsp-installer/installers/context.lua b/lua/nvim-lsp-installer/installers/context.lua index 7889e544ea..6032df1895 100644 --- a/lua/nvim-lsp-installer/installers/context.lua +++ b/lua/nvim-lsp-installer/installers/context.lua @@ -1,66 +1,15 @@ -local Data = require "nvim-lsp-installer.data" local log = require "nvim-lsp-installer.log" local process = require "nvim-lsp-installer.process" local installers = require "nvim-lsp-installer.installers" local platform = require "nvim-lsp-installer.platform" local fs = require "nvim-lsp-installer.fs" local path = require "nvim-lsp-installer.path" +local fetch = require "nvim-lsp-installer.core.fetch" +local Data = require "nvim-lsp-installer.data" -local M = {} - ----@param url string @The url to fetch. ----@param callback fun(err: string|nil, raw_data: string) -local function fetch(url, callback) - local stdio = process.in_memory_sink() - log.fmt_debug("Fetching URL %s", url) - local on_exit = function(success) - if success then - log.fmt_debug("Successfully fetched URL %s", url) - callback(nil, table.concat(stdio.buffers.stdout, "")) - else - local stderr = table.concat(stdio.buffers.stderr, "") - log.fmt_warn("Failed to fetch URL %s. stderr=%s", url, stderr) - callback(("Failed to fetch url %q.\n%s"):format(url, stderr), nil) - end - end - - local job_variants = { - process.lazy_spawn("wget", { - args = { "-nv", "-O", "-", url }, - stdio_sink = stdio.sink, - }), - process.lazy_spawn("curl", { - args = { "-fsSL", url }, - stdio_sink = stdio.sink, - }), - } - - if platform.is_win then - local ps_script = { - "$ProgressPreference = 'SilentlyContinue'", - ("Write-Output (iwr -UseBasicParsing -Uri %q).Content"):format(url), - } - table.insert( - job_variants, - 1, - process.lazy_spawn("powershell.exe", { - args = { "-NoProfile", "-Command", table.concat(ps_script, ";") }, - stdio_sink = stdio.sink, - env = process.graft_env({}, { "PSMODULEPATH" }), - }) - ) - end +local list_find_first = Data.list_find_first - process.attempt { - jobs = job_variants, - on_iterate = function() - log.debug "Flushing stdout/stderr buffers." - stdio.buffers.stdout = {} - stdio.buffers.stderr = {} - end, - on_finish = on_exit, - } -end +local M = {} ---@param repo string @The GitHub repo ("username/repo"). function M.use_github_latest_tag(repo) @@ -84,13 +33,14 @@ function M.use_github_latest_tag(repo) return end - local data = Data.json_decode(raw_data) + local data = vim.json.decode(raw_data) if vim.tbl_count(data) == 0 then context.stdio_sink.stderr("No tags found for GitHub repo %s.\n", repo) callback(false) return end context.requested_server_version = data[1].name + context.github_repo = repo callback(true) end) ) @@ -123,7 +73,7 @@ function M.use_github_release(repo, opts) return callback(false) end - local latest_release = Data.list_find_first(Data.json_decode(response), function(release) + local latest_release = list_find_first(vim.json.decode(response), function(release) local is_stable_release = not release.prerelease and not release.draft if opts.tag_name_pattern then return is_stable_release and release.tag_name:match(opts.tag_name_pattern) @@ -138,6 +88,7 @@ function M.use_github_release(repo, opts) end log.debug("Resolved latest version", server.name, repo, latest_release.tag_name) context.requested_server_version = latest_release.tag_name + context.github_repo = repo callback(true) end) ) @@ -211,6 +162,14 @@ function M.capture(fn) end end +---@param fn fun(receipt_builder: InstallReceiptBuilder, ctx: ServerInstallContext) +function M.receipt(fn) + return M.capture(function(ctx) + fn(ctx.receipt, ctx) + return installers.noop + end) +end + ---Update the context object. ---@param fn fun(context: ServerInstallContext): ServerInstallerFunction function M.set(fn) diff --git a/lua/nvim-lsp-installer/installers/dotnet.lua b/lua/nvim-lsp-installer/installers/dotnet.lua new file mode 100644 index 0000000000..172cd37040 --- /dev/null +++ b/lua/nvim-lsp-installer/installers/dotnet.lua @@ -0,0 +1,51 @@ +local installers = require "nvim-lsp-installer.installers" +local std = require "nvim-lsp-installer.installers.std" +local process = require "nvim-lsp-installer.process" + +local M = {} + +---@param installer ServerInstallerFunction +local function ensure_dotnet(installer) + return installers.pipe { + std.ensure_executables { + { + "dotnet", + "dotnet was not found in path. Refer to https://dotnet.microsoft.com/download for installation instructions.", + }, + }, + installer, + } +end + +---@param package string +function M.package(package) + return ensure_dotnet( + ---@type ServerInstallerFunction + function(_, callback, ctx) + local args = { + "tool", + "update", + "--tool-path", + ".", + } + if ctx.requested_server_version then + vim.list_extend(args, { "--version", ctx.requested_server_version }) + end + vim.list_extend(args, { package }) + process.spawn("dotnet", { + args = args, + cwd = ctx.install_dir, + stdio_sink = ctx.stdio_sink, + }, callback) + ctx.receipt:with_primary_source(ctx.receipt.dotnet(package)) + end + ) +end + +function M.env(root_dir) + return { + PATH = process.extend_path { root_dir }, + } +end + +return M diff --git a/lua/nvim-lsp-installer/installers/gem.lua b/lua/nvim-lsp-installer/installers/gem.lua index 62a7d22213..56d7977f66 100644 --- a/lua/nvim-lsp-installer/installers/gem.lua +++ b/lua/nvim-lsp-installer/installers/gem.lua @@ -17,11 +17,16 @@ function M.packages(packages) { "gem", "gem was not found in path, refer to https://wiki.openstack.org/wiki/RubyGems." }, }, ---@type ServerInstallerFunction - function(_, callback, context) + function(_, callback, ctx) local pkgs = Data.list_copy(packages or {}) - if context.requested_server_version then + if ctx.requested_server_version then -- The "head" package is the recipient for the requested version. It's.. by design... don't ask. - pkgs[1] = ("%s:%s"):format(pkgs[1], context.requested_server_version) + pkgs[1] = ("%s:%s"):format(pkgs[1], ctx.requested_server_version) + end + + ctx.receipt:with_primary_source(ctx.receipt.gem(pkgs[1])) + for i = 2, #pkgs do + ctx.receipt:with_secondary_source(ctx.receipt.gem(pkgs[i])) end process.spawn(M.gem_cmd, { @@ -33,8 +38,8 @@ function M.packages(packages) "--no-document", table.concat(pkgs, " "), }, - cwd = context.install_dir, - stdio_sink = context.stdio_sink, + cwd = ctx.install_dir, + stdio_sink = ctx.stdio_sink, }, callback) end, } diff --git a/lua/nvim-lsp-installer/installers/go.lua b/lua/nvim-lsp-installer/installers/go.lua index 10ac74d8ec..4a979c5da0 100644 --- a/lua/nvim-lsp-installer/installers/go.lua +++ b/lua/nvim-lsp-installer/installers/go.lua @@ -10,21 +10,26 @@ function M.packages(packages) return installers.pipe { std.ensure_executables { { "go", "go was not found in path, refer to https://golang.org/doc/install." } }, ---@type ServerInstallerFunction - function(_, callback, context) + function(_, callback, ctx) local pkgs = Data.list_copy(packages or {}) local c = process.chain { env = process.graft_env { GO111MODULE = "on", - GOBIN = context.install_dir, - GOPATH = context.install_dir, + GOBIN = ctx.install_dir, + GOPATH = ctx.install_dir, }, - cwd = context.install_dir, - stdio_sink = context.stdio_sink, + cwd = ctx.install_dir, + stdio_sink = ctx.stdio_sink, } - if context.requested_server_version then + if ctx.requested_server_version then -- The "head" package is the recipient for the requested version. It's.. by design... don't ask. - pkgs[1] = ("%s@%s"):format(pkgs[1], context.requested_server_version) + pkgs[1] = ("%s@%s"):format(pkgs[1], ctx.requested_server_version) + end + + ctx.receipt:with_primary_source(ctx.receipt.go(pkgs[1])) + for i = 2, #pkgs do + ctx.receipt:with_secondary_source(ctx.receipt.go(pkgs[i])) end c.run("go", vim.list_extend({ "get", "-v" }, pkgs)) diff --git a/lua/nvim-lsp-installer/installers/init.lua b/lua/nvim-lsp-installer/installers/init.lua index ab9ad4f99a..cfe48faa4f 100644 --- a/lua/nvim-lsp-installer/installers/init.lua +++ b/lua/nvim-lsp-installer/installers/init.lua @@ -17,9 +17,11 @@ end ---@alias ServerInstallCallback fun(success: boolean) ---@class ServerInstallContext +---@field receipt InstallReceiptBuilder ---@field requested_server_version string|nil @The version requested by the user. ---@field stdio_sink StdioSink ---@field github_release_file string|nil @Only available if context.use_github_release_file has been called. +---@field github_repo string|nil @Only available if context.use_github_release_file has been called. ---@field os_distribution table @Only available if context.use_os_distribution has been called. ---@field homebrew_prefix string @Only available if context.use_homebrew_prefix has been called. ---@field install_dir string @@ -165,10 +167,20 @@ end ---@param installer ServerInstallerFunction|ServerInstallerFunction[] @The installer to execute in a new installer context. function M.branch_context(installer) ---@type ServerInstallerFunction - return function(server, callback, context) - local new_context = vim.deepcopy(context) + return function(server, callback, ctx) + local receipt = ctx.receipt + -- This temporary nil assignment is done to avoid deepcopy traversing the receipt builder unnecessarily + ctx.receipt = nil + local new_context = vim.deepcopy(ctx) + ctx.receipt = receipt + new_context.receipt = receipt normalize_installer(installer)(server, callback, new_context) end end +---@type ServerInstallerFunction +function M.noop(_, callback) + callback(true) +end + return M diff --git a/lua/nvim-lsp-installer/installers/npm.lua b/lua/nvim-lsp-installer/installers/npm.lua index d479d0d583..f891589e45 100644 --- a/lua/nvim-lsp-installer/installers/npm.lua +++ b/lua/nvim-lsp-installer/installers/npm.lua @@ -49,6 +49,11 @@ local function create_installer(standalone) -- is a bit unreliable across npm versions (especially <7), so we take extra measures to avoid -- inadvertently polluting global npm config. fs.append_file(path.concat { ctx.install_dir, ".npmrc" }, "global-style=true") + + ctx.receipt:with_primary_source(ctx.receipt.npm(pkgs[1])) + for i = 2, #pkgs do + ctx.receipt:with_secondary_source(ctx.receipt.npm(pkgs[i])) + end end -- stylua: ignore start diff --git a/lua/nvim-lsp-installer/installers/pip3.lua b/lua/nvim-lsp-installer/installers/pip3.lua index 3dd44167ff..3ef6f4eb7f 100644 --- a/lua/nvim-lsp-installer/installers/pip3.lua +++ b/lua/nvim-lsp-installer/installers/pip3.lua @@ -37,6 +37,11 @@ local function create_installer(python_executable, packages) pkgs[1] = ("%s==%s"):format(pkgs[1], ctx.requested_server_version) end + ctx.receipt:with_primary_source(ctx.receipt.pip3(pkgs[1])) + for i = 2, #pkgs do + ctx.receipt:with_secondary_source(ctx.receipt.pip3(pkgs[i])) + end + local install_command = { "-m", "pip", "install", "-U" } vim.list_extend(install_command, settings.current.pip.install_args) c.run("python", vim.list_extend(install_command, pkgs)) diff --git a/lua/nvim-lsp-installer/server.lua b/lua/nvim-lsp-installer/server.lua index 153b060556..b06249b349 100644 --- a/lua/nvim-lsp-installer/server.lua +++ b/lua/nvim-lsp-installer/server.lua @@ -7,6 +7,7 @@ local installers = require "nvim-lsp-installer.installers" local servers = require "nvim-lsp-installer.servers" local status_win = require "nvim-lsp-installer.ui.status-win" local path = require "nvim-lsp-installer.path" +local receipt = require "nvim-lsp-installer.core.receipt" local M = {} @@ -173,9 +174,24 @@ function M.Server:promote_install_dir(install_dir) return true end +---@param receipt_builder InstallReceiptBuilder +function M.Server:_write_receipt(receipt_builder) + receipt_builder:with_name(self.name):with_schema_version("1.0"):with_completion_time(vim.loop.gettimeofday()) + + local receipt_success, install_receipt = pcall(receipt_builder.build, receipt_builder) + if receipt_success then + local install_receipt_path = path.concat { self.root_dir, "nvim-lsp-installer-receipt.json" } + pcall(fs.write_file, install_receipt_path, vim.json.encode(install_receipt)) + else + log.fmt_error("Failed to build receipt for server=%s. Error=%s", self.name, install_receipt) + end +end + ---@param context ServerInstallContext ---@param callback ServerInstallCallback function M.Server:install_attached(context, callback) + context.receipt = receipt.InstallReceiptBuilder.new() + context.receipt:with_start_time(vim.loop.gettimeofday()) local context_ok, context_err = pcall(self._setup_install_context, self, context) if not context_ok then log.error("Failed to setup installation context.", context_err) @@ -202,6 +218,8 @@ function M.Server:install_attached(context, callback) -- installation. pcall(fs.rmrf, self:get_tmp_install_dir()) + self:_write_receipt(context.receipt) + -- Dispatch the server is ready vim.schedule(function() dispatcher.dispatch_server_ready(self) diff --git a/lua/nvim-lsp-installer/servers/ansiblels/init.lua b/lua/nvim-lsp-installer/servers/ansiblels/init.lua index c7b55db9de..6c0c6c73bc 100644 --- a/lua/nvim-lsp-installer/servers/ansiblels/init.lua +++ b/lua/nvim-lsp-installer/servers/ansiblels/init.lua @@ -2,6 +2,7 @@ local server = require "nvim-lsp-installer.server" local path = require "nvim-lsp-installer.path" local std = require "nvim-lsp-installer.installers.std" local npm = require "nvim-lsp-installer.installers.npm" +local context = require "nvim-lsp-installer.installers.context" return function(name, root_dir) return server.Server:new { @@ -15,6 +16,14 @@ return function(name, root_dir) npm.exec("npm", { "install" }), npm.run "compile", npm.exec("npm", { "install", "--production" }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source( + receipt.git_remote( + "https://github.com/ansible/ansible-language-server", + ctx.requested_server_version + ) + ) + end), }, default_options = { cmd = { "node", path.concat { root_dir, "out", "server", "src", "server.js" }, "--stdio" }, diff --git a/lua/nvim-lsp-installer/servers/arduino_language_server/init.lua b/lua/nvim-lsp-installer/servers/arduino_language_server/init.lua index 557b0ebe1f..4007803f58 100644 --- a/lua/nvim-lsp-installer/servers/arduino_language_server/init.lua +++ b/lua/nvim-lsp-installer/servers/arduino_language_server/init.lua @@ -56,6 +56,9 @@ return function(name, root_dir) stdio_sink = ctx.stdio_sink, }, callback) end, + context.receipt(function(receipt, ctx) + receipt:with_secondary_source(receipt.github_release_file(ctx)) + end), } local arduino_language_server_installer = installers.branch_context { @@ -82,6 +85,9 @@ return function(name, root_dir) std.rename(("clangd_%s"):format(ctx.requested_server_version), "clangd"), } end), + context.receipt(function(receipt, ctx) + receipt:with_secondary_source(receipt.github_release_file(ctx)) + end), } return server.Server:new { diff --git a/lua/nvim-lsp-installer/servers/bicep/init.lua b/lua/nvim-lsp-installer/servers/bicep/init.lua index 1ebc6b1f05..897709992d 100644 --- a/lua/nvim-lsp-installer/servers/bicep/init.lua +++ b/lua/nvim-lsp-installer/servers/bicep/init.lua @@ -22,6 +22,9 @@ return function(name, root_dir) std.rename(path.concat { "vscode", "extension", "bicepLanguageServer" }, "langserver"), std.rmrf "vscode", context.set_working_dir "langserver", + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd = { "dotnet", path.concat { root_dir, "Bicep.LangServer.dll" } }, diff --git a/lua/nvim-lsp-installer/servers/ccls/init.lua b/lua/nvim-lsp-installer/servers/ccls/init.lua index 60a72a66eb..e77ae80b11 100644 --- a/lua/nvim-lsp-installer/servers/ccls/init.lua +++ b/lua/nvim-lsp-installer/servers/ccls/init.lua @@ -98,6 +98,9 @@ return function(name, root_dir) ), } end), + context.receipt(function(receipt, ctx) + receipt:with_secondary_source(receipt.github_release_file(ctx)) + end), } end @@ -106,13 +109,13 @@ return function(name, root_dir) directory = "ccls-git", recursive = true, }), - function(server, callback, ctx) + function(srv, callback, ctx) local c = process.chain { cwd = path.concat { ctx.install_dir, "ccls-git" }, stdio_sink = ctx.stdio_sink, } - local clang_resource_dir = path.concat { server.root_dir, "clang-resource" } + local clang_resource_dir = path.concat { srv.root_dir, "clang-resource" } c.run( "cmake", @@ -131,6 +134,11 @@ return function(name, root_dir) c.spawn(callback) end, std.rmrf "ccls-git", + context.receipt(function(receipt, ctx) + receipt:with_primary_source( + receipt.git_remote("https://github.com/MaskRay/ccls", ctx.requested_server_version) + ) + end), } local linux_ccls_installer = installers.pipe { diff --git a/lua/nvim-lsp-installer/servers/clangd/init.lua b/lua/nvim-lsp-installer/servers/clangd/init.lua index 7aea65c352..e4e819b838 100644 --- a/lua/nvim-lsp-installer/servers/clangd/init.lua +++ b/lua/nvim-lsp-installer/servers/clangd/init.lua @@ -27,6 +27,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.rename(("clangd_%s"):format(ctx.requested_server_version), "clangd") end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/clojure_lsp/init.lua b/lua/nvim-lsp-installer/servers/clojure_lsp/init.lua index c1c9cde402..5e13fa002f 100644 --- a/lua/nvim-lsp-installer/servers/clojure_lsp/init.lua +++ b/lua/nvim-lsp-installer/servers/clojure_lsp/init.lua @@ -24,6 +24,9 @@ return function(name, root_dir) return std.unzip_remote(ctx.github_release_file) end), std.chmod("+x", { "clojure-lsp" }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/codeqlls/init.lua b/lua/nvim-lsp-installer/servers/codeqlls/init.lua index 64d3a48a6e..9bb82d98e1 100644 --- a/lua/nvim-lsp-installer/servers/codeqlls/init.lua +++ b/lua/nvim-lsp-installer/servers/codeqlls/init.lua @@ -25,6 +25,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/csharp_ls/init.lua b/lua/nvim-lsp-installer/servers/csharp_ls/init.lua index b77030cf1c..82ad425877 100644 --- a/lua/nvim-lsp-installer/servers/csharp_ls/init.lua +++ b/lua/nvim-lsp-installer/servers/csharp_ls/init.lua @@ -1,6 +1,5 @@ local server = require "nvim-lsp-installer.server" -local process = require "nvim-lsp-installer.process" -local std = require "nvim-lsp-installer.installers.std" +local dotnet = require "nvim-lsp-installer.installers.dotnet" return function(name, root_dir) return server.Server:new { @@ -8,33 +7,9 @@ return function(name, root_dir) root_dir = root_dir, languages = { "c#" }, homepage = "https://github.com/razzmatazz/csharp-language-server", - installer = { - std.ensure_executables { - { - "dotnet", - "dotnet was not found in path. Refer to https://dotnet.microsoft.com/download for installation instructions.", - }, - }, - ---@type ServerInstallerFunction - function(_, callback, ctx) - process.spawn("dotnet", { - args = { "tool", "update", "--tool-path", ".", "csharp-ls" }, - cwd = ctx.install_dir, - stdio_sink = ctx.stdio_sink, - }, function(success) - if not success then - ctx.stdio_sink.stderr "Failed to install csharp-ls.\n" - callback(false) - else - callback(true) - end - end) - end, - }, + installer = dotnet.package "csharp-ls", default_options = { - cmd_env = { - PATH = process.extend_path { root_dir }, - }, + cmd_env = dotnet.env(root_dir), }, } end diff --git a/lua/nvim-lsp-installer/servers/dartls/init.lua b/lua/nvim-lsp-installer/servers/dartls/init.lua index 3990b9d95b..433b5667d3 100644 --- a/lua/nvim-lsp-installer/servers/dartls/init.lua +++ b/lua/nvim-lsp-installer/servers/dartls/init.lua @@ -1,5 +1,6 @@ local server = require "nvim-lsp-installer.server" local std = require "nvim-lsp-installer.installers.std" +local context = require "nvim-lsp-installer.installers.context" return function(name, root_dir) return server.Server:new { @@ -7,11 +8,16 @@ return function(name, root_dir) root_dir = root_dir, homepage = "https://github.com/dart-lang/sdk", languages = { "dart" }, - installer = std.ensure_executables { - { - "dart", - "dart was not found in path. Refer to https://dart.dev/get-dart for installation instructions.", + installer = { + std.ensure_executables { + { + "dart", + "dart was not found in path. Refer to https://dart.dev/get-dart for installation instructions.", + }, }, + context.receipt(function(receipt) + receipt:with_primary_source(receipt.system "dart") + end), }, default_options = {}, } diff --git a/lua/nvim-lsp-installer/servers/denols/init.lua b/lua/nvim-lsp-installer/servers/denols/init.lua index ae1a856c40..dfd0ab2a5d 100644 --- a/lua/nvim-lsp-installer/servers/denols/init.lua +++ b/lua/nvim-lsp-installer/servers/denols/init.lua @@ -31,6 +31,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/elixirls/init.lua b/lua/nvim-lsp-installer/servers/elixirls/init.lua index e0f638ea95..7a8f8beae7 100644 --- a/lua/nvim-lsp-installer/servers/elixirls/init.lua +++ b/lua/nvim-lsp-installer/servers/elixirls/init.lua @@ -16,6 +16,9 @@ return function(name, root_dir) return std.unzip_remote(ctx.github_release_file, "elixir-ls") end), std.chmod("+x", { "elixir-ls/language_server.sh" }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd = { diff --git a/lua/nvim-lsp-installer/servers/erlangls/init.lua b/lua/nvim-lsp-installer/servers/erlangls/init.lua index 787fee0b39..749a57b095 100644 --- a/lua/nvim-lsp-installer/servers/erlangls/init.lua +++ b/lua/nvim-lsp-installer/servers/erlangls/init.lua @@ -17,7 +17,7 @@ return function(name, root_dir) std.ensure_executables { { rebar3, ("%s was not found in path. Refer to http://rebar3.org/docs/."):format(rebar3) }, }, - context.use_github_release "erlang-ls/erlang_ls", + context.use_github_latest_tag "erlang-ls/erlang_ls", std.git_clone "https://github.com/erlang-ls/erlang_ls.git", function(_, callback, ctx) local c = process.chain { @@ -28,6 +28,9 @@ return function(name, root_dir) c.run(rebar3, { "as", "dap", "escriptize" }) c.spawn(callback) end, + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_tag(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/fsautocomplete/init.lua b/lua/nvim-lsp-installer/servers/fsautocomplete/init.lua index a14a728688..cd1284e7cc 100644 --- a/lua/nvim-lsp-installer/servers/fsautocomplete/init.lua +++ b/lua/nvim-lsp-installer/servers/fsautocomplete/init.lua @@ -1,6 +1,5 @@ local server = require "nvim-lsp-installer.server" -local process = require "nvim-lsp-installer.process" -local std = require "nvim-lsp-installer.installers.std" +local dotnet = require "nvim-lsp-installer.installers.dotnet" return function(name, root_dir) return server.Server:new { @@ -8,33 +7,9 @@ return function(name, root_dir) root_dir = root_dir, languages = { "f#" }, homepage = "https://github.com/fsharp/FsAutoComplete", - installer = { - std.ensure_executables { - { - "dotnet", - "dotnet was not found in path. Refer to https://dotnet.microsoft.com/download for installation instructions.", - }, - }, - ---@type ServerInstallerFunction - function(_, callback, ctx) - process.spawn("dotnet", { - args = { "tool", "update", "--tool-path", ".", "fsautocomplete" }, - cwd = ctx.install_dir, - stdio_sink = ctx.stdio_sink, - }, function(success) - if not success then - ctx.stdio_sink.stderr "Failed to install fsautocomplete.\n" - callback(false) - else - callback(true) - end - end) - end, - }, + installer = dotnet.package "fsautocomplete", default_options = { - cmd_env = { - PATH = process.extend_path { root_dir }, - }, + cmd_env = dotnet.env(root_dir), }, } end diff --git a/lua/nvim-lsp-installer/servers/groovyls/init.lua b/lua/nvim-lsp-installer/servers/groovyls/init.lua index 5d55dc297c..becc1dd776 100644 --- a/lua/nvim-lsp-installer/servers/groovyls/init.lua +++ b/lua/nvim-lsp-installer/servers/groovyls/init.lua @@ -16,6 +16,14 @@ return function(name, root_dir) std.gradlew { args = { "build" }, }, + context.receipt(function(receipt, ctx) + receipt:with_primary_source( + receipt.git_remote( + "https://github.com/GroovyLanguageServer/groovy-language-server", + ctx.requested_server_version + ) + ) + end), }, default_options = { cmd = { "java", "-jar", path.concat { root_dir, "build", "libs", "groovyls-all.jar" } }, diff --git a/lua/nvim-lsp-installer/servers/hls/init.lua b/lua/nvim-lsp-installer/servers/hls/init.lua index d1987b2238..a5966045b9 100644 --- a/lua/nvim-lsp-installer/servers/hls/init.lua +++ b/lua/nvim-lsp-installer/servers/hls/init.lua @@ -28,6 +28,9 @@ return function(name, root_dir) -- we can't use std.chmod because of shell wildcard expansion unix = shell.sh [[ chmod +x haskell* ]], }, + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/jdtls/init.lua b/lua/nvim-lsp-installer/servers/jdtls/init.lua index 4f3779b621..ddc00c2693 100644 --- a/lua/nvim-lsp-installer/servers/jdtls/init.lua +++ b/lua/nvim-lsp-installer/servers/jdtls/init.lua @@ -4,6 +4,7 @@ local std = require "nvim-lsp-installer.installers.std" local context = require "nvim-lsp-installer.installers.context" local platform = require "nvim-lsp-installer.platform" local Data = require "nvim-lsp-installer.data" +local fetch = require "nvim-lsp-installer.core.fetch" return function(name, root_dir) local function get_cmd(workspace_name) @@ -49,13 +50,38 @@ return function(name, root_dir) languages = { "java" }, homepage = "https://github.com/eclipse/eclipse.jdt.ls", installer = { + ---@type ServerInstallerFunction + function(_, callback, ctx) + if ctx.requested_server_version then + callback(true) + return + end + fetch("https://download.eclipse.org/jdtls/snapshots/latest.txt", function(err, data) + if err then + ctx.stdio_sink.stderr "Failed to fetch latest verison.\n" + callback(false) + else + ctx.requested_server_version = vim.trim(data) + :gsub("^jdt%-language%-server%-", "") + :gsub("%.tar%.gz$", "") + callback(true) + end + end) + end, context.capture(function(ctx) - local version = ctx.requested_server_version or "latest" return std.untargz_remote( - ("https://download.eclipse.org/jdtls/snapshots/jdt-language-server-%s.tar.gz"):format(version) + ("https://download.eclipse.org/jdtls/snapshots/jdt-language-server-%s.tar.gz"):format( + ctx.requested_server_version + ) ) end), std.download_file("https://projectlombok.org/downloads/lombok.jar", "lombok.jar"), + context.receipt(function(receipt, ctx) + receipt:with_primary_source { + type = "jdtls", + version = ctx.requested_server_version, + } + end), }, default_options = { cmd = get_cmd(vim.env.WORKSPACE and vim.env.WORKSPACE or path.concat { vim.env.HOME, "workspace" }), diff --git a/lua/nvim-lsp-installer/servers/kotlin_language_server/init.lua b/lua/nvim-lsp-installer/servers/kotlin_language_server/init.lua index 2d70c2b3f8..4909b56d58 100644 --- a/lua/nvim-lsp-installer/servers/kotlin_language_server/init.lua +++ b/lua/nvim-lsp-installer/servers/kotlin_language_server/init.lua @@ -15,6 +15,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/lemminx/init.lua b/lua/nvim-lsp-installer/servers/lemminx/init.lua index eedce08288..72891a1e4e 100644 --- a/lua/nvim-lsp-installer/servers/lemminx/init.lua +++ b/lua/nvim-lsp-installer/servers/lemminx/init.lua @@ -45,6 +45,9 @@ return function(name, root_dir) platform.is_win and ("%s.exe"):format(unzipped_file) or unzipped_file, platform.is_win and "lemminx.exe" or "lemminx" ), + context.receipt(function(receipt) + receipt:with_primary_source(receipt.unmanaged) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/ltex/init.lua b/lua/nvim-lsp-installer/servers/ltex/init.lua index 3cb8259fdc..5eb10dc051 100644 --- a/lua/nvim-lsp-installer/servers/ltex/init.lua +++ b/lua/nvim-lsp-installer/servers/ltex/init.lua @@ -32,6 +32,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.rename(("ltex-ls-%s"):format(ctx.requested_server_version), "ltex-ls") end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/omnisharp/init.lua b/lua/nvim-lsp-installer/servers/omnisharp/init.lua index 3ee13a9fa3..7d4279b1a1 100644 --- a/lua/nvim-lsp-installer/servers/omnisharp/init.lua +++ b/lua/nvim-lsp-installer/servers/omnisharp/init.lua @@ -32,6 +32,9 @@ return function(name, root_dir) return std.unzip_remote(ctx.github_release_file, "omnisharp") end), std.chmod("+x", { "omnisharp/run" }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd = { diff --git a/lua/nvim-lsp-installer/servers/phpactor/init.lua b/lua/nvim-lsp-installer/servers/phpactor/init.lua index d48f9a2ba0..42ef65f67c 100644 --- a/lua/nvim-lsp-installer/servers/phpactor/init.lua +++ b/lua/nvim-lsp-installer/servers/phpactor/init.lua @@ -3,6 +3,7 @@ local path = require "nvim-lsp-installer.path" local server = require "nvim-lsp-installer.server" local composer = require "nvim-lsp-installer.installers.composer" local std = require "nvim-lsp-installer.installers.std" +local context = require "nvim-lsp-installer.installers.context" local process = require "nvim-lsp-installer.process" return function(name, root_dir) @@ -15,6 +16,11 @@ return function(name, root_dir) unix = { std.git_clone "https://github.com/phpactor/phpactor.git", composer.install(), + context.receipt(function(receipt, ctx) + receipt:with_primary_source( + receipt.git_remote("https://github.com/phpactor/phpactor.git", ctx.requested_server_version) + ) + end), }, }, default_options = { diff --git a/lua/nvim-lsp-installer/servers/powershell_es/init.lua b/lua/nvim-lsp-installer/servers/powershell_es/init.lua index f95ebcf08e..35facc2daa 100644 --- a/lua/nvim-lsp-installer/servers/powershell_es/init.lua +++ b/lua/nvim-lsp-installer/servers/powershell_es/init.lua @@ -20,6 +20,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { bundle_path = path.concat { root_dir }, diff --git a/lua/nvim-lsp-installer/servers/puppet/init.lua b/lua/nvim-lsp-installer/servers/puppet/init.lua index 759fefe116..09842f3015 100644 --- a/lua/nvim-lsp-installer/servers/puppet/init.lua +++ b/lua/nvim-lsp-installer/servers/puppet/init.lua @@ -16,6 +16,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/quick_lint_js/init.lua b/lua/nvim-lsp-installer/servers/quick_lint_js/init.lua index 4944f8bf6a..1f292ae9fb 100644 --- a/lua/nvim-lsp-installer/servers/quick_lint_js/init.lua +++ b/lua/nvim-lsp-installer/servers/quick_lint_js/init.lua @@ -42,19 +42,22 @@ return function(name, root_dir) homepage = "https://quick-lint-js.com/", languages = { "javascript" }, installer = { + context.use_github_latest_tag "quick-lint/quick-lint-js", context.capture(function(ctx) - local requested_server_version = coalesce(ctx.requested_server_version, "latest") local url = "https://c.quick-lint-js.com/releases/%s/manual/%s" if platform.is_windows then - return std.unzip_remote(url:format(requested_server_version, release_file)) + return std.unzip_remote(url:format(ctx.requested_server_version, release_file)) else - return std.untargz_remote(url:format(requested_server_version, release_file)) + return std.untargz_remote(url:format(ctx.requested_server_version, release_file)) end end), installers.on { unix = context.set_working_dir "quick-lint-js", }, + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_tag(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/rescriptls/init.lua b/lua/nvim-lsp-installer/servers/rescriptls/init.lua index 5717c20817..4f0e786518 100644 --- a/lua/nvim-lsp-installer/servers/rescriptls/init.lua +++ b/lua/nvim-lsp-installer/servers/rescriptls/init.lua @@ -16,6 +16,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd = { "node", path.concat { root_dir, "extension", "server", "out", "server.js" }, "--stdio" }, diff --git a/lua/nvim-lsp-installer/servers/rust_analyzer/init.lua b/lua/nvim-lsp-installer/servers/rust_analyzer/init.lua index 5611dca3e1..b2c8f7b8e8 100644 --- a/lua/nvim-lsp-installer/servers/rust_analyzer/init.lua +++ b/lua/nvim-lsp-installer/servers/rust_analyzer/init.lua @@ -46,6 +46,9 @@ return function(name, root_dir) ) end), std.chmod("+x", { "rust-analyzer" }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/serve_d/init.lua b/lua/nvim-lsp-installer/servers/serve_d/init.lua index 36dba64afb..092cbada3a 100644 --- a/lua/nvim-lsp-installer/servers/serve_d/init.lua +++ b/lua/nvim-lsp-installer/servers/serve_d/init.lua @@ -26,6 +26,9 @@ return function(name, root_dir) return std.untarxz_remote(ctx.github_release_file) end end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/solang/init.lua b/lua/nvim-lsp-installer/servers/solang/init.lua index 794c4edb13..c46c90f017 100644 --- a/lua/nvim-lsp-installer/servers/solang/init.lua +++ b/lua/nvim-lsp-installer/servers/solang/init.lua @@ -24,6 +24,9 @@ return function(name, root_dir) return std.download_file(ctx.github_release_file, platform.is_win and "solang.exe" or "solang") end), std.chmod("+x", { "solang" }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), } local llvm_installer = installers.pipe { diff --git a/lua/nvim-lsp-installer/servers/solc/init.lua b/lua/nvim-lsp-installer/servers/solc/init.lua index dd04f59281..bdd2b3317d 100644 --- a/lua/nvim-lsp-installer/servers/solc/init.lua +++ b/lua/nvim-lsp-installer/servers/solc/init.lua @@ -9,28 +9,27 @@ local coalesce, when = Data.coalesce, Data.when return function(name, root_dir) local bin_name = platform.is_win and "solc.exe" or "solc" - return server.Server:new { name = name, root_dir = root_dir, homepage = "https://github.com/ethereum/solidity", languages = { "solidity" }, installer = { - context.capture(function(ctx) - local file_template = coalesce( - when(platform.is_mac, "macosx-amd64/solc-macosx-amd64-%s"), - when(platform.is_linux and platform.arch == "x64", "linux-amd64/solc-linux-amd64-%s"), - when(platform.is_win and platform.arch == "x64", "windows-amd64/solc-windows-amd64-%s.exe") + context.use_github_release_file( + "ethereum/solidity", + coalesce( + when(platform.is_mac, "solc-macos"), + when(platform.is_linux, "solc-static-linux"), + when(platform.is_win, "solc-windows.exe") ) - if not file_template then - error( - ("Current operating system and/or arch (%q) is currently not supported."):format(platform.arch) - ) - end - file_template = file_template:format(coalesce(ctx.requested_server_version, "latest")) - return std.download_file(("https://binaries.soliditylang.org/%s"):format(file_template), bin_name) + ), + context.capture(function(ctx) + return std.download_file(ctx.github_release_file, bin_name) end), std.chmod("+x", { bin_name }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/sourcekit/init.lua b/lua/nvim-lsp-installer/servers/sourcekit/init.lua index 46fb008ccd..b7f3d3a17d 100644 --- a/lua/nvim-lsp-installer/servers/sourcekit/init.lua +++ b/lua/nvim-lsp-installer/servers/sourcekit/init.lua @@ -1,5 +1,6 @@ local server = require "nvim-lsp-installer.server" local std = require "nvim-lsp-installer.installers.std" +local context = require "nvim-lsp-installer.installers.context" return function(name, root_dir) return server.Server:new { @@ -7,11 +8,16 @@ return function(name, root_dir) root_dir = root_dir, homepage = "https://github.com/apple/sourcekit-lsp", languages = { "swift" }, - installer = std.ensure_executables { - { - "sourcekit-lsp", - "sourcekit-lsp was not found in path. Refer to https://github.com/apple/sourcekit-lsp for installation instructions.", + installer = { + std.ensure_executables { + { + "sourcekit-lsp", + "sourcekit-lsp was not found in path. Refer to https://github.com/apple/sourcekit-lsp for installation instructions.", + }, }, + context.receipt(function(receipt) + receipt:with_primary_source(receipt.system "sourcekit-lsp") + end), }, default_options = {}, } diff --git a/lua/nvim-lsp-installer/servers/spectral/init.lua b/lua/nvim-lsp-installer/servers/spectral/init.lua index 0c46be108b..28a0927437 100644 --- a/lua/nvim-lsp-installer/servers/spectral/init.lua +++ b/lua/nvim-lsp-installer/servers/spectral/init.lua @@ -20,6 +20,9 @@ return function(name, root_dir) }, installers.always_succeed(npm.run "compile"), context.set_working_dir "server", + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd = { "node", path.concat { root_dir, "out", "server.js" }, "--stdio" }, diff --git a/lua/nvim-lsp-installer/servers/sumneko_lua/init.lua b/lua/nvim-lsp-installer/servers/sumneko_lua/init.lua index 1d562bb4f8..8294ae9d38 100644 --- a/lua/nvim-lsp-installer/servers/sumneko_lua/init.lua +++ b/lua/nvim-lsp-installer/servers/sumneko_lua/init.lua @@ -39,6 +39,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/taplo/init.lua b/lua/nvim-lsp-installer/servers/taplo/init.lua index c9e405bb38..b1bedb1754 100644 --- a/lua/nvim-lsp-installer/servers/taplo/init.lua +++ b/lua/nvim-lsp-installer/servers/taplo/init.lua @@ -32,6 +32,11 @@ return function(name, root_dir) win = std.unzip_remote(ctx.github_release_file), } end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx, { + tag_name_pattern = "^release%-lsp%-", + })) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/terraformls/init.lua b/lua/nvim-lsp-installer/servers/terraformls/init.lua index 4e4c5bead2..8bcb7f3256 100644 --- a/lua/nvim-lsp-installer/servers/terraformls/init.lua +++ b/lua/nvim-lsp-installer/servers/terraformls/init.lua @@ -38,6 +38,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file, "terraform-ls") end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/texlab/init.lua b/lua/nvim-lsp-installer/servers/texlab/init.lua index 2379c5c0de..4b1e02c932 100644 --- a/lua/nvim-lsp-installer/servers/texlab/init.lua +++ b/lua/nvim-lsp-installer/servers/texlab/init.lua @@ -29,6 +29,9 @@ return function(name, root_dir) win = std.unzip_remote(ctx.github_release_file), } end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/tflint/init.lua b/lua/nvim-lsp-installer/servers/tflint/init.lua index 8a6f987ecf..125afa86d9 100644 --- a/lua/nvim-lsp-installer/servers/tflint/init.lua +++ b/lua/nvim-lsp-installer/servers/tflint/init.lua @@ -28,6 +28,9 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/vala_ls/init.lua b/lua/nvim-lsp-installer/servers/vala_ls/init.lua index 8503579e9f..b3e514311c 100644 --- a/lua/nvim-lsp-installer/servers/vala_ls/init.lua +++ b/lua/nvim-lsp-installer/servers/vala_ls/init.lua @@ -41,6 +41,9 @@ return function(name, root_dir) c.spawn(callback) end, std.rmrf "vala-language-server", + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/zk/init.lua b/lua/nvim-lsp-installer/servers/zk/init.lua index e8ea645a3c..02a416bf80 100644 --- a/lua/nvim-lsp-installer/servers/zk/init.lua +++ b/lua/nvim-lsp-installer/servers/zk/init.lua @@ -51,6 +51,9 @@ return function(name, root_dir) return std.untargz_remote(ctx.github_release_file) end) )), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = { diff --git a/lua/nvim-lsp-installer/servers/zls/init.lua b/lua/nvim-lsp-installer/servers/zls/init.lua index 9840964096..21d522397a 100644 --- a/lua/nvim-lsp-installer/servers/zls/init.lua +++ b/lua/nvim-lsp-installer/servers/zls/init.lua @@ -33,6 +33,9 @@ return function(name, root_dir) end), std.rename("bin", "package"), std.chmod("+x", { path.concat { "package", "zls" } }), + context.receipt(function(receipt, ctx) + receipt:with_primary_source(receipt.github_release_file(ctx)) + end), }, default_options = { cmd_env = {