1
0
mirror of https://github.com/esphome/esphome.git synced 2026-02-08 00:31:58 +00:00

address bot review comemnts

This commit is contained in:
J. Nick Koston
2026-02-06 16:04:12 +01:00
parent f660a62deb
commit 1b8153bd46
2 changed files with 50 additions and 3 deletions

View File

@@ -36,6 +36,7 @@ BUNDLE_EXTENSION = ".esphomebundle.tar.gz"
MANIFEST_FILENAME = "manifest.json"
CURRENT_MANIFEST_VERSION = 1
MAX_DECOMPRESSED_SIZE = 500 * 1024 * 1024 # 500 MB
MAX_MANIFEST_SIZE = 1024 * 1024 # 1 MB
# Directories preserved across bundle extractions (build caches)
_PRESERVE_DIRS = (".esphome", ".pioenvs", ".pio")
@@ -510,6 +511,12 @@ def _read_manifest_from_tar(tar: tarfile.TarFile) -> dict[str, Any]:
if f is None:
raise EsphomeError("Invalid bundle: manifest.json is not a regular file")
if member.size > MAX_MANIFEST_SIZE:
raise EsphomeError(
f"Invalid bundle: manifest.json too large "
f"({member.size} bytes, max {MAX_MANIFEST_SIZE})"
)
try:
manifest = json.loads(f.read())
except (json.JSONDecodeError, UnicodeDecodeError) as err:
@@ -616,11 +623,16 @@ def _default_target_dir(bundle_path: Path) -> Path:
def _restore_preserved_dirs(preserved: dict[str, Path], target_dir: Path) -> None:
"""Move preserved build cache directories back into target_dir."""
"""Move preserved build cache directories back into target_dir.
If the bundle contained entries under a preserved directory name,
the extracted copy is removed so the original cache always wins.
"""
for dirname, src in preserved.items():
dst = target_dir / dirname
if not dst.exists():
shutil.move(str(src), str(dst))
if dst.exists():
shutil.rmtree(dst)
shutil.move(str(src), str(dst))
def prepare_bundle_for_compile(

View File

@@ -411,6 +411,18 @@ def test_extract_bundle_manifest_version_zero(tmp_path: Path) -> None:
extract_bundle(bundle_path, tmp_path / "out")
def test_extract_bundle_manifest_too_large(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
"""Oversized manifest.json is rejected."""
monkeypatch.setattr("esphome.bundle.MAX_MANIFEST_SIZE", 50)
bundle_path = _make_bundle(tmp_path)
with pytest.raises(EsphomeError, match="manifest.json too large"):
extract_bundle(bundle_path, tmp_path / "out")
def test_extract_bundle_manifest_not_regular_file(tmp_path: Path) -> None:
"""manifest.json that is a directory entry raises EsphomeError."""
bundle_path = tmp_path / f"dirmanifest{BUNDLE_EXTENSION}"
@@ -530,6 +542,29 @@ def test_prepare_bundle_missing_file(tmp_path: Path) -> None:
prepare_bundle_for_compile(missing)
def test_prepare_bundle_cache_wins_over_bundle_content(tmp_path: Path) -> None:
"""Pre-existing build cache is restored even if the bundle contains those dirs."""
bundle_path = _make_bundle(
tmp_path,
extra_files={
".esphome/from_bundle.json": b'{"from": "bundle"}',
},
)
target = tmp_path / "work"
target.mkdir()
# Pre-existing build cache
esphome_dir = target / ".esphome"
esphome_dir.mkdir()
(esphome_dir / "local_cache.json").write_text('{"from": "local"}')
prepare_bundle_for_compile(bundle_path, target)
# Local cache should win over bundle content
assert (target / ".esphome" / "local_cache.json").read_text() == '{"from": "local"}'
assert not (target / ".esphome" / "from_bundle.json").exists()
def test_prepare_bundle_default_target_dir(tmp_path: Path) -> None:
"""prepare_bundle_for_compile uses default dir when target_dir is None."""
bundle_path = _make_bundle(tmp_path)