aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lua/mason-core/installer/managers/pypi.lua43
-rw-r--r--tests/mason-core/installer/managers/pypi_spec.lua13
-rw-r--r--tests/mason-core/installer/registry/link_spec.lua2
3 files changed, 40 insertions, 18 deletions
diff --git a/lua/mason-core/installer/managers/pypi.lua b/lua/mason-core/installer/managers/pypi.lua
index e9c0c432..0f3de1fb 100644
--- a/lua/mason-core/installer/managers/pypi.lua
+++ b/lua/mason-core/installer/managers/pypi.lua
@@ -20,17 +20,32 @@ local function create_venv(py_executables)
end, py_executables)):ok_or "Failed to create python3 virtual environment."
end
+---@param ctx InstallContext
+---@param executable string
+local function find_venv_executable(ctx, executable)
+ local candidates = _.filter(_.identity, {
+ platform.is.unix and path.concat { VENV_DIR, "bin", executable },
+ -- MSYS2
+ platform.is.win and path.concat { VENV_DIR, "bin", ("%s.exe"):format(executable) },
+ -- Stock Windows
+ platform.is.win and path.concat { VENV_DIR, "Scripts", ("%s.exe"):format(executable) },
+ })
+
+ for _, candidate in ipairs(candidates) do
+ if ctx.fs:file_exists(candidate) then
+ return Result.success(candidate)
+ end
+ end
+ return Result.failure(("Failed to find executable %q in Python virtual environment."):format(executable))
+end
+
---@async
---@param args SpawnArgs
local function venv_python(args)
local ctx = installer.context()
- local python_path = path.concat {
- ctx.cwd:get(),
- VENV_DIR,
- platform.is.win and "Scripts" or "bin",
- platform.is.win and "python.exe" or "python",
- }
- return ctx.spawn[python_path](args)
+ return find_venv_executable(ctx, "python"):and_then(function(python_path)
+ return ctx.spawn[path.concat { ctx.cwd:get(), python_path }](args)
+ end)
end
---@async
@@ -93,16 +108,10 @@ function M.install(pkg, version, opts)
}, opts.install_extra_args)
end
----@param exec string
-function M.bin_path(exec)
- return Result.pcall(platform.when, {
- unix = function()
- return path.concat { "venv", "bin", exec }
- end,
- win = function()
- return path.concat { "venv", "Scripts", ("%s.exe"):format(exec) }
- end,
- })
+---@param executable string
+function M.bin_path(executable)
+ local ctx = installer.context()
+ return find_venv_executable(ctx, executable)
end
return M
diff --git a/tests/mason-core/installer/managers/pypi_spec.lua b/tests/mason-core/installer/managers/pypi_spec.lua
index cb4bc2b3..353606aa 100644
--- a/tests/mason-core/installer/managers/pypi_spec.lua
+++ b/tests/mason-core/installer/managers/pypi_spec.lua
@@ -1,4 +1,5 @@
local installer = require "mason-core.installer"
+local match = require "luassert.match"
local path = require "mason-core.path"
local pypi = require "mason-core.installer.managers.pypi"
local spy = require "luassert.spy"
@@ -35,6 +36,9 @@ describe("pypi manager", function()
it("should init venv and upgrade pip", function()
local ctx = create_dummy_context()
stub(ctx, "promote_cwd")
+ stub(ctx.fs, "file_exists")
+ ctx.fs.file_exists.on_call_with(match.ref(ctx.fs), "venv/bin/python").returns(true)
+
installer.exec_in_context(ctx, function()
pypi.init { upgrade_pip = true, install_extra_args = { "--proxy", "http://localhost" } }
end)
@@ -60,6 +64,8 @@ describe("pypi manager", function()
it("should install", function()
local ctx = create_dummy_context()
+ stub(ctx.fs, "file_exists")
+ ctx.fs.file_exists.on_call_with(match.ref(ctx.fs), "venv/bin/python").returns(true)
installer.exec_in_context(ctx, function()
pypi.install("pypi-package", "1.0.0")
end)
@@ -81,6 +87,8 @@ describe("pypi manager", function()
it("should write output", function()
local ctx = create_dummy_context()
+ stub(ctx.fs, "file_exists")
+ ctx.fs.file_exists.on_call_with(match.ref(ctx.fs), "venv/bin/python").returns(true)
spy.on(ctx.stdio_sink, "stdout")
installer.exec_in_context(ctx, function()
@@ -92,6 +100,9 @@ describe("pypi manager", function()
it("should install extra specifier", function()
local ctx = create_dummy_context()
+ stub(ctx.fs, "file_exists")
+ ctx.fs.file_exists.on_call_with(match.ref(ctx.fs), "venv/bin/python").returns(true)
+
installer.exec_in_context(ctx, function()
pypi.install("pypi-package", "1.0.0", {
extra = "lsp",
@@ -115,6 +126,8 @@ describe("pypi manager", function()
it("should install extra packages", function()
local ctx = create_dummy_context()
+ stub(ctx.fs, "file_exists")
+ ctx.fs.file_exists.on_call_with(match.ref(ctx.fs), "venv/bin/python").returns(true)
installer.exec_in_context(ctx, function()
pypi.install("pypi-package", "1.0.0", {
extra_packages = { "extra-package" },
diff --git a/tests/mason-core/installer/registry/link_spec.lua b/tests/mason-core/installer/registry/link_spec.lua
index 662e1323..eb6af1cc 100644
--- a/tests/mason-core/installer/registry/link_spec.lua
+++ b/tests/mason-core/installer/registry/link_spec.lua
@@ -119,7 +119,7 @@ describe("registry linker", function()
["npm:executable"] = "node_modules/.bin/executable",
["nuget:executable"] = "executable",
["opam:executable"] = "bin/executable",
- ["pypi:executable"] = "venv/bin/executable",
+ -- ["pypi:executable"] = "venv/bin/executable",
}
for bin, path in pairs(matrix) do