Skip to content

Commit b356498

Browse files
committed
refactor: slightly more helpful error messages and early error if incomaptible py version
1 parent e0d3374 commit b356498

File tree

2 files changed

+68
-24
lines changed

2 files changed

+68
-24
lines changed

lua/mason-core/installer/managers/pypi.lua

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ local function pep440_check_version(version, specifiers)
3939
local ok, result = pcall(pep440.check_version, version, specifiers)
4040
if not ok then
4141
log.fmt_warn(
42-
"Failed to check version compatibility for version %s with specifiers %s: %s",
42+
"Failed to check PEP440 version compatibility for version %s with specifiers %s: %s",
4343
version,
4444
specifiers,
4545
result
@@ -91,12 +91,11 @@ local function create_venv(pkg)
9191
local target = resolve_python3(versioned_candidates) or stock_target
9292

9393
if not target then
94-
ctx.stdio_sink.stderr(
95-
("Unable to find python3 installation. Tried the following candidates: %s.\n"):format(
94+
return Result.failure(
95+
("Unable to find python3 installation in PATH. Tried the following candidates: %s."):format(
9696
_.join(", ", _.concat(stock_candidates, versioned_candidates))
9797
)
9898
)
99-
return Result.failure "Failed to find python3 installation."
10099
end
101100

102101
-- 3. If a versioned python3 installation was not found, warn the user if the stock python3 installation is outside
@@ -106,12 +105,22 @@ local function create_venv(pkg)
106105
and supported_python_versions ~= nil
107106
and not pep440_check_version(tostring(target.version), supported_python_versions)
108107
then
109-
ctx.stdio_sink.stderr(
110-
("Warning: The resolved Python version %s is not compatible with the required Python versions: %s.\n"):format(
111-
target.version,
112-
supported_python_versions
108+
if ctx.opts.force then
109+
ctx.stdio_sink.stderr(
110+
("Warning: The resolved python3 version %s is not compatible with the required Python versions: %s.\n"):format(
111+
target.version,
112+
supported_python_versions
113+
)
113114
)
114-
)
115+
else
116+
ctx.stdio_sink.stderr "Run with :MasonInstall --force to bypass this version validation.\n"
117+
return Result.failure(
118+
("Failed to find a python3 installation in PATH that meets the required versions (%s). Found version: %s."):format(
119+
supported_python_versions,
120+
target.version
121+
)
122+
)
123+
end
115124
end
116125

117126
log.fmt_debug("Found python3 installation version=%s, executable=%s", target.version, target.executable)

tests/mason-core/installer/managers/pypi_spec.lua

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,8 @@ describe("pypi manager", function()
9090
installer.exec_in_context(ctx, function()
9191
pypi.init {
9292
package = { name = "cmake-language-server", version = "0.1.10" },
93-
upgrade_pip = true,
94-
install_extra_args = { "--proxy", "http://localhost" },
93+
upgrade_pip = false,
94+
install_extra_args = {},
9595
}
9696
end)
9797

@@ -104,7 +104,7 @@ describe("pypi manager", function()
104104
}
105105
end)
106106

107-
it("should default to stock version if unable to find suitable versioned candidate during init", function()
107+
it("should error if unable to find a suitable python3 version", function()
108108
local ctx = create_dummy_context()
109109
spy.on(ctx.stdio_sink, "stderr")
110110
stub(ctx, "promote_cwd")
@@ -119,26 +119,61 @@ describe("pypi manager", function()
119119
stub(spawn, "python3", mockx.returns(Result.success()))
120120
spawn.python3.on_call_with({ "--version" }).returns(Result.success { stdout = "Python 3.5.0" })
121121

122-
installer.exec_in_context(ctx, function()
123-
pypi.init {
122+
local result = installer.exec_in_context(ctx, function()
123+
return pypi.init {
124124
package = { name = "cmake-language-server", version = "0.1.10" },
125-
upgrade_pip = true,
126-
install_extra_args = { "--proxy", "http://localhost" },
125+
upgrade_pip = false,
126+
install_extra_args = {},
127127
}
128128
end)
129129

130-
assert.spy(ctx.promote_cwd).was_called(1)
131-
assert.spy(ctx.spawn.python3).was_called(1)
132-
assert.spy(ctx.spawn.python3).was_called_with {
133-
"-m",
134-
"venv",
135-
"venv",
136-
}
130+
assert.same(
131+
Result.failure "Failed to find a python3 installation in PATH that meets the required versions (>=3.8).",
132+
result
133+
)
137134
assert
138135
.spy(ctx.stdio_sink.stderr)
139-
.was_called_with "Warning: The resolved Python version 3.5.0 is not compatible with the required Python versions: >=3.8.\n"
136+
.was_called_with "Run with :MasonInstall --force to bypass this version validation.\n"
140137
end)
141138

139+
it(
140+
"should default to stock version if unable to find suitable versioned candidate during init and when force=true",
141+
function()
142+
local ctx = create_dummy_context { force = true }
143+
spy.on(ctx.stdio_sink, "stderr")
144+
stub(ctx, "promote_cwd")
145+
stub(ctx.fs, "file_exists")
146+
stub(providers.pypi, "get_supported_python_versions", mockx.returns(Result.success ">=3.8"))
147+
stub(vim.fn, "executable")
148+
vim.fn.executable.on_call_with("python3.12").returns(0)
149+
vim.fn.executable.on_call_with("python3.11").returns(0)
150+
vim.fn.executable.on_call_with("python3.10").returns(0)
151+
vim.fn.executable.on_call_with("python3.9").returns(0)
152+
vim.fn.executable.on_call_with("python3.8").returns(0)
153+
stub(spawn, "python3", mockx.returns(Result.success()))
154+
spawn.python3.on_call_with({ "--version" }).returns(Result.success { stdout = "Python 3.5.0" })
155+
156+
installer.exec_in_context(ctx, function()
157+
pypi.init {
158+
package = { name = "cmake-language-server", version = "0.1.10" },
159+
upgrade_pip = true,
160+
install_extra_args = { "--proxy", "http://localhost" },
161+
}
162+
end)
163+
164+
assert.spy(ctx.promote_cwd).was_called(1)
165+
assert.spy(ctx.spawn.python3).was_called(1)
166+
assert.spy(ctx.spawn.python3).was_called_with {
167+
"-m",
168+
"venv",
169+
"venv",
170+
}
171+
assert
172+
.spy(ctx.stdio_sink.stderr)
173+
.was_called_with "Warning: The resolved python3 version 3.5.0 is not compatible with the required Python versions: >=3.8.\n"
174+
end
175+
)
176+
142177
it("should install", function()
143178
local ctx = create_dummy_context()
144179
stub(ctx.fs, "file_exists")

0 commit comments

Comments
 (0)