From 6c9307953a013970e0c046d349413e2b26636ee5 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 26 Apr 2020 18:13:46 -0700 Subject: [PATCH 1/3] Validate that discovered config flows set a unique ID --- script/hassfest/config_flow.py | 66 +++++++++++++++++++++------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/script/hassfest/config_flow.py b/script/hassfest/config_flow.py index 6971cc28fc90b..a10db6686703d 100644 --- a/script/hassfest/config_flow.py +++ b/script/hassfest/config_flow.py @@ -2,6 +2,8 @@ import json from typing import Dict +from homeassistant.requirements import DISCOVERY_INTEGRATIONS + from .model import Config, Integration BASE = """ @@ -15,33 +17,49 @@ FLOWS = {} """.strip() +UNIQUE_ID_IGNORE = {"esphome", "fritzbox", "heos", "huawei_lte", "netatmo", "tradfri"} + -def validate_integration(integration: Integration): - """Validate we can load config flow without installing requirements.""" - if not (integration.path / "config_flow.py").is_file(): +def validate_integration(config: Config, integration: Integration): + """Validate config flow of an integration.""" + config_flow_file = integration.path / "config_flow.py" + + if not config_flow_file.is_file(): integration.add_error( "config_flow", "Config flows need to be defined in the file config_flow.py" ) + return + + needs_unique_id = integration.domain not in UNIQUE_ID_IGNORE and any( + key in integration.manifest + for keys in DISCOVERY_INTEGRATIONS.values() + for key in keys + ) + + if not needs_unique_id: + return + + config_flow = config_flow_file.read_text() + + has_unique_id = ( + "self.async_set_unique_id" in config_flow + or "config_entry_flow.register_discovery_flow" in config_flow + ) + + if has_unique_id: + return + + if config.specific_integrations: + notice_method = integration.add_warning + else: + notice_method = integration.add_error + + notice_method( + "config_flow", "Config flows that are discoverable need to set a unique ID" + ) + - # Currently not require being able to load config flow without - # installing requirements. - # try: - # integration.import_pkg('config_flow') - # except ImportError as err: - # integration.add_error( - # 'config_flow', - # "Unable to import config flow: {}. Config flows should be able " - # "to be imported without installing requirements.".format(err)) - # return - - # if integration.domain not in config_entries.HANDLERS: - # integration.add_error( - # 'config_flow', - # "Importing the config flow platform did not register a config " - # "flow handler.") - - -def generate_and_validate(integrations: Dict[str, Integration]): +def generate_and_validate(integrations: Dict[str, Integration], config: Config): """Validate and generate config flow data.""" domains = [] @@ -56,7 +74,7 @@ def generate_and_validate(integrations: Dict[str, Integration]): if not config_flow: continue - validate_integration(integration) + validate_integration(config, integration) domains.append(domain) @@ -66,7 +84,7 @@ def generate_and_validate(integrations: Dict[str, Integration]): def validate(integrations: Dict[str, Integration], config: Config): """Validate config flow file.""" config_flow_path = config.root / "homeassistant/generated/config_flows.py" - config.cache["config_flow"] = content = generate_and_validate(integrations) + config.cache["config_flow"] = content = generate_and_validate(integrations, config) if config.specific_integrations: return From eeabb3f5d579a52d90e87bf10e77fabc31748878 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Sun, 26 Apr 2020 18:21:15 -0700 Subject: [PATCH 2/3] OAuth2 config flow helper also handles unique ID --- script/hassfest/config_flow.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/script/hassfest/config_flow.py b/script/hassfest/config_flow.py index a10db6686703d..ae75df8340598 100644 --- a/script/hassfest/config_flow.py +++ b/script/hassfest/config_flow.py @@ -17,7 +17,7 @@ FLOWS = {} """.strip() -UNIQUE_ID_IGNORE = {"esphome", "fritzbox", "heos", "huawei_lte", "netatmo", "tradfri"} +UNIQUE_ID_IGNORE = {"esphome", "fritzbox", "heos", "huawei_lte", "tradfri"} def validate_integration(config: Config, integration: Integration): @@ -44,6 +44,7 @@ def validate_integration(config: Config, integration: Integration): has_unique_id = ( "self.async_set_unique_id" in config_flow or "config_entry_flow.register_discovery_flow" in config_flow + or "config_entry_oauth2_flow.AbstractOAuth2FlowHandler" in config_flow ) if has_unique_id: From 0cf4ec6cccc27b741ef9a58b2a1ac70383174050 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 27 Apr 2020 10:36:47 -0700 Subject: [PATCH 3/3] Update script/hassfest/config_flow.py Co-Authored-By: Franck Nijhof --- script/hassfest/config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/hassfest/config_flow.py b/script/hassfest/config_flow.py index ae75df8340598..c31e77ccdfffe 100644 --- a/script/hassfest/config_flow.py +++ b/script/hassfest/config_flow.py @@ -17,7 +17,7 @@ FLOWS = {} """.strip() -UNIQUE_ID_IGNORE = {"esphome", "fritzbox", "heos", "huawei_lte", "tradfri"} +UNIQUE_ID_IGNORE = {"esphome", "fritzbox", "heos", "huawei_lte"} def validate_integration(config: Config, integration: Integration):