aboutsummaryrefslogtreecommitdiffstats
path: root/lua
diff options
context:
space:
mode:
authorWilliam Boman <william@redwill.se>2022-05-17 23:15:36 +0200
committerGitHub <noreply@github.com>2022-05-17 23:15:36 +0200
commit0e90f04651388df2477400b4b63e5443fcda43af (patch)
tree82626e8193cdbf9406176fa6a7ff85f565698eb7 /lua
parentfix(omnisharp): remove invalid equality check (diff)
downloadmason-0e90f04651388df2477400b4b63e5443fcda43af.tar
mason-0e90f04651388df2477400b4b63e5443fcda43af.tar.gz
mason-0e90f04651388df2477400b4b63e5443fcda43af.tar.bz2
mason-0e90f04651388df2477400b4b63e5443fcda43af.tar.lz
mason-0e90f04651388df2477400b4b63e5443fcda43af.tar.xz
mason-0e90f04651388df2477400b4b63e5443fcda43af.tar.zst
mason-0e90f04651388df2477400b4b63e5443fcda43af.zip
fix(spawn): avoid spawning commands that aren't on PATH (#706)
This is primarily done to avoid cluttering the log file with a bunch of ERROR entries. Also avoids unnecessary roundtrips to uv_spawn, I guess.
Diffstat (limited to 'lua')
-rw-r--r--lua/nvim-lsp-installer/core/managers/pip3/init.lua3
-rw-r--r--lua/nvim-lsp-installer/core/spawn.lua34
2 files changed, 32 insertions, 5 deletions
diff --git a/lua/nvim-lsp-installer/core/managers/pip3/init.lua b/lua/nvim-lsp-installer/core/managers/pip3/init.lua
index b6a82633..0c442243 100644
--- a/lua/nvim-lsp-installer/core/managers/pip3/init.lua
+++ b/lua/nvim-lsp-installer/core/managers/pip3/init.lua
@@ -62,6 +62,7 @@ function M.install(packages)
settings.current.pip.install_args,
pkgs,
env = M.env(ctx.cwd:get()), -- use venv env
+ check_executable = false,
}
end)
:or_else_throw "Unable to create python3 venv environment."
@@ -95,6 +96,7 @@ function M.check_outdated_primary_package(receipt, install_dir)
"--format=json",
cwd = install_dir,
env = M.env(install_dir), -- use venv
+ check_executable = false,
}):map_catching(function(result)
---@alias PipOutdatedPackage {name: string, version: string, latest_version: string}
---@type PipOutdatedPackage[]
@@ -131,6 +133,7 @@ function M.get_installed_primary_package_version(receipt, install_dir)
"--format=json",
cwd = install_dir,
env = M.env(install_dir), -- use venv env
+ check_executable = false,
}):map_catching(function(result)
local pip_packages = vim.json.decode(result.stdout)
local normalized_pip_package = M.normalize_package(receipt.primary_source.package)
diff --git a/lua/nvim-lsp-installer/core/spawn.lua b/lua/nvim-lsp-installer/core/spawn.lua
index 83da908e..a1c55c0f 100644
--- a/lua/nvim-lsp-installer/core/spawn.lua
+++ b/lua/nvim-lsp-installer/core/spawn.lua
@@ -2,8 +2,9 @@ local a = require "nvim-lsp-installer.core.async"
local Result = require "nvim-lsp-installer.core.result"
local process = require "nvim-lsp-installer.core.process"
local platform = require "nvim-lsp-installer.core.platform"
+local functional = require "nvim-lsp-installer.core.functional"
----@alias JobSpawn Record<string, async fun(opts: JobSpawnOpts): Result>
+---@alias JobSpawn table<string, async fun(opts: JobSpawnOpts): Result>
---@type JobSpawn
local spawn = {
_aliases = {
@@ -37,14 +38,30 @@ local function parse_args(args, dest)
return dest
end
+local is_executable = functional.memoize(function(cmd)
+ if vim.in_fast_event() then
+ a.scheduler()
+ end
+ return vim.fn.executable(cmd) == 1
+end, functional.identity)
+
+---@class SpawnArgs
+---@field with_paths string[] @Optional. Paths to add to the PATH environment variable.
+---@field env table<string, string> @Optional. Example { SOME_ENV = "value", SOME_OTHER_ENV = "some_value" }
+---@field env_raw string[] @Optional. Example: { "SOME_ENV=value", "SOME_OTHER_ENV=some_value" }
+---@field stdio_sink StdioSink @Optional. If provided, will be used to write to stdout and stderr.
+---@field cwd string @Optional
+---@field on_spawn fun(handle: luv_handle, stdio: luv_pipe[]) @Optional. Will be called when the process successfully spawns.
+---@field check_executable boolean @Optional. Whether to check if the provided command is executable (defaults to true).
+
setmetatable(spawn, {
- __index = function(self, k)
- ---@param args string|nil|string[][]
+ ---@param normalized_cmd string
+ __index = function(self, normalized_cmd)
+ ---@param args SpawnArgs
return function(args)
local cmd_args = {}
parse_args(args, cmd_args)
- ---@type table<string, string>
local env = args.env
if args.with_paths then
@@ -66,7 +83,14 @@ setmetatable(spawn, {
spawn_args.stdio_sink = stdio.sink
end
- local cmd = self._aliases[k] or k
+ local cmd = self._aliases[normalized_cmd] or normalized_cmd
+
+ if args.check_executable ~= false and not is_executable(cmd) then
+ return Failure({
+ stderr = ("%s is not executable"):format(cmd),
+ }, cmd)
+ end
+
local _, exit_code = a.wait(function(resolve)
local handle, stdio = process.spawn(cmd, spawn_args, resolve)
if args.on_spawn and handle and stdio then