diff --git a/esphome/arduino8266/framework.py b/esphome/arduino8266/framework.py index f680815c31..125238a30a 100644 --- a/esphome/arduino8266/framework.py +++ b/esphome/arduino8266/framework.py @@ -22,7 +22,7 @@ from esphome.build_helpers.ninja import find_ninja from esphome.build_helpers.tools_cache import tools_cache_path from esphome.core import EsphomeError, Version from esphome.framework_helpers import str_to_lst_of_str -from esphome.platformio.registry import install_package +from esphome.platformio.registry import install_package, prefetch_packages FRAMEWORK_PACKAGE = "framework-arduinoespressif8266" TOOLCHAIN_PACKAGE = "toolchain-xtensa" @@ -101,6 +101,25 @@ def check_and_install(framework_version: Version) -> InstalledPaths: package_version = framework_package_version(framework_version) framework_path = get_framework_path(package_version) downloads_dir = get_arduino8266_tools_path() / "downloads" + toolchain_path = get_toolchain_path() + # Fetch both archives at once; the installs below verify and extract + prefetch_packages( + [ + ( + FRAMEWORK_PACKAGE, + package_version, + framework_path, + ESPHOME_ARDUINO8266_FRAMEWORK_MIRRORS, + ), + ( + TOOLCHAIN_PACKAGE, + TOOLCHAIN_VERSION, + toolchain_path, + ESPHOME_ARDUINO8266_TOOLCHAIN_MIRRORS, + ), + ], + downloads_dir, + ) install_package( FRAMEWORK_PACKAGE, package_version, @@ -109,7 +128,6 @@ def check_and_install(framework_version: Version) -> InstalledPaths: downloads_dir, expect=("cores/esp8266", "tools/sdk", "libraries"), ) - toolchain_path = get_toolchain_path() install_package( TOOLCHAIN_PACKAGE, TOOLCHAIN_VERSION, diff --git a/tests/unit_tests/test_arduino8266_framework.py b/tests/unit_tests/test_arduino8266_framework.py index 2837be1905..932958d667 100644 --- a/tests/unit_tests/test_arduino8266_framework.py +++ b/tests/unit_tests/test_arduino8266_framework.py @@ -63,6 +63,7 @@ def test_check_and_install_returns_paths(tmp_path: Path) -> None: with ( patch.dict(os.environ, {"ESPHOME_ARDUINO8266_PREFIX": str(tmp_path)}), patch.object(framework, "install_package") as mock_install, + patch.object(framework, "prefetch_packages") as mock_prefetch, patch.object(framework, "find_ninja", return_value=tmp_path / "ninja"), ): paths = framework.check_and_install(cv.Version(3, 1, 2)) @@ -89,6 +90,24 @@ def test_check_and_install_returns_paths(tmp_path: Path) -> None: tmp_path / "downloads", ) assert tc_call.kwargs["expect"] == ("bin", "xtensa-lx106-elf") + # The prefetch sees the same package specs as the installs + assert mock_prefetch.call_args.args == ( + [ + ( + framework.FRAMEWORK_PACKAGE, + "3.30102.0", + tmp_path / "frameworks" / "3.30102.0", + framework.ESPHOME_ARDUINO8266_FRAMEWORK_MIRRORS, + ), + ( + framework.TOOLCHAIN_PACKAGE, + framework.TOOLCHAIN_VERSION, + tmp_path / "toolchains" / framework.TOOLCHAIN_VERSION, + framework.ESPHOME_ARDUINO8266_TOOLCHAIN_MIRRORS, + ), + ], + tmp_path / "downloads", + ) def test_get_build_env_prepends_toolchain_bin(tmp_path: Path) -> None: