aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lua/mason-core/spawn.lua25
-rw-r--r--tests/mason-core/spawn_spec.lua33
2 files changed, 46 insertions, 12 deletions
diff --git a/lua/mason-core/spawn.lua b/lua/mason-core/spawn.lua
index d604dfe2..0da67569 100644
--- a/lua/mason-core/spawn.lua
+++ b/lua/mason-core/spawn.lua
@@ -14,17 +14,30 @@ local spawn = {
}
---@param cmd string
-local function exepath(cmd)
+---@param path? string
+local function exepath(cmd, path)
+ local function get_exepath(cmd)
+ if path then
+ local old_path = vim.env.PATH
+ vim.env.PATH = path
+ local expanded_cmd = vim.fn.exepath(cmd)
+ vim.env.PATH = old_path
+ return expanded_cmd
+ else
+ return vim.fn.exepath(cmd)
+ end
+ end
+
if platform.is.win then
-- On Windows, exepath() assumes the system is capable of executing "Unix-like" executables if the shell is a Unix
-- shell. We temporarily override it to a Windows shell ("powershell") to avoid that behaviour.
local old_shell = vim.o.shell
vim.o.shell = "powershell"
- local expanded_cmd = vim.fn.exepath(cmd)
+ local expanded_cmd = get_exepath(cmd)
vim.o.shell = old_shell
return expanded_cmd
else
- return vim.fn.exepath(cmd)
+ return get_exepath(cmd)
end
end
@@ -41,7 +54,7 @@ local function Failure(err, cmd)
}))
end
-local has_path = _.any(_.starts_with "PATH=")
+local get_path_from_env_list = _.compose(_.strip_prefix "PATH=", _.find_first(_.starts_with "PATH="))
---@class SpawnArgs
---@field with_paths string[]? Paths to add to the PATH environment variable.
@@ -80,9 +93,9 @@ setmetatable(spawn, {
-- Find the executable path via vim.fn.exepath on Windows because libuv fails to resolve certain executables
-- in PATH.
- if platform.is.win and (spawn_args.env and has_path(spawn_args.env)) == nil then
+ if platform.is.win then
a.scheduler()
- local expanded_cmd = exepath(canonical_cmd)
+ local expanded_cmd = exepath(canonical_cmd, spawn_args.env and get_path_from_env_list(spawn_args.env))
if expanded_cmd ~= "" then
cmd = expanded_cmd
end
diff --git a/tests/mason-core/spawn_spec.lua b/tests/mason-core/spawn_spec.lua
index db8f9575..b224bfc3 100644
--- a/tests/mason-core/spawn_spec.lua
+++ b/tests/mason-core/spawn_spec.lua
@@ -148,6 +148,8 @@ describe("async spawn", function()
end)
describe("Windows", function()
+ -- Note: Tests assume they're executed in a Unix environment (e.g. uses Unix path separators in tests).
+
before_each(function()
platform.is.win = true
end)
@@ -173,24 +175,43 @@ describe("async spawn", function()
)
end)
- it("should not use exepath if env.PATH is set", function()
+ it("should use exepath if env.PATH is set", function()
stub(process, "spawn", function(_, _, callback)
callback(true, 0, 0)
end)
- local result = a.run_blocking(spawn.bash, { "arg1", env = { PATH = "C:\\some\\path" } })
+ local result = a.run_blocking(spawn.bash, { "arg1", env = { PATH = "C:\\some\\path:" .. vim.env.PATH } })
assert.is_true(result:is_success())
assert.spy(process.spawn).was_called(1)
assert.spy(process.spawn).was_called_with(
- "bash",
+ vim.fn.exepath "bash",
+ match.tbl_containing {
+ args = match.same { "arg1" },
+ env = match.is_table(),
+ },
+ match.is_function()
+ )
+ end)
+
+ it("should use exepath if env_raw.PATH is set", function()
+ stub(process, "spawn", function(_, _, callback)
+ callback(true, 0, 0)
+ end)
+
+ local result = a.run_blocking(spawn.bash, { "arg1", env_raw = { "PATH=C:\\some\\path:" .. vim.env.PATH } })
+ assert.is_true(result:is_success())
+ assert.spy(process.spawn).was_called(1)
+ assert.spy(process.spawn).was_called_with(
+ vim.fn.exepath "bash",
match.tbl_containing {
args = match.same { "arg1" },
+ env = match.is_table(),
},
match.is_function()
)
end)
- it("should not use exepath if env_raw.PATH is set", function()
+ it("should default to provided cmd if exepath returns nothing", function()
stub(process, "spawn", function(_, _, callback)
callback(true, 0, 0)
end)
@@ -207,7 +228,7 @@ describe("async spawn", function()
)
end)
- it("should not use exepath if with_paths is provided", function()
+ it("should use exepath if with_paths is provided", function()
stub(process, "spawn", function(_, _, callback)
callback(true, 0, 0)
end)
@@ -216,7 +237,7 @@ describe("async spawn", function()
assert.is_true(result:is_success())
assert.spy(process.spawn).was_called(1)
assert.spy(process.spawn).was_called_with(
- "bash",
+ vim.fn.exepath "bash",
match.tbl_containing {
args = match.same { "arg1" },
},