diff --git a/esphome/helpers.py b/esphome/helpers.py index 1193d61eaa..289abe5459 100644 --- a/esphome/helpers.py +++ b/esphome/helpers.py @@ -1,4 +1,5 @@ import codecs +from contextlib import suppress import logging import os @@ -233,8 +234,20 @@ def copy_file_if_changed(src: os.PathLike, dst: os.PathLike) -> None: return mkdir_p(os.path.dirname(dst)) try: - shutil.copy(src, dst) + shutil.copyfile(src, dst) except OSError as err: + if isinstance(err, PermissionError): + # Older esphome versions copied over the src file permissions too. + # So when the dst file had 444 permissions, the dst file would have those + # too and subsequent writes would fail + + # -> delete file (it would be overwritten anyway), and try again + # if that fails, use normal error handler + with suppress(OSError): + os.unlink(dst) + shutil.copyfile(src, dst) + return + from esphome.core import EsphomeError raise EsphomeError(f"Error copying file {src} to {dst}: {err}") from err