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:
@@ -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(
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user