diff options
| author | William Boman <william@redwill.se> | 2022-04-11 17:19:01 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-11 17:19:01 +0200 |
| commit | 88f590ce0e01767bcc8dfdc862a456efde77d4a0 (patch) | |
| tree | 2f5faaffa76b9147a873b2adc3286b6624144976 /lua/nvim-lsp-installer/core/managers | |
| parent | fix(verible): use correct unpacked directory name on Windows (#589) (diff) | |
| download | mason-88f590ce0e01767bcc8dfdc862a456efde77d4a0.tar mason-88f590ce0e01767bcc8dfdc862a456efde77d4a0.tar.gz mason-88f590ce0e01767bcc8dfdc862a456efde77d4a0.tar.bz2 mason-88f590ce0e01767bcc8dfdc862a456efde77d4a0.tar.lz mason-88f590ce0e01767bcc8dfdc862a456efde77d4a0.tar.xz mason-88f590ce0e01767bcc8dfdc862a456efde77d4a0.tar.zst mason-88f590ce0e01767bcc8dfdc862a456efde77d4a0.zip | |
more async refactor (#587)
Diffstat (limited to 'lua/nvim-lsp-installer/core/managers')
7 files changed, 210 insertions, 20 deletions
diff --git a/lua/nvim-lsp-installer/core/managers/cargo/client.lua b/lua/nvim-lsp-installer/core/managers/cargo/client.lua new file mode 100644 index 00000000..7e69cdf4 --- /dev/null +++ b/lua/nvim-lsp-installer/core/managers/cargo/client.lua @@ -0,0 +1,14 @@ +local fetch = require "nvim-lsp-installer.core.fetch" + +local M = {} + +---@alias CrateResponse {crate: {id: string, max_stable_version: string, max_version: string, newest_version: string}} + +---@async +---@param crate string +---@return Result @of [Crate] +function M.fetch_crate(crate) + return fetch(("https://crates.io/api/v1/crates/%s"):format(crate)):map_catching(vim.json.decode) +end + +return M diff --git a/lua/nvim-lsp-installer/core/managers/cargo/init.lua b/lua/nvim-lsp-installer/core/managers/cargo/init.lua index 5d74e010..84beaf1e 100644 --- a/lua/nvim-lsp-installer/core/managers/cargo/init.lua +++ b/lua/nvim-lsp-installer/core/managers/cargo/init.lua @@ -3,11 +3,8 @@ local path = require "nvim-lsp-installer.path" local spawn = require "nvim-lsp-installer.core.spawn" local a = require "nvim-lsp-installer.core.async" local Optional = require "nvim-lsp-installer.core.optional" -local crates = require "nvim-lsp-installer.core.clients.crates" -local Result = require "nvim-lsp-installer.core.result" local installer = require "nvim-lsp-installer.core.installer" - -local fetch_crate = a.promisify(crates.fetch_crate, true) +local client = require "nvim-lsp-installer.core.managers.cargo.client" ---@param crate string local function with_receipt(crate) @@ -58,7 +55,7 @@ function M.install(crate, opts) end ---@param output string @The `cargo install --list` output. ----@return Record<string, string> @Key is the crate name, value is its version. +---@return table<string, string> @Key is the crate name, value is its version. function M.parse_installed_crates(output) local installed_crates = {} for _, line in ipairs(vim.split(output, "\n")) do @@ -74,18 +71,19 @@ end ---@param receipt InstallReceipt ---@param install_dir string function M.check_outdated_primary_package(receipt, install_dir) - local installed_version = M.get_installed_primary_package_version(receipt, install_dir):get_or_throw() - - local response = fetch_crate(receipt.primary_source.package) - if installed_version ~= response.crate.max_stable_version then - return Result.success { - name = receipt.primary_source.package, - current_version = installed_version, - latest_version = response.crate.max_stable_version, - } - else - return Result.failure "Primary package is not outdated." - end + return M.get_installed_primary_package_version(receipt, install_dir):map_catching(function(installed_version) + ---@type CrateResponse + local crate_response = client.fetch_crate(receipt.primary_source.package):get_or_throw() + if installed_version ~= crate_response.crate.max_stable_version then + return { + name = receipt.primary_source.package, + current_version = installed_version, + latest_version = crate_response.crate.max_stable_version, + } + else + error "Primary package is not outdated." + end + end) end ---@async diff --git a/lua/nvim-lsp-installer/core/managers/gem/init.lua b/lua/nvim-lsp-installer/core/managers/gem/init.lua index f40cb736..4191d587 100644 --- a/lua/nvim-lsp-installer/core/managers/gem/init.lua +++ b/lua/nvim-lsp-installer/core/managers/gem/init.lua @@ -75,10 +75,10 @@ function M.parse_outdated_gem(outdated_gem) return outdated_package end ----Parses the stdout of the `gem list` command into a Record<package_name, version> +---Parses the stdout of the `gem list` command into a table<package_name, version> ---@param output string function M.parse_gem_list_output(output) - ---@type Record<string, string> + ---@type table<string, string> local gem_versions = {} for _, line in ipairs(vim.split(output, "\n")) do local gem_package, version = line:match "^(%S+) %((%S+)%)$" diff --git a/lua/nvim-lsp-installer/core/managers/github/client.lua b/lua/nvim-lsp-installer/core/managers/github/client.lua new file mode 100644 index 00000000..a8766748 --- /dev/null +++ b/lua/nvim-lsp-installer/core/managers/github/client.lua @@ -0,0 +1,88 @@ +local Data = require "nvim-lsp-installer.data" +local log = require "nvim-lsp-installer.log" +local fetch = require "nvim-lsp-installer.core.fetch" +local spawn = require "nvim-lsp-installer.core.spawn" + +local list_find_first = Data.list_find_first + +local M = {} + +---@alias GitHubRelease {tag_name:string, prerelease: boolean, draft: boolean} +---@alias GitHubTag {name: string} + +---@async +---@param repo string The GitHub repo ("username/repo"). +function M.fetch_releases(repo) + log.fmt_trace("Fetching GitHub releases for repo=%s", repo) + local path = ("repos/%s/releases"):format(repo) + return spawn.gh({ "api", path }) + :map(function(result) + return result.stdout + end) + :recover_catching(function() + return fetch(("https://api.github.com/%s"):format(path)):get_or_throw() + end) + :map_catching(vim.json.decode) +end + +---@alias FetchLatestGithubReleaseOpts {tag_name_pattern:string} + +---@async +---@param repo string The GitHub repo ("username/repo"). +---@param opts FetchLatestGithubReleaseOpts|nil +---@return Result @of GitHubRelease +function M.fetch_latest_release(repo, opts) + opts = opts or {} + return M.fetch_releases(repo):map_catching( + ---@param releases GitHubRelease[] + function(releases) + ---@type GitHubRelease|nil + local latest_release = list_find_first( + releases, + ---@param release GitHubRelease + 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) + end + return is_stable_release + end + ) + + if not latest_release then + log.fmt_info("Failed to find latest release. repo=%s, opts=%s", repo, opts) + error "Failed to find latest release." + end + + log.fmt_debug("Resolved latest version repo=%s, tag_name=%s", repo, latest_release.tag_name) + return latest_release + end + ) +end + +---@async +---@param repo string The GitHub repo ("username/repo"). +function M.fetch_tags(repo) + local path = ("repos/%s/tags"):format(repo) + return spawn.gh({ "api", path }) + :map(function(result) + return result.stdout + end) + :recover_catching(function() + return fetch(("https://api.github.com/%s"):format(path)):get_or_throw() + end) + :map_catching(vim.json.decode) +end + +---@async +---@param repo string The GitHub repo ("username/repo"). +function M.fetch_latest_tag(repo) + return M.fetch_tags(repo):map_catching(function(tags) + if vim.tbl_count(tags) == 0 then + error "No tags found." + end + return tags[1] + end) +end + +return M diff --git a/lua/nvim-lsp-installer/core/managers/npm/init.lua b/lua/nvim-lsp-installer/core/managers/npm/init.lua index a4631e42..94d8b2ee 100644 --- a/lua/nvim-lsp-installer/core/managers/npm/init.lua +++ b/lua/nvim-lsp-installer/core/managers/npm/init.lua @@ -69,7 +69,7 @@ end ---@param exec_args string[] @The arguments to pass to npm exec. function M.exec(exec_args) local ctx = installer.context() - ctx.spawn.npm { "exec", "--yes", exec_args } + ctx.spawn.npm { "exec", "--yes", "--", exec_args } end ---@async diff --git a/lua/nvim-lsp-installer/core/managers/powershell/init.lua b/lua/nvim-lsp-installer/core/managers/powershell/init.lua new file mode 100644 index 00000000..a246e24c --- /dev/null +++ b/lua/nvim-lsp-installer/core/managers/powershell/init.lua @@ -0,0 +1,46 @@ +local spawn = require "nvim-lsp-installer.core.spawn" +local process = require "nvim-lsp-installer.process" + +local M = {} + +local PWSHOPT = { + progress_preference = [[ $ProgressPreference = 'SilentlyContinue'; ]], -- https://stackoverflow.com/a/63301751 + security_protocol = [[ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; ]], +} + +---@param script string +---@param opts JobSpawnOpts +---@param custom_spawn JobSpawn +function M.script(script, opts, custom_spawn) + opts = opts or {} + ---@type JobSpawn + local spawner = custom_spawn or spawn + return spawner.powershell(vim.tbl_extend("keep", { + "-NoProfile", + on_spawn = function(_, stdio) + local stdin = stdio[1] + stdin:write(PWSHOPT.progress_preference) + stdin:write(PWSHOPT.security_protocol) + stdin:write(script) + stdin:close() + end, + env = process.graft_env(opts.env or {}, { "PSMODULEPATH" }), + }, opts)) +end + +---@param command string +---@param opts JobSpawnOpts +---@param custom_spawn JobSpawn +function M.command(command, opts, custom_spawn) + opts = opts or {} + ---@type JobSpawn + local spawner = custom_spawn or spawn + return spawner.powershell(vim.tbl_extend("keep", { + "-NoProfile", + "-Command", + PWSHOPT.progress_preference .. PWSHOPT.security_protocol .. command, + env = process.graft_env(opts.env or {}, { "PSMODULEPATH" }), + }, opts)) +end + +return M diff --git a/lua/nvim-lsp-installer/core/managers/std/init.lua b/lua/nvim-lsp-installer/core/managers/std/init.lua new file mode 100644 index 00000000..49a7f53d --- /dev/null +++ b/lua/nvim-lsp-installer/core/managers/std/init.lua @@ -0,0 +1,44 @@ +local a = require "nvim-lsp-installer.core.async" +local installer = require "nvim-lsp-installer.core.installer" + +local M = {} + +local function with_system_executable_receipt(executable) + return function() + local ctx = installer.context() + ctx.receipt:with_primary_source(ctx.receipt.system(executable)) + end +end + +---@async +---@param executable string +---@param opts {help_url:string|nil} +function M.system_executable(executable, opts) + return function() + M.ensure_executable(executable, opts).with_receipt() + end +end + +---@async +---@param executable string +---@param opts {help_url:string|nil} +function M.ensure_executable(executable, opts) + local ctx = installer.context() + opts = opts or {} + if vim.in_fast_event() then + a.scheduler() + end + if vim.fn.executable(executable) ~= 1 then + ctx.stdio_sink.stderr(("%s was not found in path.\n"):format(executable)) + if opts.help_url then + ctx.stdio_sink.stderr(("See %s for installation instructions.\n"):format(opts.help_url)) + end + error("Installation failed: system executable was not found.", 0) + end + + return { + with_receipt = with_system_executable_receipt(executable), + } +end + +return M |
