mirror of
https://github.com/esphome/esphome.git
synced 2026-09-30 16:30:22 +00:00
[core] Hash downloaded file paths at the default data dir location (#18824)
This commit is contained in:
@@ -783,7 +783,8 @@ class EsphomeCore:
|
||||
can compare a locally computed hash against the one a device
|
||||
advertises. Machine-local data is kept out of the input: build_path
|
||||
(which embeds ESPHOME_BUILD_PATH and OS path separators) is excluded,
|
||||
and Path values are dumped relative to the config directory.
|
||||
and Path values are dumped relative to the config directory, with
|
||||
the data directory always at its default ``.esphome`` location.
|
||||
"""
|
||||
if self._config_hash is None:
|
||||
from esphome import yaml_util
|
||||
@@ -794,11 +795,15 @@ class EsphomeCore:
|
||||
esphome_conf = dict(esphome_conf)
|
||||
esphome_conf.pop(CONF_BUILD_PATH, None)
|
||||
config[CONF_ESPHOME] = esphome_conf
|
||||
relative_to = data_dir = None
|
||||
if self.config_path is not None:
|
||||
relative_to, data_dir = self.config_dir, self.data_dir
|
||||
config_str = yaml_util.dump(
|
||||
config,
|
||||
show_secrets=True,
|
||||
sort_keys=True,
|
||||
relative_to=self.config_dir if self.config_path is not None else None,
|
||||
relative_to=relative_to,
|
||||
data_dir=data_dir,
|
||||
)
|
||||
self._config_hash = fnv1a_32bit_hash(config_str)
|
||||
return self._config_hash
|
||||
|
||||
+20
-2
@@ -1057,11 +1057,19 @@ def _load_yaml_internal_with_type(
|
||||
loader.dispose()
|
||||
|
||||
|
||||
def dump(dict_, show_secrets=False, sort_keys=False, relative_to: Path | None = None):
|
||||
def dump(
|
||||
dict_,
|
||||
show_secrets=False,
|
||||
sort_keys=False,
|
||||
relative_to: Path | None = None,
|
||||
data_dir: Path | None = None,
|
||||
):
|
||||
"""Dump YAML to a string and remove null.
|
||||
|
||||
When ``relative_to`` is given, Path values are dumped relative to that
|
||||
directory (POSIX form) so the output is machine independent.
|
||||
directory (POSIX form) so the output is machine independent; Path values
|
||||
under ``data_dir`` are then dumped as ``.esphome/<rest>``. ``data_dir``
|
||||
has no effect unless ``relative_to`` is also given.
|
||||
"""
|
||||
if show_secrets:
|
||||
_SECRET_VALUES.clear()
|
||||
@@ -1073,6 +1081,7 @@ def dump(dict_, show_secrets=False, sort_keys=False, relative_to: Path | None =
|
||||
class _Dumper(ESPHomeDumper):
|
||||
_redact_sensitive = not show_secrets
|
||||
_relative_to = relative_to
|
||||
_data_dir = data_dir
|
||||
|
||||
return yaml.dump(
|
||||
dict_,
|
||||
@@ -1231,6 +1240,9 @@ class ESPHomeDumper(yaml.SafeDumper):
|
||||
# directory (in POSIX form) so the output does not depend on where the
|
||||
# config lives on the machine that produced it.
|
||||
_relative_to: Path | None = None
|
||||
# Paths under this directory are dumped as ``.esphome/<rest>`` so the
|
||||
# add-on's ``/data`` mount matches the CLI layout.
|
||||
_data_dir: Path | None = None
|
||||
|
||||
def represent_mapping(self, tag, mapping, flow_style=None):
|
||||
value = []
|
||||
@@ -1274,6 +1286,12 @@ class ESPHomeDumper(yaml.SafeDumper):
|
||||
# path that still cannot be relativized (e.g. a different drive)
|
||||
# keeps its POSIX form so separators stay stable across OSes.
|
||||
path = Path(os.path.normpath(value))
|
||||
# Checked first: the default data dir sits inside the config dir.
|
||||
if self._data_dir is not None and path.is_relative_to(
|
||||
data_dir := os.path.normpath(self._data_dir)
|
||||
):
|
||||
rel = Path(".esphome") / path.relative_to(data_dir)
|
||||
return self.represent_stringify(rel.as_posix())
|
||||
with suppress(ValueError):
|
||||
path = path.relative_to(
|
||||
os.path.normpath(self._relative_to), walk_up=True
|
||||
|
||||
Reference in New Issue
Block a user