mirror of
https://github.com/esphome/esphome.git
synced 2026-08-27 16:29:29 +00:00
Merge branch 'esp8266-native-library-backend' into esp8266-native-build-spec
This commit is contained in:
@@ -324,14 +324,16 @@ def _external_short_name(name: str) -> str:
|
||||
|
||||
|
||||
def _check_unfulfilled_provides(
|
||||
provided_requests: list[str], satisfied: set[str]
|
||||
provided_requests: list[str], satisfied: set[str], still_requested: set[str]
|
||||
) -> None:
|
||||
"""Reconcile the provides() promise: every dependency the walk skipped
|
||||
on the backend's word must have been added from the framework tree (or
|
||||
knowingly satisfied by a converted/external library). An unfulfilled
|
||||
promise can only surface as undefined symbols at link, so it fails
|
||||
here by name like the other can-never-link checks in this module."""
|
||||
if missing := sorted(set(provided_requests) - satisfied):
|
||||
here by name like the other can-never-link checks in this module. The
|
||||
walk records across re-resolutions, so a name no final manifest still
|
||||
requests is stale state, never a failure."""
|
||||
if missing := sorted((set(provided_requests) & still_requested) - satisfied):
|
||||
raise EsphomeError(
|
||||
"provides() skipped these dependencies but nothing added them: "
|
||||
f"{', '.join(missing)}; the build is missing libraries"
|
||||
@@ -391,6 +393,9 @@ def resolve_libraries(
|
||||
# Bundled candidates skipped on purpose (platform filter); the
|
||||
# provides() reconciliation must count them as satisfied
|
||||
knowingly_skipped: set[str] = set()
|
||||
# Dependency names of the manifests actually emitted; a walk recording
|
||||
# for a since-re-resolved manifest must not fail the reconciliation
|
||||
final_dep_names: set[str] = set()
|
||||
# Ordered set of bundled dependency names to add once conversion is done
|
||||
pending_bundled: dict[str, None] = {}
|
||||
# Deps matching a separately-requested external are already in the build
|
||||
@@ -407,6 +412,8 @@ def resolve_libraries(
|
||||
component.data.get("dependencies"), component.name
|
||||
):
|
||||
name = dep.get("name")
|
||||
if isinstance(name, str):
|
||||
final_dep_names.add(name)
|
||||
if isinstance(name, str) and "/" in name:
|
||||
owner, _, pkg = name.partition("/")
|
||||
if _is_safe_library_name(owner) and _is_safe_library_name(pkg):
|
||||
@@ -527,6 +534,7 @@ def resolve_libraries(
|
||||
| converted_manifest_names
|
||||
| external_short_names
|
||||
| knowingly_skipped,
|
||||
final_dep_names,
|
||||
)
|
||||
|
||||
return bundled + converted
|
||||
|
||||
@@ -944,9 +944,11 @@ def _warn_unsatisfied_versionless(
|
||||
if dep_name in resolved_manifest_names:
|
||||
# Name-only evidence: any resolved component with this manifest
|
||||
# name counts, not just ones the requester can reach, so a
|
||||
# coincidental name collision must stay visible
|
||||
# coincidental name collision must stay visible where the user
|
||||
# could pin it; treeless backends cannot act on it
|
||||
warned.add(dep_name)
|
||||
_LOGGER.warning(
|
||||
log = _LOGGER.warning if backend.provides is not None else _LOGGER.debug
|
||||
log(
|
||||
"Version-less dependency %s of %s assumed satisfied by a "
|
||||
"resolved library's manifest name only",
|
||||
dep_name,
|
||||
|
||||
@@ -721,10 +721,15 @@ def test_unfulfilled_provides_promise_raises(tmp_path: Path) -> None:
|
||||
undefined symbols at link, so it fails here by name, deduplicated;
|
||||
satisfied ones pass silently."""
|
||||
with pytest.raises(EsphomeError, match="Wire") as err:
|
||||
component._check_unfulfilled_provides(["Wire", "Wire", "Hash"], {"Hash"})
|
||||
component._check_unfulfilled_provides(
|
||||
["Wire", "Wire", "Hash"], {"Hash"}, {"Wire", "Hash"}
|
||||
)
|
||||
assert str(err.value).count("Wire") == 1
|
||||
assert "Hash" not in str(err.value)
|
||||
component._check_unfulfilled_provides(["Hash"], {"Hash"})
|
||||
component._check_unfulfilled_provides(["Hash"], {"Hash"}, {"Hash"})
|
||||
# A recording for a since-re-resolved manifest is stale walk state,
|
||||
# never a failure: no final manifest still requests Wire
|
||||
component._check_unfulfilled_provides(["Wire"], set(), set())
|
||||
|
||||
|
||||
def test_extra_script_link_flags_reach_the_library(tmp_path: Path) -> None:
|
||||
|
||||
Reference in New Issue
Block a user