aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lua/nvim-lsp-installer/fs.lua18
-rw-r--r--lua/nvim-lsp-installer/server.lua52
2 files changed, 37 insertions, 33 deletions
diff --git a/lua/nvim-lsp-installer/fs.lua b/lua/nvim-lsp-installer/fs.lua
index 023d1db5..b6dce79d 100644
--- a/lua/nvim-lsp-installer/fs.lua
+++ b/lua/nvim-lsp-installer/fs.lua
@@ -5,13 +5,8 @@ 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)
- and not pathm.is_subdirectory(tmpdir_root, path)
- then
+ if not pathm.is_subdirectory(settings.current.install_root_dir, 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(
@@ -22,7 +17,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.
+---@param path string @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)
@@ -58,6 +53,15 @@ function M.mkdir(path)
assert(uv.fs_mkdir(path, 493)) -- 493(10) == 755(8)
end
+---Recursively removes the path if it exists before creating a directory.
+---@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.rm_mkdirp(path)
+ if M.dir_exists(path) then
+ M.rmrf(path)
+ end
+ return M.mkdirp(path)
+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)
diff --git a/lua/nvim-lsp-installer/server.lua b/lua/nvim-lsp-installer/server.lua
index 38ffc52f..5339d1ce 100644
--- a/lua/nvim-lsp-installer/server.lua
+++ b/lua/nvim-lsp-installer/server.lua
@@ -5,6 +5,7 @@ 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"
+local path = require "nvim-lsp-installer.path"
local M = {}
@@ -104,26 +105,21 @@ function M.Server:install()
end
---@param context ServerInstallContext
----@param callback ServerInstallCallback
-function M.Server:install_attached(context, callback)
- ---@param path string
- local function mkdir(path)
- local mkdir_ok, mkdir_err = pcall(fs.mkdir, path)
- if not mkdir_ok then
- log.fmt_error("Failed to mkdir. path=%s error=%s", path, mkdir_err)
- 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
+function M.Server:_setup_install_context(context)
+ context.install_dir = path.concat { settings.current.install_root_dir, ("%s.tmp"):format(self.name) }
+ fs.rm_mkdirp(context.install_dir)
- context.install_dir = vim.fn.tempname()
- if not mkdir(context.install_dir) then
- callback(false)
- return
+ if not fs.dir_exists(settings.current.install_root_dir) then
+ fs.mkdirp(settings.current.install_root_dir)
end
- if not fs.dir_exists(settings.current.install_root_dir) and not mkdir(settings.current.install_root_dir) then
+end
+
+---@param context ServerInstallContext
+---@param callback ServerInstallCallback
+function M.Server:install_attached(context, callback)
+ 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)
callback(false)
return
end
@@ -132,17 +128,20 @@ function M.Server:install_attached(context, callback)
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
- log.fmt_error("Failed to rmrf. path=%s error=%s", self.root_dir, rmrf_err)
- context.stdio_sink.stderr "Failed to delete existing installation.\n"
- context.stdio_sink.stderr(tostring(rmrf_err) .. "\n")
- return
- end
+ -- 1. Remove and recreate final installation directory
+ local rmrf_ok, rmrf_err = pcall(fs.rm_mkdirp, self.root_dir)
+ if not rmrf_ok then
+ log.fmt_error("Failed to rm_mkdirp. path=%s error=%s", self.root_dir, rmrf_err)
+ context.stdio_sink.stderr "Failed to remove and recreate final installation directory.\n"
+ context.stdio_sink.stderr(tostring(rmrf_err) .. "\n")
+ callback(false)
+ return
end
+
+ -- 2. Move the temporary install dir to the final installation directory
local rename_ok, rename_err = pcall(fs.rename, context.install_dir, self.root_dir)
if rename_ok then
+ -- 3a. Dispatch the server is ready
vim.schedule(function()
dispatcher.dispatch_server_ready(self)
for _, on_ready_handler in ipairs(self._on_ready_handlers) do
@@ -150,6 +149,7 @@ function M.Server:install_attached(context, callback)
end
end)
else
+ --- 3b. We failed to rename the temporary dir to the final installation dir
log.fmt_error(
"Failed to rename. path=%s new_path=%s error=%s",
context.install_dir,