Merge branch 'esp8266-native-build-surgery' into esp8266-native-toolchain-plumbing

This commit is contained in:
J. Nick Koston
2026-08-23 15:52:33 -05:00
2 changed files with 38 additions and 9 deletions
+19 -7
View File
@@ -83,9 +83,12 @@ def print_summary(size_json: Path, partitions_csv: Path | None) -> None:
# Backstop for shapes the named guards below miss; warning so a
# regression here cannot go missing indefinitely
_LOGGER.warning(
"Skipping size summary for %s: %s: %s", size_json, type(e).__name__, e
"Skipping size summary for %s: %s: %s",
size_json,
type(e).__name__,
e,
exc_info=True,
)
_LOGGER.debug("Size summary failure detail", exc_info=True)
def _print_summary(size_json: Path, partitions_csv: Path | None) -> None:
@@ -104,7 +107,7 @@ def _print_summary(size_json: Path, partitions_csv: Path | None) -> None:
if (ram := _ram_bar(data, size_json)) is not None:
print_size_line("RAM", *ram)
if (flash := _flash_bar(data, partitions_csv)) is not None:
if (flash := _flash_bar(data, size_json, partitions_csv)) is not None:
print_size_line("Flash", *flash)
@@ -129,17 +132,26 @@ def _ram_bar(data: dict, size_json: Path) -> tuple[int, int] | None:
total = _dict_get(ram_region, "size")
if _is_number(used) and _is_number(total) and total > 0:
return int(used), int(total)
if _present_but_not_dict(memory_types) or _present_but_not_dict(ram_region):
malformed = (
_present_but_not_dict(memory_types)
or _present_but_not_dict(ram_region)
or any(v is not None and not _is_number(v) for v in (used, total))
)
if malformed:
# A structurally corrupt report, not a variant without the region
_LOGGER.warning("Skipping RAM summary: malformed memory_types in %s", size_json)
else:
_LOGGER.warning(
# A variant may name its RAM region differently; healthy builds
# must not warn
_LOGGER.debug(
"Skipping RAM summary: no usable DRAM/DIRAM region in %s", size_json
)
return None
def _flash_bar(data: dict, partitions_csv: Path | None) -> tuple[int, int] | None:
def _flash_bar(
data: dict, size_json: Path, partitions_csv: Path | None
) -> tuple[int, int] | None:
"""The Flash bar's (used, total), or None (already logged) to skip it.
Owns both sides of the bar, so nothing after a print can raise: the
@@ -147,7 +159,7 @@ def _flash_bar(data: dict, partitions_csv: Path | None) -> tuple[int, int] | Non
"""
image_size = data.get("image_size")
if not _is_number(image_size):
_LOGGER.warning("Skipping Flash summary: no usable image_size")
_LOGGER.warning("Skipping Flash summary: no usable image_size in %s", size_json)
return None
if partitions_csv is None:
_LOGGER.debug("Skipping Flash summary: no partition table given")
+19 -2
View File
@@ -213,15 +213,32 @@ def test_print_summary_nested_bad_shapes_never_raise(
caplog: pytest.LogCaptureFixture,
payload: dict,
) -> None:
"""Bad nested shapes hit the named RAM guard, not the blanket backstop."""
"""Corrupt nested shapes hit the named malformed guard, not the blanket."""
size_json = _write_size_json(tmp_path, payload)
print_summary(size_json, None)
# No half-formed bar for CI to scrape; every payload fails before printing
assert capsys.readouterr().out == ""
assert "Skipping RAM summary" in caplog.text
assert "malformed memory_types" in caplog.text
assert "Skipping size summary for" not in caplog.text
def test_print_summary_absent_region_stays_quiet(
tmp_path: Path,
capsys: pytest.CaptureFixture[str],
caplog: pytest.LogCaptureFixture,
) -> None:
"""A well-shaped report without DRAM/DIRAM is a variant difference, not
a broken artifact: debug, never a per-build warning."""
size_json = _write_size_json(tmp_path, {"memory_types": {}, "image_size": 1})
with caplog.at_level(logging.DEBUG, logger="esphome.espidf.size_summary"):
print_summary(size_json, None)
assert "RAM:" not in capsys.readouterr().out
assert "no usable DRAM/DIRAM region" in caplog.text
assert not [
r for r in caplog.records if r.levelno >= logging.WARNING and "RAM" in r.message
]
def test_print_summary_non_numeric_image_size_warns_by_name(
tmp_path: Path,
capsys: pytest.CaptureFixture[str],