mirror of
https://github.com/home-assistant/core.git
synced 2025-07-16 17:57:11 +00:00
Extend package support (#14611)
This commit is contained in:
parent
48972c7570
commit
6ceafabd78
@ -548,6 +548,31 @@ def _identify_config_schema(module):
|
|||||||
return '', schema
|
return '', schema
|
||||||
|
|
||||||
|
|
||||||
|
def _recursive_merge(pack_name, comp_name, config, conf, package):
|
||||||
|
"""Merge package into conf, recursively."""
|
||||||
|
for key, pack_conf in package.items():
|
||||||
|
if isinstance(pack_conf, dict):
|
||||||
|
if not pack_conf:
|
||||||
|
continue
|
||||||
|
conf[key] = conf.get(key, OrderedDict())
|
||||||
|
_recursive_merge(pack_name, comp_name, config,
|
||||||
|
conf=conf[key], package=pack_conf)
|
||||||
|
|
||||||
|
elif isinstance(pack_conf, list):
|
||||||
|
if not pack_conf:
|
||||||
|
continue
|
||||||
|
conf[key] = cv.ensure_list(conf.get(key))
|
||||||
|
conf[key].extend(cv.ensure_list(pack_conf))
|
||||||
|
|
||||||
|
else:
|
||||||
|
if conf.get(key) is not None:
|
||||||
|
_log_pkg_error(
|
||||||
|
pack_name, comp_name, config,
|
||||||
|
'has keys that are defined multiple times')
|
||||||
|
else:
|
||||||
|
conf[key] = pack_conf
|
||||||
|
|
||||||
|
|
||||||
def merge_packages_config(hass, config, packages,
|
def merge_packages_config(hass, config, packages,
|
||||||
_log_pkg_error=_log_pkg_error):
|
_log_pkg_error=_log_pkg_error):
|
||||||
"""Merge packages into the top-level configuration. Mutate config."""
|
"""Merge packages into the top-level configuration. Mutate config."""
|
||||||
@ -607,11 +632,10 @@ def merge_packages_config(hass, config, packages,
|
|||||||
config[comp_name][key] = val
|
config[comp_name][key] = val
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# The last merge type are sections that may occur only once
|
# The last merge type are sections that require recursive merging
|
||||||
if comp_name in config:
|
if comp_name in config:
|
||||||
_log_pkg_error(
|
_recursive_merge(pack_name, comp_name, config,
|
||||||
pack_name, comp_name, config, "may occur only once"
|
conf=config[comp_name], package=comp_conf)
|
||||||
" and it already exist in your main configuration")
|
|
||||||
continue
|
continue
|
||||||
config[comp_name] = comp_conf
|
config[comp_name] = comp_conf
|
||||||
|
|
||||||
|
@ -654,21 +654,81 @@ def test_merge_type_mismatch(merge_log_err, hass):
|
|||||||
assert len(config['light']) == 2
|
assert len(config['light']) == 2
|
||||||
|
|
||||||
|
|
||||||
def test_merge_once_only(merge_log_err, hass):
|
def test_merge_once_only_keys(merge_log_err, hass):
|
||||||
"""Test if we have a merge for a comp that may occur only once."""
|
"""Test if we have a merge for a comp that may occur only once. Keys."""
|
||||||
packages = {
|
packages = {'pack_2': {'api': {
|
||||||
'pack_2': {
|
'key_3': 3,
|
||||||
'mqtt': {},
|
}}}
|
||||||
'api': {}, # No config schema
|
|
||||||
},
|
|
||||||
}
|
|
||||||
config = {
|
config = {
|
||||||
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||||
'mqtt': {}, 'api': {}
|
'api': {
|
||||||
|
'key_1': 1,
|
||||||
|
'key_2': 2,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_util.merge_packages_config(hass, config, packages)
|
||||||
|
assert config['api'] == {'key_1': 1, 'key_2': 2, 'key_3': 3, }
|
||||||
|
|
||||||
|
# Duplicate keys error
|
||||||
|
packages = {'pack_2': {'api': {
|
||||||
|
'key': 2,
|
||||||
|
}}}
|
||||||
|
config = {
|
||||||
|
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||||
|
'api': {'key': 1, }
|
||||||
}
|
}
|
||||||
config_util.merge_packages_config(hass, config, packages)
|
config_util.merge_packages_config(hass, config, packages)
|
||||||
assert merge_log_err.call_count == 1
|
assert merge_log_err.call_count == 1
|
||||||
assert len(config) == 3
|
|
||||||
|
|
||||||
|
def test_merge_once_only_lists(hass):
|
||||||
|
"""Test if we have a merge for a comp that may occur only once. Lists."""
|
||||||
|
packages = {'pack_2': {'api': {
|
||||||
|
'list_1': ['item_2', 'item_3'],
|
||||||
|
'list_2': ['item_1'],
|
||||||
|
'list_3': [],
|
||||||
|
}}}
|
||||||
|
config = {
|
||||||
|
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||||
|
'api': {
|
||||||
|
'list_1': ['item_1'],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_util.merge_packages_config(hass, config, packages)
|
||||||
|
assert config['api'] == {
|
||||||
|
'list_1': ['item_1', 'item_2', 'item_3'],
|
||||||
|
'list_2': ['item_1'],
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def test_merge_once_only_dictionaries(hass):
|
||||||
|
"""Test if we have a merge for a comp that may occur only once. Dicts."""
|
||||||
|
packages = {'pack_2': {'api': {
|
||||||
|
'dict_1': {
|
||||||
|
'key_2': 2,
|
||||||
|
'dict_1.1': {'key_1.2': 1.2, },
|
||||||
|
},
|
||||||
|
'dict_2': {'key_1': 1, },
|
||||||
|
'dict_3': {},
|
||||||
|
}}}
|
||||||
|
config = {
|
||||||
|
config_util.CONF_CORE: {config_util.CONF_PACKAGES: packages},
|
||||||
|
'api': {
|
||||||
|
'dict_1': {
|
||||||
|
'key_1': 1,
|
||||||
|
'dict_1.1': {'key_1.1': 1.1, }
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
config_util.merge_packages_config(hass, config, packages)
|
||||||
|
assert config['api'] == {
|
||||||
|
'dict_1': {
|
||||||
|
'key_1': 1,
|
||||||
|
'key_2': 2,
|
||||||
|
'dict_1.1': {'key_1.1': 1.1, 'key_1.2': 1.2, },
|
||||||
|
},
|
||||||
|
'dict_2': {'key_1': 1, },
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_merge_id_schema(hass):
|
def test_merge_id_schema(hass):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user