mirror of
https://github.com/esphome/esphome.git
synced 2026-08-22 22:26:21 +00:00
Dump the main.cpp config comment with sorted keys
voluptuous fills schema defaults in set-iteration order, so the validated dict's key order changes with the process hash seed; the unsorted dump churned the comment block in main.cpp and relinked the firmware on every esphome run for any config using a defaults-heavy action (logger.log in a button's on_press was enough). Affects the PlatformIO path identically.
This commit is contained in:
+5
-1
@@ -762,7 +762,11 @@ def _wrap_to_code(name, comp, yaml_util):
|
||||
async def wrapped(conf):
|
||||
cg.add(cg.LineComment(f"{name}:"))
|
||||
if comp.config_schema is not None:
|
||||
conf_str = yaml_util.dump(conf)
|
||||
# sort_keys: voluptuous fills schema defaults in set-iteration
|
||||
# order, so the validated dict's key order changes with the
|
||||
# process hash seed; an unsorted dump would churn main.cpp and
|
||||
# relink the firmware on every run
|
||||
conf_str = yaml_util.dump(conf, sort_keys=True)
|
||||
conf_str = conf_str.replace("//", "")
|
||||
# remove tailing \ to avoid multi-line comment warning
|
||||
conf_str = conf_str.replace("\\\n", "\n")
|
||||
|
||||
@@ -7207,3 +7207,29 @@ def test_compile_program_espidf_idedata_none_warns(
|
||||
):
|
||||
assert compile_program(MagicMock(), {}) == 0
|
||||
assert "No idedata was generated" in caplog.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_wrap_to_code_comment_is_insertion_order_independent() -> None:
|
||||
"""The config comment dumps with sorted keys: voluptuous fills schema
|
||||
defaults in set-iteration order, so an unsorted dump would churn
|
||||
main.cpp and relink the firmware on every run."""
|
||||
from types import SimpleNamespace
|
||||
|
||||
from esphome import yaml_util
|
||||
from esphome.__main__ import _wrap_to_code
|
||||
|
||||
comments: list[str] = []
|
||||
|
||||
async def to_code(conf):
|
||||
pass
|
||||
|
||||
comp = SimpleNamespace(to_code=to_code, config_schema=object())
|
||||
wrapped = _wrap_to_code("demo", comp, yaml_util)
|
||||
with patch("esphome.codegen.add", side_effect=lambda st: comments.append(str(st))):
|
||||
await wrapped({"beta": 1, "alpha": 2})
|
||||
first = list(comments)
|
||||
comments.clear()
|
||||
await wrapped({"alpha": 2, "beta": 1})
|
||||
assert first == comments
|
||||
assert "alpha: 2" in comments[1]
|
||||
|
||||
Reference in New Issue
Block a user