diff --git a/esphome/config.py b/esphome/config.py index 73aa7077e0..36a81f677b 100644 --- a/esphome/config.py +++ b/esphome/config.py @@ -374,7 +374,10 @@ class LoadValidationStep(ConfigValidationStep): path + [CONF_ID], ) continue - result.add_str_error("No platform specified! See 'platform' key.", path) + result.add_str_error( + f"'{self.domain}' requires a 'platform' key but it was not specified.", + path, + ) continue # Remove temp output path and construct new one result.remove_output_path(path, p_domain) @@ -449,9 +452,28 @@ class MetadataValidationStep(ConfigValidationStep): success = True for dependency in self.comp.dependencies: - if dependency not in result: + dependency_parts = dependency.split(".") + if len(dependency_parts) > 2: result.add_str_error( - f"Component {self.domain} requires component {dependency}", + "Dependencies must be specified as a single component or in component.platform format only", + self.path, + ) + return + component_dep = dependency_parts[0] + platform_dep = dependency_parts[-1] + if component_dep not in result: + result.add_str_error( + f"Component {self.domain} requires component {component_dep}", + self.path, + ) + success = False + elif component_dep != platform_dep and ( + not isinstance(platform_list := result.get(component_dep), list) + or not any(CONF_PLATFORM in p for p in platform_list) + or not any(p[CONF_PLATFORM] == platform_dep for p in platform_list) + ): + result.add_str_error( + f"Component {self.domain} requires 'platform: {platform_dep}' in component '{component_dep}'", self.path, ) success = False diff --git a/script/list-components.py b/script/list-components.py index 8e2d47c6b3..5b5fa5811f 100755 --- a/script/list-components.py +++ b/script/list-components.py @@ -69,7 +69,9 @@ def create_components_graph(): sys.exit(1) for dependency in comp.dependencies: - add_item_to_components_graph(components_graph, dependency, name) + add_item_to_components_graph( + components_graph, dependency.split(".")[0], name + ) for target_config in TARGET_CONFIGURATIONS: CORE.data[KEY_CORE] = target_config @@ -87,7 +89,9 @@ def create_components_graph(): add_item_to_components_graph(components_graph, platform_name, name) for dependency in platform.dependencies: - add_item_to_components_graph(components_graph, dependency, name) + add_item_to_components_graph( + components_graph, dependency.split(".")[0], name + ) for target_config in TARGET_CONFIGURATIONS: CORE.data[KEY_CORE] = target_config