mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
Unlink a damaged build_info.json so regeneration completes, and log the replacement
The widened except left non-UTF-8 damage half-fixed: the staleness branch fired, but write_file_if_changed then re-read the damaged file and raised EsphomeError. Unlinking in the handler makes the recovery self-sufficient, and the warning makes a repeatedly unreadable file visible instead of silently costing a rebuild each run. The non-UTF-8 case now runs end to end as a third row of the parametrized damage test, replacing the stubbed decision-only test.
This commit is contained in:
+7
-2
@@ -1,3 +1,4 @@
|
||||
from contextlib import suppress
|
||||
import importlib
|
||||
import json
|
||||
import logging
|
||||
@@ -343,8 +344,12 @@ def copy_src_tree():
|
||||
):
|
||||
# Non-object JSON is stale like every other damage case
|
||||
sources_changed = True
|
||||
except (ValueError, OSError):
|
||||
# ValueError covers both JSONDecodeError and UnicodeDecodeError
|
||||
except (ValueError, OSError) as err:
|
||||
# ValueError covers both JSONDecodeError and UnicodeDecodeError;
|
||||
# unlink so the regenerating write never re-reads the damage
|
||||
_LOGGER.warning("Replacing damaged build_info.json: %s", err)
|
||||
with suppress(OSError):
|
||||
build_info_json_path.unlink(missing_ok=True)
|
||||
sources_changed = True
|
||||
|
||||
# Write build_info header and JSON metadata
|
||||
|
||||
@@ -2118,8 +2118,8 @@ def test_copy_src_tree_detects_version_change(
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"damage",
|
||||
(b"invalid json {{{", b"[]"),
|
||||
ids=("invalid-json", "non-object"),
|
||||
(b"invalid json {{{", b"[]", b'\xff{"config_hash": 1}'),
|
||||
ids=("invalid-json", "non-object", "non-utf8"),
|
||||
)
|
||||
@patch("esphome.writer.CORE")
|
||||
@patch("esphome.writer.iter_components")
|
||||
@@ -2143,35 +2143,6 @@ def test_copy_src_tree_regenerates_damaged_build_info(
|
||||
assert new_json["config_hash"] == 0xDEADBEEF
|
||||
|
||||
|
||||
@patch("esphome.writer.write_file_if_changed", return_value=False)
|
||||
@patch("esphome.writer.CORE")
|
||||
@patch("esphome.writer.iter_components")
|
||||
@patch("esphome.writer.walk_files")
|
||||
def test_copy_src_tree_non_utf8_build_info_reads_as_stale(
|
||||
mock_walk_files: MagicMock,
|
||||
mock_iter_components: MagicMock,
|
||||
mock_core: MagicMock,
|
||||
mock_write: MagicMock,
|
||||
tmp_path: Path,
|
||||
) -> None:
|
||||
"""Non-UTF-8 build_info.json fires the staleness branch instead of raising.
|
||||
|
||||
Writes are stubbed (returning False, so nothing else can set
|
||||
sources_changed): regenerating over the damaged file needs
|
||||
write_file_if_changed's own recovery, which lands separately.
|
||||
"""
|
||||
build_info_json_path = _setup_build_info_mocks(
|
||||
mock_core, mock_iter_components, mock_walk_files, tmp_path
|
||||
)
|
||||
core_path = tmp_path / "src" / "esphome" / "core"
|
||||
(core_path / "build_info_data.h").write_text("// old")
|
||||
(core_path / "build_info_data.cpp").write_text("// old")
|
||||
build_info_json_path.write_bytes(b'\xff{"config_hash": 1}')
|
||||
_run_copy_src_tree()
|
||||
written = [call.args[0] for call in mock_write.call_args_list]
|
||||
assert build_info_json_path in written
|
||||
|
||||
|
||||
@patch("esphome.writer.CORE")
|
||||
@patch("esphome.writer.iter_components")
|
||||
@patch("esphome.writer.walk_files")
|
||||
|
||||
Reference in New Issue
Block a user