Raise the actionable ninja message when the package itself is missing

This commit is contained in:
J. Nick Koston
2026-08-20 06:17:10 -05:00
parent 3f9568eaf0
commit 4520f27d94
2 changed files with 17 additions and 1 deletions
+7 -1
View File
@@ -208,7 +208,13 @@ def _find_ninja() -> Path:
"""
if binary := shutil.which("ninja"):
return Path(binary)
import ninja
try:
import ninja
except ImportError as err:
raise EsphomeError(
"ninja not found on PATH or in the ninja package; reinstall the "
"esphome Python environment"
) from err
binary = Path(ninja.BIN_DIR) / ("ninja.exe" if os.name == "nt" else "ninja")
if not binary.is_file():
@@ -237,6 +237,16 @@ def test_find_ninja_falls_back_to_wheel(tmp_path: Path) -> None:
assert framework._find_ninja() == tmp_path / binary_name
def test_find_ninja_package_not_installed() -> None:
"""A missing ninja package raises the actionable message, not ImportError."""
with (
patch("shutil.which", return_value=None),
patch.dict(sys.modules, {"ninja": None}),
pytest.raises(EsphomeError, match="ninja not found"),
):
framework._find_ninja()
def test_find_ninja_missing_everywhere(tmp_path: Path) -> None:
wheel = MagicMock(BIN_DIR=str(tmp_path))
with (