aboutsummaryrefslogtreecommitdiffstats
path: root/lua
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2021-10-06 15:17:43 +0200
committerGitHub <noreply@github.com>2021-10-06 15:17:43 +0200
commitd09ada1a3ed7fb35fefc20eb5daa4b767fc73906 (patch)
tree2152516dba481350642db27df018c1f60a3171f1 /lua
parentwindows: add -UseBasicParsing for iwr calls (diff)
downloadmason-d09ada1a3ed7fb35fefc20eb5daa4b767fc73906.tar
mason-d09ada1a3ed7fb35fefc20eb5daa4b767fc73906.tar.gz
mason-d09ada1a3ed7fb35fefc20eb5daa4b767fc73906.tar.bz2
mason-d09ada1a3ed7fb35fefc20eb5daa4b767fc73906.tar.lz
mason-d09ada1a3ed7fb35fefc20eb5daa4b767fc73906.tar.xz
mason-d09ada1a3ed7fb35fefc20eb5daa4b767fc73906.tar.zst
mason-d09ada1a3ed7fb35fefc20eb5daa4b767fc73906.zip
windows: attempt all common archiver programs (#136)
Diffstat (limited to 'lua')
-rw-r--r--lua/nvim-lsp-installer/fs.lua2
-rw-r--r--lua/nvim-lsp-installer/installers/init.lua44
-rw-r--r--lua/nvim-lsp-installer/installers/std.lua103
-rw-r--r--lua/nvim-lsp-installer/process.lua84
4 files changed, 179 insertions, 54 deletions
diff --git a/lua/nvim-lsp-installer/fs.lua b/lua/nvim-lsp-installer/fs.lua
index ab775f4d..e6864685 100644
--- a/lua/nvim-lsp-installer/fs.lua
+++ b/lua/nvim-lsp-installer/fs.lua
@@ -19,7 +19,7 @@ end
function M.rename(path, new_path)
assert_ownership(path)
assert_ownership(new_path)
- return uv.fs_rename(path, new_path)
+ uv.fs_rename(path, new_path)
end
function M.mkdirp(path)
diff --git a/lua/nvim-lsp-installer/installers/init.lua b/lua/nvim-lsp-installer/installers/init.lua
index 0dd48972..83b46a1b 100644
--- a/lua/nvim-lsp-installer/installers/init.lua
+++ b/lua/nvim-lsp-installer/installers/init.lua
@@ -1,4 +1,5 @@
local platform = require "nvim-lsp-installer.platform"
+local log = require "nvim-lsp-installer.log"
local Data = require "nvim-lsp-installer.data"
local M = {}
@@ -32,6 +33,37 @@ function M.pipe(installers)
end
end
+function M.first_successful(installers)
+ if #installers == 0 then
+ error "No installers to pipe."
+ end
+
+ return function(server, callback, context)
+ local function execute(idx)
+ log.fmt_trace("Executing installer idx=%d", idx)
+ local ok, err = pcall(installers[idx], server, function(success)
+ log.fmt_trace("Installer idx=%d on exit with success=%s", idx, success)
+ if not success and installers[idx + 1] then
+ -- iterate
+ execute(idx + 1)
+ else
+ callback(success)
+ end
+ end, context)
+ if not ok then
+ context.stdio_sink.stderr(tostring(err) .. "\n")
+ if installers[idx + 1] then
+ execute(idx + 1)
+ else
+ callback(false)
+ end
+ end
+ end
+
+ execute(1)
+ end
+end
+
-- much fp, very wow
function M.compose(installers)
return M.pipe(Data.list_reverse(installers))
@@ -64,7 +96,11 @@ function M.on(platform_table)
return function(server, callback, context)
local installer = get_by_platform(platform_table)
if installer then
- installer(server, callback, context)
+ if type(installer) == "function" then
+ installer(server, callback, context)
+ else
+ M.pipe(installer)(server, callback, context)
+ end
else
callback(true)
end
@@ -76,7 +112,11 @@ function M.when(platform_table)
return function(server, callback, context)
local installer = get_by_platform(platform_table)
if installer then
- installer(server, callback, context)
+ if type(installer) == "function" then
+ installer(server, callback, context)
+ else
+ M.pipe(installer)(server, callback, context)
+ end
else
context.stdio_sink.stderr(
("Current operating system is not yet supported for server %q.\n"):format(server.name)
diff --git a/lua/nvim-lsp-installer/installers/std.lua b/lua/nvim-lsp-installer/installers/std.lua
index bdd60eca..c7728fe7 100644
--- a/lua/nvim-lsp-installer/installers/std.lua
+++ b/lua/nvim-lsp-installer/installers/std.lua
@@ -1,4 +1,5 @@
local path = require "nvim-lsp-installer.path"
+local fs = require "nvim-lsp-installer.fs"
local process = require "nvim-lsp-installer.process"
local platform = require "nvim-lsp-installer.platform"
local installers = require "nvim-lsp-installer.installers"
@@ -52,15 +53,60 @@ function M.unzip_remote(url, dest)
}
end
-function M.untar(file, opts)
- local default_opts = {
- strip_components = 0,
- }
- opts = vim.tbl_deep_extend("force", default_opts, opts or {})
+function M.untar(file)
return installers.pipe {
function(server, callback, context)
process.spawn("tar", {
- args = { "-xvf", file, "--strip-components", opts.strip_components },
+ args = { "-xvf", file },
+ cwd = server.root_dir,
+ stdio_sink = context.stdio_sink,
+ }, callback)
+ end,
+ installers.always_succeed(M.delete_file(file)),
+ }
+end
+
+local function win_extract(file)
+ return installers.pipe {
+ function(server, 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,
+ 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,
+ stdio_sink = context.stdio_sink,
+ })
+ local winzip = process.lazy_spawn("wzunzip", {
+ args = { file },
+ cwd = server.root_dir,
+ stdio_sink = context.stdio_sink,
+ })
+ process.attempt {
+ jobs = { sevenzip, peazip, winzip },
+ on_finish = callback,
+ }
+ end,
+ installers.always_succeed(M.delete_file(file)),
+ }
+end
+
+local function win_untarxz(file)
+ return installers.pipe {
+ win_extract(file),
+ M.untar(file:gsub(".xz$", "")),
+ }
+end
+
+local function win_arc_unarchive(file)
+ return installers.pipe {
+ function(server, callback, context)
+ context.stdio_sink.stdout "Attempting to unarchive using arc."
+ process.spawn("arc", {
+ args = { "unarchive", file },
cwd = server.root_dir,
stdio_sink = context.stdio_sink,
}, callback)
@@ -69,28 +115,37 @@ function M.untar(file, opts)
}
end
-function M.untarxz_remote(url, tar_opts)
+function M.untarxz_remote(url)
return installers.pipe {
M.download_file(url, "archive.tar.xz"),
- M.untar("archive.tar.xz", tar_opts),
+ installers.when {
+ unix = M.untar "archive.tar.xz",
+ win = installers.first_successful {
+ win_untarxz "archive.tar.xz",
+ win_arc_unarchive "archive.tar.xz",
+ },
+ },
}
end
-function M.untargz_remote(url, tar_opts)
+function M.untargz_remote(url)
return installers.pipe {
M.download_file(url, "archive.tar.gz"),
- M.untar("archive.tar.gz", tar_opts),
+ M.untar "archive.tar.gz",
}
end
function M.gunzip(file)
- return function(server, callback, context)
- process.spawn("gzip", {
- args = { "-d", file },
- cwd = server.root_dir,
- stdio_sink = context.stdio_sink,
- }, callback)
- end
+ return installers.when {
+ unix = function(server, callback, context)
+ process.spawn("gzip", {
+ args = { "-d", file },
+ cwd = server.root_dir,
+ stdio_sink = context.stdio_sink,
+ }, callback)
+ end,
+ win = win_extract(file),
+ }
end
function M.gunzip_remote(url, out_file)
@@ -159,6 +214,20 @@ function M.ensure_executables(executables)
end)
end
+function M.rename(old_path, new_path)
+ return function(server, callback, context)
+ local ok = pcall(
+ fs.rename,
+ path.concat { server.root_dir, old_path },
+ path.concat { server.root_dir, new_path }
+ )
+ if not ok then
+ context.stdio_sink.stderr(("Failed to rename %q to %q.\n"):format(old_path, new_path))
+ end
+ callback(ok)
+ end
+end
+
function M.chmod(flags, files)
return installers.on {
unix = function(server, callback, context)
diff --git a/lua/nvim-lsp-installer/process.lua b/lua/nvim-lsp-installer/process.lua
index e7ede690..f81ba8cb 100644
--- a/lua/nvim-lsp-installer/process.lua
+++ b/lua/nvim-lsp-installer/process.lua
@@ -62,7 +62,7 @@ local function sanitize_env_list(env_list)
sanitized_list[#sanitized_list + 1] = env
else
local idx = env:find "="
- sanitized_list[#sanitized_list + 1] = env:sub(1, idx) .. "=<redacted>"
+ sanitized_list[#sanitized_list + 1] = env:sub(1, idx) .. "<redacted>"
end
end
return sanitized_list
@@ -115,6 +115,8 @@ function M.spawn(cmd, opts, callback)
check:stop()
callback(successful)
end)
+
+ log.fmt_debug("Job pid=%s exited with exit_code=%s, signal=%s", pid_or_err, exit_code, signal)
end)
if handle == nil then
@@ -137,29 +139,31 @@ function M.spawn(cmd, opts, callback)
end
function M.chain(opts)
- local stack = {}
+ local jobs = {}
return {
run = function(cmd, args)
- stack[#stack + 1] = { cmd = cmd, args = args }
+ jobs[#jobs + 1] = M.lazy_spawn(
+ cmd,
+ vim.tbl_deep_extend("force", opts, {
+ args = args,
+ })
+ )
end,
spawn = function(callback)
local function execute(idx)
- local item = stack[idx]
- M.spawn(
- item.cmd,
- vim.tbl_deep_extend("force", opts, {
- args = item.args,
- }),
- function(successful)
- if successful and stack[idx + 1] then
- -- iterate
- execute(idx + 1)
- else
- -- we done
- callback(successful)
- end
+ local ok, err = pcall(jobs[idx], function(successful)
+ if successful and jobs[idx + 1] then
+ -- iterate
+ execute(idx + 1)
+ else
+ -- we done
+ callback(successful)
end
- )
+ end)
+ if not ok then
+ log.fmt_error("Chained job failed to execute. Error=%s", tostring(err))
+ callback(false)
+ end
end
execute(1)
@@ -226,24 +230,36 @@ function M.attempt(opts)
if #jobs == 0 then
error "process.attempt(...) need at least one job."
end
- local function spawn(idx)
- jobs[idx](function(success)
- if success then
- -- this job succeeded. exit early
- on_finish(true)
- elseif jobs[idx + 1] then
- -- iterate
- if on_iterate then
- on_iterate()
- end
- log.debug "Previous job failed, attempting next."
- spawn(idx + 1)
- else
- -- we exhausted all jobs without success
- log.debug "All jobs failed."
- on_finish(false)
+
+ local spawn, on_job_exit
+
+ on_job_exit = function(cur_idx, success)
+ if success then
+ -- this job succeeded. exit early
+ on_finish(true)
+ elseif jobs[cur_idx + 1] then
+ -- iterate
+ if on_iterate then
+ on_iterate()
end
+ log.debug "Previous job failed, attempting next."
+ spawn(cur_idx + 1)
+ else
+ -- we exhausted all jobs without success
+ log.debug "All jobs failed."
+ on_finish(false)
+ end
+ end
+
+ spawn = function(idx)
+ local ok, err = pcall(jobs[idx], function(success)
+ on_job_exit(idx, success)
end)
+ if not ok then
+ log.fmt_error("Job failed to execute. Error=%s", tostring(err))
+ on_job_exit(idx, false)
+ on_finish(false)
+ end
end
spawn(1)