Reject unsupported toolchains on the PlatformIO-only platforms and warn on empty srcFilter matches

This commit is contained in:
J. Nick Koston
2026-08-20 06:52:54 -05:00
parent 42e9448a50
commit dad9a1175b
7 changed files with 69 additions and 0 deletions
+7
View File
@@ -123,6 +123,13 @@ def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
for f in collect_filtered_files(read_path / src_dir, src_filter)
if (path := Path(f)).suffix in SRC_FILE_EXTENSIONS
)
if not lib.sources and ("srcFilter" in build or "srcDir" in build):
# A default probe finding nothing is a header-only library; a
# declared filter matching nothing is a manifest/tree problem.
_LOGGER.warning(
"Library %s declares srcFilter/srcDir but no source files matched",
name,
)
return lib
+1
View File
@@ -37,6 +37,7 @@ CONFIG_SCHEMA = cv.All(
}
),
set_core_data,
cv.require_platformio_toolchain("host"),
)
+1
View File
@@ -315,6 +315,7 @@ BASE_SCHEMA = cv.Schema(
BASE_SCHEMA.add_extra(_detect_variant)
BASE_SCHEMA.add_extra(_update_core_data)
BASE_SCHEMA.add_extra(cv.require_platformio_toolchain("LibreTiny"))
def _configure_lwip(config: dict) -> None:
+1
View File
@@ -312,6 +312,7 @@ CONFIG_SCHEMA = cv.All(
cv.has_at_least_one_key(CONF_BOARD, CONF_VARIANT),
_detect_variant,
set_core_data,
cv.require_platformio_toolchain("RP2"),
)
+22
View File
@@ -2532,6 +2532,28 @@ def platformio_version_constraint(value):
return constraints
def require_platformio_toolchain(platform_name: str):
"""Reject a CLI-selected toolchain other than PlatformIO.
For platforms with only the PlatformIO backend; without this a
``--toolchain`` they cannot serve would silently build with PlatformIO.
"""
def validator(config):
from esphome.const import Toolchain
if CORE.toolchain is None:
CORE.toolchain = Toolchain.PLATFORMIO
if CORE.toolchain != Toolchain.PLATFORMIO:
raise Invalid(
f"Unsupported toolchain '{CORE.toolchain.value}' for "
f"{platform_name}. The only supported toolchain is 'platformio'."
)
return config
return validator
def require_framework_version(
*,
max_version=False,
@@ -96,6 +96,27 @@ def test_library_info_missing_link_dir_warns(
assert lib.link_dirs == [(read_path / "missing_blobs").resolve()]
def test_library_info_declared_filter_matches_nothing_warns(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
data = {"build": {"srcFilter": ["+<nothing/*>"]}}
lib = component._library_info("x", read_path, data)
assert not lib.sources
assert "declares srcFilter/srcDir but no source files matched" in caplog.text
def test_library_info_header_only_does_not_warn(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
read_path = tmp_path / "lib"
(read_path / "src").mkdir(parents=True)
lib = component._library_info("x", read_path, {})
assert not lib.sources
assert "no source files matched" not in caplog.text
def test_library_info_no_src_dir(tmp_path: Path) -> None:
read_path = tmp_path / "empty"
read_path.mkdir()
@@ -3165,3 +3165,19 @@ def test_file__remapped_path_is_directory_raises(setup_core: Path) -> None:
with pytest.raises(Invalid, match="is not a file"):
cv.file_("/original/config/headers")
def test_require_platformio_toolchain() -> None:
"""Platforms with only the PlatformIO backend reject other toolchains."""
from esphome.const import Toolchain
from esphome.core import CORE
validator = cv.require_platformio_toolchain("RP2")
CORE.toolchain = None
config: dict = {}
assert validator(config) is config
assert CORE.toolchain == Toolchain.PLATFORMIO
CORE.toolchain = Toolchain.ARDUINO
with pytest.raises(Invalid, match="Unsupported toolchain 'arduino' for RP2"):
validator(config)