mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
Merge branch 'esp8266-native-ninja-emission' into esp8266-arduino-toolchain
This commit is contained in:
@@ -35,6 +35,7 @@ from esphome.platformio.library import (
|
||||
IncompatiblePlatform,
|
||||
InvalidLibrary,
|
||||
LibraryBackend,
|
||||
_node_key,
|
||||
check_library_data,
|
||||
collect_filtered_files,
|
||||
convert_libraries,
|
||||
@@ -71,7 +72,11 @@ class ArduinoLibrary:
|
||||
|
||||
def _library_info(name: str, read_path: Path, data: dict) -> ArduinoLibrary:
|
||||
"""Resolve one library's sources, include dirs, and flags (PIO semantics)."""
|
||||
build = data.get("build", {})
|
||||
build = data.get("build", {}) if isinstance(data, dict) else None
|
||||
if not isinstance(build, dict):
|
||||
# A bare json.load imposes no shape; name the library instead of an
|
||||
# AttributeError deep in a traceback
|
||||
raise EsphomeError(f"Library {name} has a malformed manifest")
|
||||
|
||||
# PIO's source-dir resolution: manifest srcDir, else src/Src, else the root
|
||||
if "srcDir" in build:
|
||||
@@ -177,6 +182,15 @@ def _bundled_library(framework_path: Path, name: str) -> ArduinoLibrary:
|
||||
else:
|
||||
manifest = lib_dir / "library.properties"
|
||||
data = parse_library_properties(manifest) if manifest.is_file() else {}
|
||||
if isinstance(data, dict) and data.get("dependencies"):
|
||||
# The dependency walk never runs for bundled libraries (a no-op for
|
||||
# the ESP8266 core, whose bundled manifests declare none); on a core
|
||||
# where one does, the skip must be visible before link errors
|
||||
_LOGGER.warning(
|
||||
"Bundled library %s declares dependencies, which are not "
|
||||
"resolved automatically; add them with add_library() if needed",
|
||||
name,
|
||||
)
|
||||
return _library_info(name, lib_dir, data)
|
||||
|
||||
|
||||
@@ -309,8 +323,15 @@ def resolve_libraries(
|
||||
# A requested library the converter dropped would otherwise
|
||||
# surface only as link errors far from the cause; name the
|
||||
# requests that went missing, not just the survivors
|
||||
resolved_names = {c.name for c in resolved}
|
||||
dropped = [str(lib) for lib in external if lib.name not in resolved_names]
|
||||
# ConvertedLibrary.name is canonical (bare "pngle" resolves to
|
||||
# "bitbank2__pngle"); diff the request-side node keys instead
|
||||
resolved_keys = {c.node_key or c.name for c in resolved}
|
||||
dropped = [
|
||||
str(lib)
|
||||
for lib in external
|
||||
if _node_key(lib.name, lib.version, lib.repository)[0]
|
||||
not in resolved_keys
|
||||
]
|
||||
_LOGGER.warning(
|
||||
"%d of %d requested libraries were not resolved (missing: %s)",
|
||||
len(external) - len(resolved),
|
||||
|
||||
@@ -229,6 +229,10 @@ class ConvertedLibrary:
|
||||
self.name = name
|
||||
self.version = version
|
||||
self.source = source
|
||||
# The request-side _node_key this component resolved from; the
|
||||
# canonical name can differ (bare "pngle" -> "bitbank2__pngle"), so
|
||||
# callers diff requests against this, not against name
|
||||
self.node_key: str | None = None
|
||||
self.data = {}
|
||||
self.dependencies: list[ConvertedLibrary] = []
|
||||
self._path: Path | None = None
|
||||
@@ -891,6 +895,7 @@ def convert_libraries(
|
||||
component = ConvertedLibrary(
|
||||
_owner_pkgname_to_name(owner, name), version, URLSource(url)
|
||||
)
|
||||
component.node_key = key
|
||||
component.download(salt=salt, namespace=backend.cache_key)
|
||||
|
||||
source_dir = component.source_dir
|
||||
|
||||
@@ -552,3 +552,57 @@ def test_bundled_dependency_platform_rejection_is_debug(
|
||||
cache_key="arduino8266",
|
||||
)
|
||||
assert "Skipping bundled dependency Wire" not in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.parametrize("data", [{"build": "src"}, [], "nope"])
|
||||
def test_library_info_malformed_manifest_is_named(tmp_path: Path, data: object) -> None:
|
||||
"""A malformed manifest names the library, never an AttributeError."""
|
||||
read_path = tmp_path / "lib"
|
||||
read_path.mkdir()
|
||||
with pytest.raises(EsphomeError, match="Library x has a malformed manifest"):
|
||||
component._library_info("x", read_path, data)
|
||||
|
||||
|
||||
def test_drop_warning_maps_requests_by_node_key(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""A bare request resolving to a canonical name is not falsely reported
|
||||
missing; the genuinely dropped request is the one named."""
|
||||
framework = _make_framework(tmp_path)
|
||||
_add_library("pngle", None)
|
||||
_add_library("gone/missing", "1.0.0")
|
||||
lib_dir = tmp_path / "converted" / "pngle"
|
||||
(lib_dir / "src").mkdir(parents=True)
|
||||
resolved = _converted("bitbank2__pngle", lib_dir, {"build": {}})
|
||||
resolved.node_key = "pngle"
|
||||
with patch.object(component, "convert_libraries", return_value=[resolved]):
|
||||
component.resolve_libraries(
|
||||
framework,
|
||||
pio_platform="espressif8266",
|
||||
board_mcu="esp8266",
|
||||
cache_key="arduino8266",
|
||||
)
|
||||
assert "1 of 2 requested libraries were not resolved" in caplog.text
|
||||
assert "missing" in caplog.text
|
||||
assert "pngle" not in caplog.text.split("missing:")[-1]
|
||||
assert "gone/missing" in caplog.text.split("missing:")[-1]
|
||||
|
||||
|
||||
def test_bundled_library_with_declared_dependencies_warns(
|
||||
tmp_path: Path, caplog: pytest.LogCaptureFixture
|
||||
) -> None:
|
||||
"""A bundled manifest that declares dependencies is visible, not
|
||||
silently skipped (a no-op for the ESP8266 core, not for every core)."""
|
||||
framework = _make_framework(tmp_path)
|
||||
wire = framework / "libraries" / "Wire"
|
||||
(wire / "library.json").write_text(
|
||||
'{"name": "Wire", "dependencies": [{"name": "SPI"}]}'
|
||||
)
|
||||
_add_library("Wire", None)
|
||||
component.resolve_libraries(
|
||||
framework,
|
||||
pio_platform="espressif8266",
|
||||
board_mcu="esp8266",
|
||||
cache_key="arduino8266",
|
||||
)
|
||||
assert "Bundled library Wire declares dependencies" in caplog.text
|
||||
|
||||
Reference in New Issue
Block a user