From 47520965208a6731b3fb224f8b88c7409f497667 Mon Sep 17 00:00:00 2001 From: Otto Winter Date: Wed, 15 Jul 2020 15:27:24 +0200 Subject: [PATCH] Don't remove location information for packages (#1133) --- esphome/components/packages/__init__.py | 59 +++++++++----------- esphome/components/substitutions/__init__.py | 3 +- esphome/config.py | 10 ++-- esphome/const.py | 1 + requirements.txt | 1 - 5 files changed, 33 insertions(+), 41 deletions(-) diff --git a/esphome/components/packages/__init__.py b/esphome/components/packages/__init__.py index 729af4a9a0..afbeae7f8d 100644 --- a/esphome/components/packages/__init__.py +++ b/esphome/components/packages/__init__.py @@ -1,51 +1,44 @@ -from deepmerge import conservative_merger as package_merger - import esphome.config_validation as cv from esphome.const import CONF_PACKAGES -VALID_PACKAGE_NAME_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_' +def _merge_package(full_old, full_new): -def _merge_package(config, package_name, package_config): - config = config.copy() - package_merger.merge(config, package_config) - return config + def merge(old, new): + # pylint: disable=no-else-return + if isinstance(new, dict): + if not isinstance(old, dict): + return new + res = old.copy() + for k, v in new.items(): + res[k] = merge(old[k], v) if k in old else v + return res + elif isinstance(new, list): + if not isinstance(old, list): + return new + return old + new + return new -def _is_valid_package_name(value: str) -> bool: - if not value: - return False - if value[0].isdigit(): - return False - try: - cv.valid_name(value) - except cv.Invalid: - return False - return True + return merge(full_old, full_new) def do_packages_pass(config: dict): if CONF_PACKAGES not in config: - return + return config packages = config[CONF_PACKAGES] - temp_config = config.copy() with cv.prepend_path(CONF_PACKAGES): - if packages is not None and not isinstance(packages, dict): + if not isinstance(packages, dict): raise cv.Invalid("Packages must be a key to value mapping, got {} instead" "".format(type(packages))) + for package_name, package_config in packages.items(): with cv.prepend_path(package_name): - if not isinstance(package_config, dict): - raise cv.Invalid("Package definition must be a dictionary containing valid " - "esphome configuration to be merged with the main " - "config, got {} instead" - .format(type(package_config))) - if not _is_valid_package_name(package_name): - raise cv.Invalid("Package name is invalid. Valid name should consist of " - "letters, numbers and underscores. It shouldn't also " - "start with number") - temp_config = _merge_package(temp_config, package_name, package_config) - del temp_config[CONF_PACKAGES] - config.clear() - config.update(temp_config) + recursive_package = package_config + if isinstance(package_config, dict): + recursive_package = do_packages_pass(package_config) + config = _merge_package(config, recursive_package) + + del config[CONF_PACKAGES] + return config diff --git a/esphome/components/substitutions/__init__.py b/esphome/components/substitutions/__init__.py index ab99e040d4..a6f70fe928 100644 --- a/esphome/components/substitutions/__init__.py +++ b/esphome/components/substitutions/__init__.py @@ -3,11 +3,10 @@ import re import esphome.config_validation as cv from esphome import core +from esphome.const import CONF_SUBSTITUTIONS _LOGGER = logging.getLogger(__name__) -CONF_SUBSTITUTIONS = 'substitutions' - VALID_SUBSTITUTIONS_CHARACTERS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' \ '0123456789_' diff --git a/esphome/config.py b/esphome/config.py index 6f3a498444..84d3ca3803 100644 --- a/esphome/config.py +++ b/esphome/config.py @@ -11,10 +11,8 @@ from contextlib import contextmanager import voluptuous as vol from esphome import core, core_config, yaml_util -from esphome.components import substitutions -from esphome.components.packages import do_packages_pass -from esphome.components.substitutions import CONF_SUBSTITUTIONS -from esphome.const import CONF_ESPHOME, CONF_PLATFORM, ESP_PLATFORMS, CONF_PACKAGES +from esphome.const import CONF_ESPHOME, CONF_PLATFORM, ESP_PLATFORMS, CONF_PACKAGES, \ + CONF_SUBSTITUTIONS from esphome.core import CORE, EsphomeError # noqa from esphome.helpers import color, indent from esphome.util import safe_print, OrderedDict @@ -393,9 +391,10 @@ def validate_config(config, command_line_substitutions): # 0. Load packages if CONF_PACKAGES in config: + from esphome.components.packages import do_packages_pass result.add_output_path([CONF_PACKAGES], CONF_PACKAGES) try: - do_packages_pass(config) + config = do_packages_pass(config) except vol.Invalid as err: result.update(config) result.add_error(err) @@ -403,6 +402,7 @@ def validate_config(config, command_line_substitutions): # 1. Load substitutions if CONF_SUBSTITUTIONS in config: + from esphome.components import substitutions result[CONF_SUBSTITUTIONS] = {**config[CONF_SUBSTITUTIONS], **command_line_substitutions} result.add_output_path([CONF_SUBSTITUTIONS], CONF_SUBSTITUTIONS) try: diff --git a/esphome/const.py b/esphome/const.py index 45b5e5e209..202d2991b5 100644 --- a/esphome/const.py +++ b/esphome/const.py @@ -467,6 +467,7 @@ CONF_STEP_PIN = 'step_pin' CONF_STOP = 'stop' CONF_STOP_ACTION = 'stop_action' CONF_SUBNET = 'subnet' +CONF_SUBSTITUTIONS = 'substitutions' CONF_SUPPORTS_COOL = 'supports_cool' CONF_SUPPORTS_HEAT = 'supports_heat' CONF_SWING_BOTH_ACTION = 'swing_both_action' diff --git a/requirements.txt b/requirements.txt index 059a07fc83..2d03924cec 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,4 +11,3 @@ ifaddr==0.1.7 platformio==4.3.4 esptool==2.8 click==7.1.2 -deepmerge==0.1.0