diff options
| author | William Boman <william@redwill.se> | 2021-10-30 11:05:50 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-10-30 11:05:50 +0200 |
| commit | 8e6615916de6f7d2491e47f8a97870eef0ad36d3 (patch) | |
| tree | 762def1fb61a0fc8a3aaaaa072da3e2c1c535817 /lua | |
| parent | doc: add some docs (diff) | |
| download | mason-8e6615916de6f7d2491e47f8a97870eef0ad36d3.tar mason-8e6615916de6f7d2491e47f8a97870eef0ad36d3.tar.gz mason-8e6615916de6f7d2491e47f8a97870eef0ad36d3.tar.bz2 mason-8e6615916de6f7d2491e47f8a97870eef0ad36d3.tar.lz mason-8e6615916de6f7d2491e47f8a97870eef0ad36d3.tar.xz mason-8e6615916de6f7d2491e47f8a97870eef0ad36d3.tar.zst mason-8e6615916de6f7d2491e47f8a97870eef0ad36d3.zip | |
run installations in tmpdir (#199)
Resolves #154.
Diffstat (limited to 'lua')
| -rw-r--r-- | lua/nvim-lsp-installer/fs.lua | 41 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/composer.lua | 10 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/gem.lua | 4 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/go.lua | 8 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/init.lua | 1 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/npm.lua | 18 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/pip3.lua | 6 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/shell.lua | 4 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/std.lua | 81 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/installers/zx.lua | 5 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/server.lua | 71 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/servers/angularls/init.lua | 4 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/servers/clangd/init.lua | 63 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/servers/erlangls/init.lua | 6 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/servers/ltex/init.lua | 59 | ||||
| -rw-r--r-- | lua/nvim-lsp-installer/servers/vala_ls/init.lua | 8 |
16 files changed, 210 insertions, 179 deletions
diff --git a/lua/nvim-lsp-installer/fs.lua b/lua/nvim-lsp-installer/fs.lua index ed018da2..023d1db5 100644 --- a/lua/nvim-lsp-installer/fs.lua +++ b/lua/nvim-lsp-installer/fs.lua @@ -5,8 +5,14 @@ local settings = require "nvim-lsp-installer.settings" local uv = vim.loop local M = {} +local tmpdir_root = vim.fn.fnamemodify(vim.fn.tempname(), ":h") + local function assert_ownership(path) - if not pathm.is_subdirectory(settings.current.install_root_dir, path) then + if + not pathm.is_subdirectory(settings.current.install_root_dir, path) + and not pathm.is_subdirectory(tmpdir_root, path) + then + log.fmt_error("assert_ownership() failed on path %s", path) error( ("Refusing to operate on path (%s) outside of the servers root dir (%s)."):format( path, @@ -16,6 +22,7 @@ local function assert_ownership(path) end end +---@param path @The full path to the file/dir to recursively delete. Will refuse to operate on paths outside of the install_root dir setting. function M.rmrf(path) log.debug("fs: rmrf", path) assert_ownership(path) @@ -25,13 +32,16 @@ function M.rmrf(path) end end +---@param path string @The full path to the file/dir to rename. Will refuse to operate on paths outside of the install_root dir setting. +---@param new_path string @The full path to the new file/dir name. Will refuse to operate on paths outside of the install_root dir setting. function M.rename(path, new_path) log.debug("fs: rename", path, new_path) assert_ownership(path) assert_ownership(new_path) - uv.fs_rename(path, new_path) + assert(uv.fs_rename(path, new_path)) end +---@param path string @The full path to the directory to create. Will refuse to operate on paths outside of the install_root dir setting. function M.mkdirp(path) log.debug("fs: mkdirp", path) assert_ownership(path) @@ -41,6 +51,15 @@ function M.mkdirp(path) end end +---@param path string @The full path to the directory to create. Will refuse to operate on paths outside of the install_root dir setting. +function M.mkdir(path) + log.debug("fs: mkdir", path) + assert_ownership(path) + assert(uv.fs_mkdir(path, 493)) -- 493(10) == 755(8) +end + +---@param path string @The full path to check if it 1) exists, and 2) is a directory. +---@return boolean function M.dir_exists(path) local ok, stat = pcall(M.fstat, path) if not ok then @@ -49,6 +68,8 @@ function M.dir_exists(path) return stat.type == "directory" end +---@param path string @The full path to check if it 1) exists, and 2) is a file. +---@return boolean function M.file_exists(path) local ok, stat = pcall(M.fstat, path) if not ok then @@ -57,6 +78,8 @@ function M.file_exists(path) return stat.type == "file" end +---@param path string @The full path to the file to get the file status from. +---@return table @Returns a struct of type uv_fs_t. function M.fstat(path) local fd = assert(uv.fs_open(path, "r", 438)) local fstat = assert(uv.fs_fstat(fd)) @@ -64,6 +87,20 @@ function M.fstat(path) return fstat end +---@param path string @The full path to the file to write. +---@param contents string @The contents to write. +function M.write_file(path, contents) + log.fmt_debug("fs: write_file %s", path) + assert_ownership(path) + local fd = assert(uv.fs_open(path, "w", 438)) + uv.fs_write(fd, contents, -1) + assert(uv.fs_close(fd)) +end + +---@alias ReaddirEntry {name: string, type: string} + +---@param path string @The full path to the directory to read. +---@return ReaddirEntry[] function M.readdir(path) local dir = assert(uv.fs_opendir(path, nil, 25)) local all_entries = {} diff --git a/lua/nvim-lsp-installer/installers/composer.lua b/lua/nvim-lsp-installer/installers/composer.lua index ebe591d4..a046575b 100644 --- a/lua/nvim-lsp-installer/installers/composer.lua +++ b/lua/nvim-lsp-installer/installers/composer.lua @@ -25,13 +25,13 @@ local M = {} function M.packages(packages) return ensure_composer( ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) local c = process.chain { - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, } - if not (fs.file_exists(path.concat { server.root_dir, "composer.json" })) then + if not (fs.file_exists(path.concat { context.install_dir, "composer.json" })) then c.run(composer, { "init", "--no-interaction", "--stability=dev" }) c.run(composer, { "config", "prefer-stable", "true" }) end @@ -51,7 +51,7 @@ end function M.install() return ensure_composer( ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) process.spawn(composer, { args = { "install", @@ -60,7 +60,7 @@ function M.install() "--optimize-autoloader", "--classmap-authoritative", }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end diff --git a/lua/nvim-lsp-installer/installers/gem.lua b/lua/nvim-lsp-installer/installers/gem.lua index 331be055..727af496 100644 --- a/lua/nvim-lsp-installer/installers/gem.lua +++ b/lua/nvim-lsp-installer/installers/gem.lua @@ -17,7 +17,7 @@ function M.packages(packages) { "gem", "gem was not found in path, refer to https://wiki.openstack.org/wiki/RubyGems." }, }, ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) 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. @@ -33,7 +33,7 @@ function M.packages(packages) "--no-document", table.concat(pkgs, " "), }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end, diff --git a/lua/nvim-lsp-installer/installers/go.lua b/lua/nvim-lsp-installer/installers/go.lua index c2dbcb37..7fbc1ddc 100644 --- a/lua/nvim-lsp-installer/installers/go.lua +++ b/lua/nvim-lsp-installer/installers/go.lua @@ -11,15 +11,15 @@ 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(server, callback, context) + function(_, callback, context) local pkgs = Data.list_copy(packages or {}) local c = process.chain { env = process.graft_env { GO111MODULE = "on", - GOBIN = server.root_dir, - GOPATH = server.root_dir, + GOBIN = context.install_dir, + GOPATH = context.install_dir, }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, } diff --git a/lua/nvim-lsp-installer/installers/init.lua b/lua/nvim-lsp-installer/installers/init.lua index a9adb74d..08218945 100644 --- a/lua/nvim-lsp-installer/installers/init.lua +++ b/lua/nvim-lsp-installer/installers/init.lua @@ -10,6 +10,7 @@ local M = {} ---@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 install_dir string ---@alias ServerInstallerFunction fun(server: Server, callback: ServerInstallCallback, context: ServerInstallContext) diff --git a/lua/nvim-lsp-installer/installers/npm.lua b/lua/nvim-lsp-installer/installers/npm.lua index d6805b0e..93c33532 100644 --- a/lua/nvim-lsp-installer/installers/npm.lua +++ b/lua/nvim-lsp-installer/installers/npm.lua @@ -29,15 +29,15 @@ local function create_installer(read_version_from_context) return function(packages) return ensure_npm( ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) local pkgs = Data.list_copy(packages or {}) local c = process.chain { - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, } -- stylua: ignore start - if not (fs.dir_exists(path.concat { server.root_dir, "node_modules" }) or - fs.file_exists(path.concat { server.root_dir, "package.json" })) + if not (fs.dir_exists(path.concat { context.install_dir, "node_modules" }) or + fs.file_exists(path.concat { context.install_dir, "package.json" })) then c.run(npm, { "init", "--yes", "--scope=lsp-installer" }) end @@ -66,10 +66,10 @@ M.install = create_installer(false) ---@param args string[] function M.exec(executable, args) ---@type ServerInstallerFunction - return function(server, callback, context) - process.spawn(M.executable(server.root_dir, executable), { + return function(_, callback, context) + process.spawn(M.executable(context.install_dir, executable), { args = args, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end @@ -80,10 +80,10 @@ end function M.run(script) return ensure_npm( ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) process.spawn(npm, { args = { "run", script }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end diff --git a/lua/nvim-lsp-installer/installers/pip3.lua b/lua/nvim-lsp-installer/installers/pip3.lua index 6b593858..0d2b9338 100644 --- a/lua/nvim-lsp-installer/installers/pip3.lua +++ b/lua/nvim-lsp-installer/installers/pip3.lua @@ -21,10 +21,10 @@ local function create_installer(python_executable, packages) }, }, ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) local pkgs = Data.list_copy(packages or {}) local c = process.chain { - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, } @@ -36,7 +36,7 @@ local function create_installer(python_executable, packages) local install_command = { "-m", "pip", "install", "-U" } vim.list_extend(install_command, settings.current.pip.install_args) - c.run(M.executable(server.root_dir, "python"), vim.list_extend(install_command, pkgs)) + c.run(M.executable(context.install_dir, "python"), vim.list_extend(install_command, pkgs)) c.spawn(callback) end, diff --git a/lua/nvim-lsp-installer/installers/shell.lua b/lua/nvim-lsp-installer/installers/shell.lua index eef0e01d..53feda70 100644 --- a/lua/nvim-lsp-installer/installers/shell.lua +++ b/lua/nvim-lsp-installer/installers/shell.lua @@ -6,10 +6,10 @@ local M = {} ---@param opts {shell: string, cmd: string[], env: table|nil} local function shell(opts) ---@type ServerInstallerFunction - return function(server, callback, context) + return function(_, callback, context) local _, stdio = process.spawn(opts.shell, { args = opts.args, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, env = process.graft_env(opts.env or {}), }, callback) diff --git a/lua/nvim-lsp-installer/installers/std.lua b/lua/nvim-lsp-installer/installers/std.lua index 25d35dba..780e8415 100644 --- a/lua/nvim-lsp-installer/installers/std.lua +++ b/lua/nvim-lsp-installer/installers/std.lua @@ -12,18 +12,18 @@ local M = {} function M.download_file(url, out_file) return installers.when { ---@type ServerInstallerFunction - unix = function(server, callback, context) + unix = function(_, callback, context) context.stdio_sink.stdout(("Downloading file %q...\n"):format(url)) process.attempt { jobs = { process.lazy_spawn("wget", { args = { "-nv", "-O", out_file, url }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }), process.lazy_spawn("curl", { args = { "-fsSL", "-o", out_file, url }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }), }, @@ -40,10 +40,10 @@ function M.unzip(file, dest) return installers.pipe { installers.when { ---@type ServerInstallerFunction - unix = function(server, callback, context) + unix = function(_, callback, context) process.spawn("unzip", { args = { "-d", dest, file }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end, @@ -66,10 +66,10 @@ end function M.untar(file) return installers.pipe { ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) process.spawn("tar", { args = { "-xvf", file }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end, @@ -81,21 +81,21 @@ end local function win_extract(file) return installers.pipe { ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) -- The trademarked "throw shit until it sticks" technique local sevenzip = process.lazy_spawn("7z", { args = { "x", "-y", "-r", file }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }) local peazip = process.lazy_spawn("peazip", { - args = { "-ext2here", path.concat { server.root_dir, file } }, -- peazip require absolute paths, or else! - cwd = server.root_dir, + args = { "-ext2here", path.concat { context.install_dir, file } }, -- peazip require absolute paths, or else! + cwd = context.install_dir, stdio_sink = context.stdio_sink, }) local winzip = process.lazy_spawn("wzunzip", { args = { file }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }) process.attempt { @@ -119,11 +119,11 @@ end local function win_arc_unarchive(file) return installers.pipe { ---@type ServerInstallerFunction - function(server, callback, context) + function(_, callback, context) context.stdio_sink.stdout "Attempting to unarchive using arc." process.spawn("arc", { args = { "unarchive", file }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end, @@ -157,10 +157,10 @@ end function M.gunzip(file) return installers.when { ---@type ServerInstallerFunction - unix = function(server, callback, context) + unix = function(_, callback, context) process.spawn("gzip", { args = { "-d", file }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end, @@ -184,8 +184,8 @@ end ---@param rel_path string @The relative path to the file/directory to remove. function M.rmrf(rel_path) ---@type ServerInstallerFunction - return function(server, callback, context) - local abs_path = path.concat { server.root_dir, rel_path } + return function(_, callback, context) + local abs_path = path.concat { context.install_dir, rel_path } context.stdio_sink.stdout(("Deleting %q\n"):format(abs_path)) vim.schedule(function() local ok = pcall(fs.rmrf, abs_path) @@ -199,13 +199,38 @@ function M.rmrf(rel_path) end end +---@param rel_path string @The relative path to the file to write. +---@param contents string @The file contents. +function M.write_file(rel_path, contents) + ---@type ServerInstallerFunction + return function(_, callback, ctx) + local file = path.concat { ctx.install_dir, rel_path } + ctx.stdio_sink.stdout(("Writing file %q\n"):format(file)) + fs.write_file(file, contents) + callback(true) + end +end + +---@param script_rel_path string @The relative path to the script file to write. +---@param abs_target_executable_path string @The absolute path to the executable that is being aliased. +function M.executable_alias(script_rel_path, abs_target_executable_path) + local windows_script = "@call %q %%" + local unix_script = [[#!/usr/bin/env sh +exec %q +]] + return installers.when { + unix = M.write_file(script_rel_path, unix_script:format(abs_target_executable_path)), + win = M.write_file(script_rel_path, windows_script:format(abs_target_executable_path)), + } +end + ---Shallow git clone. ---@param repo_url string function M.git_clone(repo_url) ---@type ServerInstallerFunction - return function(server, callback, context) + return function(_, callback, context) local c = process.chain { - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, } @@ -223,10 +248,10 @@ end ---@param opts {args: string[]} function M.gradlew(opts) ---@type ServerInstallerFunction - return function(server, callback, context) - process.spawn(path.concat { server.root_dir, platform.is_win and "gradlew.bat" or "gradlew" }, { + return function(_, callback, context) + process.spawn(path.concat { context.install_dir, platform.is_win and "gradlew.bat" or "gradlew" }, { args = opts.args, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end @@ -258,11 +283,11 @@ end ---@path new_path string @The relative path to what to rename the file/dir to. function M.rename(old_path, new_path) ---@type ServerInstallerFunction - return function(server, callback, context) + return function(_, callback, context) local ok = pcall( fs.rename, - path.concat { server.root_dir, old_path }, - path.concat { server.root_dir, new_path } + path.concat { context.install_dir, old_path }, + path.concat { context.install_dir, new_path } ) if not ok then context.stdio_sink.stderr(("Failed to rename %q to %q.\n"):format(old_path, new_path)) @@ -276,10 +301,10 @@ end function M.chmod(flags, files) return installers.on { ---@type ServerInstallerFunction - unix = function(server, callback, context) + unix = function(_, callback, context) process.spawn("chmod", { args = vim.list_extend({ flags }, files), - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end, diff --git a/lua/nvim-lsp-installer/installers/zx.lua b/lua/nvim-lsp-installer/installers/zx.lua index 067abfd0..0bba8583 100644 --- a/lua/nvim-lsp-installer/installers/zx.lua +++ b/lua/nvim-lsp-installer/installers/zx.lua @@ -57,10 +57,11 @@ local function zx_installer(force) end local function exec(file) - return function(server, callback, context) + ---@type ServerInstallerFunction + return function(_, callback, context) process.spawn(ZX_EXECUTABLE, { args = { file }, - cwd = server.root_dir, + cwd = context.install_dir, stdio_sink = context.stdio_sink, }, callback) end diff --git a/lua/nvim-lsp-installer/server.lua b/lua/nvim-lsp-installer/server.lua index 2380f47d..159c1e2e 100644 --- a/lua/nvim-lsp-installer/server.lua +++ b/lua/nvim-lsp-installer/server.lua @@ -1,6 +1,7 @@ local dispatcher = require "nvim-lsp-installer.dispatcher" local fs = require "nvim-lsp-installer.fs" local log = require "nvim-lsp-installer.log" +local settings = require "nvim-lsp-installer.settings" local installers = require "nvim-lsp-installer.installers" local servers = require "nvim-lsp-installer.servers" local status_win = require "nvim-lsp-installer.ui.status-win" @@ -86,10 +87,6 @@ function M.Server:is_installed() return servers.is_server_installed(self.name) end -function M.Server:create_root_dir() - fs.mkdirp(self.root_dir) -end - ---Queues the server to be asynchronously installed. function M.Server:install() status_win().install_server(self) @@ -98,27 +95,57 @@ end ---@param context ServerInstallContext ---@param callback ServerInstallCallback function M.Server:install_attached(context, callback) - local uninstall_ok, uninstall_err = pcall(self.uninstall, self) - if not uninstall_ok then - context.stdio_sink.stderr(tostring(uninstall_err) .. "\n") + ---@param path string + local function mkdir(path) + local mkdir_ok, mkdir_err = pcall(fs.mkdir, path) + if not mkdir_ok then + context.stdio_sink.stderr(("Failed to create directory %q.\n"):format(path)) + context.stdio_sink.stderr(tostring(mkdir_err) .. "\n") + return false + end + return true + end + + context.install_dir = vim.fn.tempname() + if not mkdir(context.install_dir) then callback(false) return end - - self:create_root_dir() - - local install_ok, install_err = pcall(self._installer, self, function(success) - if not success then - vim.schedule(function() - pcall(self.uninstall, self) - end) - else - vim.schedule(function() - dispatcher.dispatch_server_ready(self) - end) - end - callback(success) - end, context) + if not fs.dir_exists(settings.current.install_root_dir) and not mkdir(settings.current.install_root_dir) then + callback(false) + return + end + local install_ok, install_err = pcall( + self._installer, + self, + vim.schedule_wrap(function(success) + if success then + if fs.dir_exists(self.root_dir) then + local rmrf_ok, rmrf_err = pcall(fs.rmrf, self.root_dir) + if not rmrf_ok then + context.stdio_sink.stderr "Failed to delete existing installation.\n" + context.stdio_sink.stderr(tostring(rmrf_err) .. "\n") + return + end + end + local rename_ok, rename_err = pcall(fs.rename, context.install_dir, self.root_dir) + if rename_ok then + vim.schedule(function() + dispatcher.dispatch_server_ready(self) + end) + else + context.stdio_sink.stderr( + ("Failed to rename %q to %q.\n"):format(context.install_dir, self.root_dir) + ) + context.stdio_sink.stderr(tostring(rename_err) .. "\n") + callback(false) + return + end + end + callback(success) + end), + context + ) if not install_ok then context.stdio_sink.stderr(tostring(install_err) .. "\n") callback(false) diff --git a/lua/nvim-lsp-installer/servers/angularls/init.lua b/lua/nvim-lsp-installer/servers/angularls/init.lua index 102ad32f..a7217783 100644 --- a/lua/nvim-lsp-installer/servers/angularls/init.lua +++ b/lua/nvim-lsp-installer/servers/angularls/init.lua @@ -7,8 +7,8 @@ return function(name, root_dir) -- Angular requires a node_modules directory to probe for @angular/language-service and typescript -- in order to use your projects configured versions. -- This defaults to the vim cwd, but will get overwritten by the resolved root of the file. - local function get_probe_dir(root_dir) - local project_root = util.find_node_modules_ancestor(root_dir) + local function get_probe_dir(dir) + local project_root = util.find_node_modules_ancestor(dir) return project_root and (project_root .. "/node_modules") or "" end diff --git a/lua/nvim-lsp-installer/servers/clangd/init.lua b/lua/nvim-lsp-installer/servers/clangd/init.lua index fec870c1..25d4a9ec 100644 --- a/lua/nvim-lsp-installer/servers/clangd/init.lua +++ b/lua/nvim-lsp-installer/servers/clangd/init.lua @@ -1,14 +1,14 @@ +local fs = require "nvim-lsp-installer.fs" local server = require "nvim-lsp-installer.server" local path = require "nvim-lsp-installer.path" local Data = require "nvim-lsp-installer.data" local std = require "nvim-lsp-installer.installers.std" local platform = require "nvim-lsp-installer.platform" local context = require "nvim-lsp-installer.installers.context" -local installers = require "nvim-lsp-installer.installers" - -local uv = vim.loop return function(name, root_dir) + local script_name = platform.is_win and "clangd.bat" or "clangd" + return server.Server:new { name = name, root_dir = root_dir, @@ -24,54 +24,23 @@ return function(name, root_dir) context.capture(function(ctx) return std.unzip_remote(ctx.github_release_file) end), - installers.when { - unix = function(server, callback, context) - local executable = path.concat { - server.root_dir, - ("clangd_%s"):format(context.requested_server_version), + context.capture(function(ctx) + -- Preferably we'd not have to write a script file that captures the installed version. + -- But in order to not break backwards compatibility for existing installations of clangd, we do it. + return std.executable_alias( + script_name, + path.concat { + root_dir, + ("clangd_%s"):format(ctx.requested_server_version), "bin", - "clangd", + platform.is_win and "clangd.exe" or "clangd", } - local new_path = path.concat { server.root_dir, "clangd" } - context.stdio_sink.stdout(("Creating symlink from %s to %s\n"):format(executable, new_path)) - uv.fs_symlink(executable, new_path, { dir = false, junction = false }, function(err, success) - if not success then - context.stdio_sink.stderr(tostring(err) .. "\n") - callback(false) - else - callback(true) - end - end) - end, - win = function(server, callback, context) - context.stdio_sink.stdout "Creating clangd.bat...\n" - uv.fs_open(path.concat { server.root_dir, "clangd.bat" }, "w", 438, function(open_err, fd) - local executable = path.concat { - server.root_dir, - ("clangd_%s"):format(context.requested_server_version), - "bin", - "clangd.exe", - } - if open_err then - context.stdio_sink.stderr(tostring(open_err) .. "\n") - return callback(false) - end - uv.fs_write(fd, ("@call %q %%*"):format(executable), -1, function(write_err) - if write_err then - context.stdio_sink.stderr(tostring(write_err) .. "\n") - callback(false) - else - context.stdio_sink.stdout "Created clangd.bat\n" - callback(true) - end - assert(uv.fs_close(fd)) - end) - end) - end, - }, + ) + end), + std.chmod("+x", { "clangd" }), }, default_options = { - cmd = { path.concat { root_dir, platform.is_win and "clangd.bat" or "clangd" } }, + cmd = { path.concat { root_dir, script_name } }, }, } end diff --git a/lua/nvim-lsp-installer/servers/erlangls/init.lua b/lua/nvim-lsp-installer/servers/erlangls/init.lua index 36cca9e4..2b3a3120 100644 --- a/lua/nvim-lsp-installer/servers/erlangls/init.lua +++ b/lua/nvim-lsp-installer/servers/erlangls/init.lua @@ -17,10 +17,10 @@ return function(name, root_dir) }, context.use_github_release "erlang-ls/erlang_ls", std.git_clone "https://github.com/erlang-ls/erlang_ls.git", - function(server, callback, context) + function(_, callback, ctx) local c = process.chain { - cwd = server.root_dir, - stdio_sink = context.stdio_sink, + cwd = ctx.install_dir, + stdio_sink = ctx.stdio_sink, } local rebar3 = platform.is_win and "rebar3.cmd" or "rebar3" c.run(rebar3, { "escriptize" }) diff --git a/lua/nvim-lsp-installer/servers/ltex/init.lua b/lua/nvim-lsp-installer/servers/ltex/init.lua index aaae5543..216fb1b6 100644 --- a/lua/nvim-lsp-installer/servers/ltex/init.lua +++ b/lua/nvim-lsp-installer/servers/ltex/init.lua @@ -11,6 +11,8 @@ local uv = vim.loop local coalesce, when = Data.coalesce, Data.when return function(name, root_dir) + local script_name = platform.is_win and "ltex-ls.bat" or "ltex-ls" + return server.Server:new { name = name, root_dir = root_dir, @@ -31,58 +33,27 @@ return function(name, root_dir) return std.untargz_remote(ctx.github_release_file) end end), - installers.when { - unix = function(server, callback, context) - local executable = path.concat { - server.root_dir, - ("ltex-ls-%s"):format(context.requested_server_version), + context.capture(function(ctx) + -- Preferably we'd not have to write a script file that captures the installed version. + -- But in order to not break backwards compatibility for existing installations of ltex, we do it. + return std.executable_alias( + script_name, + path.concat { + root_dir, + ("ltex-ls-%s"):format(ctx.requested_server_version), "bin", - "ltex-ls", + platform.is_win and "ltex-ls.bat" or "ltex-ls", } - local new_path = path.concat { server.root_dir, "ltex-ls" } - context.stdio_sink.stdout(("Creating symlink from %s to %s\n"):format(executable, new_path)) - uv.fs_symlink(executable, new_path, { dir = false, junction = false }, function(err, success) - if not success then - context.stdio_sink.stderr(tostring(err) .. "\n") - callback(false) - else - callback(true) - end - end) - end, - win = function(server, callback, context) - context.stdio_sink.stdout "Creating ltex-ls.bat...\n" - uv.fs_open(path.concat { server.root_dir, "ltex-ls.bat" }, "w", 438, function(open_err, fd) - local executable = path.concat { - server.root_dir, - ("ltex-ls-%s"):format(context.requested_server_version), - "bin", - "ltex-ls.bat", - } - if open_err then - context.stdio_sink.stderr(tostring(open_err) .. "\n") - return callback(false) - end - uv.fs_write(fd, ("@call %q %%*"):format(executable), -1, function(write_err) - if write_err then - context.stdio_sink.stderr(tostring(write_err) .. "\n") - callback(false) - else - context.stdio_sink.stdout "Created ltex-ls.bat\n" - callback(true) - end - assert(uv.fs_close(fd)) - end) - end) - end, - }, + ) + end), + std.chmod("+x", { "ltex-ls" }), }, pre_setup = function() require "nvim-lsp-installer.servers.ltex.configure" end, default_options = { filetypes = { "tex", "bib", "markdown" }, - cmd = { path.concat { root_dir, platform.is_win and "ltex-ls.bat" or "ltex-ls" } }, + cmd = { path.concat { root_dir, script_name } }, }, } end diff --git a/lua/nvim-lsp-installer/servers/vala_ls/init.lua b/lua/nvim-lsp-installer/servers/vala_ls/init.lua index 5eed06e4..cfa8a75f 100644 --- a/lua/nvim-lsp-installer/servers/vala_ls/init.lua +++ b/lua/nvim-lsp-installer/servers/vala_ls/init.lua @@ -25,13 +25,13 @@ return function(name, root_dir) std.rename(("vala-language-server-%s"):format(ctx.requested_server_version), "vala-language-server"), } end), - function(server, callback, context) + function(_, callback, ctx) local c = process.chain { - cwd = path.concat { server.root_dir, "vala-language-server" }, - stdio_sink = context.stdio_sink, + cwd = path.concat { cwd.install_dir, "vala-language-server" }, + stdio_sink = ctx.stdio_sink, } - c.run("meson", { ("-Dprefix=%s"):format(server.root_dir), "build" }) + c.run("meson", { ("-Dprefix=%s"):format(ctx.install_dir), "build" }) c.run("ninja", { "-C", "build", "install" }) c.spawn(callback) |
