mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 23:37:34 +00:00
[substitutions] [packages] Extract resolve_substitutions_block helper
Deduplicate the resolve+shape-check block between do_substitution_pass and do_packages_pass, and drop the raw_substitutions/substitutions naming split.
This commit is contained in:
@@ -10,6 +10,7 @@ from esphome.components.substitutions import (
|
||||
ContextVars,
|
||||
push_context,
|
||||
resolve_include,
|
||||
resolve_substitutions_block,
|
||||
substitute,
|
||||
)
|
||||
from esphome.components.substitutions.jinja import has_jinja
|
||||
@@ -516,23 +517,12 @@ def do_packages_pass(
|
||||
if CONF_PACKAGES not in config:
|
||||
return config
|
||||
|
||||
raw_substitutions = config.pop(CONF_SUBSTITUTIONS, {})
|
||||
with cv.prepend_path(CONF_SUBSTITUTIONS):
|
||||
if isinstance(raw_substitutions, yaml_util.IncludeFile):
|
||||
# Resolve `substitutions: !include file.yaml` before feeding into UserDict.
|
||||
# Seed with command-line substitutions so `!include ${var}.yaml` can
|
||||
# reference CLI-provided vars in the filename.
|
||||
raw_substitutions, _ = resolve_include(
|
||||
raw_substitutions,
|
||||
[],
|
||||
ContextVars(command_line_substitutions or {}),
|
||||
strict_undefined=False,
|
||||
substitutions = UserDict(
|
||||
resolve_substitutions_block(
|
||||
config.pop(CONF_SUBSTITUTIONS, {}), command_line_substitutions
|
||||
)
|
||||
if not isinstance(raw_substitutions, dict):
|
||||
raise cv.Invalid(
|
||||
f"Substitutions must be a key to value mapping, got {type(raw_substitutions)}"
|
||||
)
|
||||
substitutions = UserDict(raw_substitutions)
|
||||
)
|
||||
processor = _PackageProcessor(
|
||||
substitutions, command_line_substitutions, skip_update
|
||||
)
|
||||
|
||||
@@ -414,6 +414,31 @@ def _warn_unresolved_variables(errors: ErrList) -> None:
|
||||
)
|
||||
|
||||
|
||||
def resolve_substitutions_block(
|
||||
substitutions: Any,
|
||||
command_line_substitutions: dict[str, Any] | None,
|
||||
) -> dict[str, Any]:
|
||||
"""Resolve a deferred ``substitutions: !include file.yaml`` and validate the shape.
|
||||
|
||||
The caller is responsible for wrapping the call in
|
||||
``cv.prepend_path(CONF_SUBSTITUTIONS)`` for error reporting.
|
||||
``command_line_substitutions`` seeds the filename context so
|
||||
``substitutions: !include ${var}.yaml`` can reference CLI-provided vars.
|
||||
"""
|
||||
if isinstance(substitutions, IncludeFile):
|
||||
substitutions, _ = resolve_include(
|
||||
substitutions,
|
||||
[],
|
||||
ContextVars(command_line_substitutions or {}),
|
||||
strict_undefined=False,
|
||||
)
|
||||
if not isinstance(substitutions, dict):
|
||||
raise cv.Invalid(
|
||||
f"Substitutions must be a key to value mapping, got {type(substitutions)}"
|
||||
)
|
||||
return substitutions
|
||||
|
||||
|
||||
def do_substitution_pass(
|
||||
config: OrderedDict, command_line_substitutions: dict[str, Any] | None = None
|
||||
) -> OrderedDict:
|
||||
@@ -429,20 +454,9 @@ def do_substitution_pass(
|
||||
# Use merge_dicts_ordered to preserve OrderedDict type for move_to_end()
|
||||
substitutions = config.pop(CONF_SUBSTITUTIONS, {})
|
||||
with cv.prepend_path(CONF_SUBSTITUTIONS):
|
||||
if isinstance(substitutions, IncludeFile):
|
||||
# Resolve `substitutions: !include file.yaml` before validating the shape.
|
||||
# Seed with command-line substitutions so `!include ${var}.yaml` can
|
||||
# reference CLI-provided vars in the filename.
|
||||
substitutions, _ = resolve_include(
|
||||
substitutions,
|
||||
[],
|
||||
ContextVars(command_line_substitutions or {}),
|
||||
strict_undefined=False,
|
||||
)
|
||||
if not isinstance(substitutions, dict):
|
||||
raise cv.Invalid(
|
||||
f"Substitutions must be a key to value mapping, got {type(substitutions)}"
|
||||
)
|
||||
substitutions = resolve_substitutions_block(
|
||||
substitutions, command_line_substitutions
|
||||
)
|
||||
substitutions = merge_dicts_ordered(
|
||||
substitutions, command_line_substitutions or {}
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user