diff --git a/esphome/build_helpers/size_summary.py b/esphome/build_helpers/size_summary.py index 5068e76d2d..72c429d095 100644 --- a/esphome/build_helpers/size_summary.py +++ b/esphome/build_helpers/size_summary.py @@ -17,3 +17,12 @@ def format_bar(used: int, total: int) -> str: f"[{progress:<{blocks}}] {pct_raw: 6.1%} " f"(used {used:d} bytes from {total:d} bytes)" ) + + +def print_size_line(label: str, used: int, total: int) -> None: + """One PlatformIO-format summary line (``RAM``/``Flash``). + + The label padding is part of the format: ``script/ci_memory_impact_extract.py`` + matches these lines verbatim. + """ + print(f"{label + ':':<7}{format_bar(used, total)}") diff --git a/esphome/espidf/size_summary.py b/esphome/espidf/size_summary.py index 64f8edb98e..2be3634c69 100644 --- a/esphome/espidf/size_summary.py +++ b/esphome/espidf/size_summary.py @@ -28,7 +28,7 @@ import json import logging from pathlib import Path -from esphome.build_helpers.size_summary import format_bar +from esphome.build_helpers.size_summary import print_size_line _LOGGER = logging.getLogger(__name__) _SIZE_SUFFIXES = {"K": 1024, "M": 1024 * 1024} @@ -89,7 +89,7 @@ def print_summary(size_json: Path, partitions_csv: Path | None) -> None: ram_used = ram_region.get("used") ram_total = ram_region.get("size") if ram_total and ram_used is not None: - print(f"RAM: {format_bar(ram_used, ram_total)}") + print_size_line("RAM", ram_used, ram_total) image_size = data.get("image_size") if image_size is None or partitions_csv is None: @@ -99,4 +99,4 @@ def print_summary(size_json: Path, partitions_csv: Path | None) -> None: except ValueError as e: _LOGGER.debug("Skipping Flash summary: %s", e) return - print(f"Flash: {format_bar(image_size, app_size)}") + print_size_line("Flash", image_size, app_size) diff --git a/esphome/platformio/library.py b/esphome/platformio/library.py index 4ae256444a..771570f872 100644 --- a/esphome/platformio/library.py +++ b/esphome/platformio/library.py @@ -48,20 +48,23 @@ DEFAULT_BUILD_SRC_FILTER = ( DEFAULT_BUILD_SRC_DIRS = "src" DEFAULT_BUILD_INCLUDE_DIR = "include" DEFAULT_BUILD_FLAGS = [] -SRC_FILE_EXTENSIONS = [ - ".c", - ".cpp", - ".cc", - ".cxx", - ".c++", - ".S", - ".spp", - ".SPP", - ".sx", - ".s", - ".asm", - ".ASM", -] +# Source suffix -> compiler kind, PlatformIO's CSUFFIXES/CXXSUFFIXES/ASSUFFIXES +# split. Native build generators map the kind to their compile rules. +SOURCE_KIND_FOR_SUFFIX: dict[str, str] = { + ".c": "c", + ".cpp": "cxx", + ".cc": "cxx", + ".cxx": "cxx", + ".c++": "cxx", + ".S": "asm", + ".spp": "asm", + ".SPP": "asm", + ".sx": "asm", + ".s": "asm", + ".asm": "asm", + ".ASM": "asm", +} +SRC_FILE_EXTENSIONS = list(SOURCE_KIND_FOR_SUFFIX) DOMAIN = "pio_components" diff --git a/esphome/platformio/toolchain.py b/esphome/platformio/toolchain.py index d76581d032..f454b81441 100644 --- a/esphome/platformio/toolchain.py +++ b/esphome/platformio/toolchain.py @@ -254,6 +254,7 @@ def _ccache_runs(ccache: str) -> bool: stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=15, + close_fds=False, ) except (OSError, subprocess.SubprocessError): _LOGGER.warning( diff --git a/tests/unit_tests/build_helpers/test_size_summary.py b/tests/unit_tests/build_helpers/test_size_summary.py index 2ccdb96613..231ae271b2 100644 --- a/tests/unit_tests/build_helpers/test_size_summary.py +++ b/tests/unit_tests/build_helpers/test_size_summary.py @@ -2,9 +2,21 @@ from __future__ import annotations -from esphome.build_helpers.size_summary import format_bar +import pytest + +from esphome.build_helpers.size_summary import format_bar, print_size_line def test_format_bar_zero_total() -> None: """A zero total must not divide by zero.""" assert format_bar(0, 0) == "[ ] 0.0% (used 0 bytes from 0 bytes)" + + +def test_print_size_line_label_padding(capsys: pytest.CaptureFixture[str]) -> None: + """The label column is exactly what ci_memory_impact_extract.py greps.""" + print_size_line("RAM", 47932, 180736) + print_size_line("Flash", 888511, 1835008) + out = capsys.readouterr().out.splitlines() + assert out[0].startswith("RAM: [") + assert out[1].startswith("Flash: [") + assert "26.5% (used 47932 bytes from 180736 bytes)" in out[0]