mirror of
https://github.com/home-assistant/core.git
synced 2025-07-29 18:28:14 +02:00
Split scaffolding script (#26832)
* Add scaffolding split * Add second config flow method
This commit is contained in:
committed by
Aaron Bach
parent
2e4cc7e5a0
commit
5a4a3e17cc
@ -1,8 +1,7 @@
|
||||
"""Generate an integration."""
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
from .const import COMPONENT_DIR, TESTS_DIR
|
||||
from .error import ExitApp
|
||||
from .model import Info
|
||||
|
||||
TEMPLATE_DIR = Path(__file__).parent / "templates"
|
||||
@ -10,38 +9,113 @@ TEMPLATE_INTEGRATION = TEMPLATE_DIR / "integration"
|
||||
TEMPLATE_TESTS = TEMPLATE_DIR / "tests"
|
||||
|
||||
|
||||
def generate(info: Info) -> None:
|
||||
"""Generate an integration."""
|
||||
print(f"Generating the {info.domain} integration...")
|
||||
integration_dir = COMPONENT_DIR / info.domain
|
||||
test_dir = TESTS_DIR / info.domain
|
||||
|
||||
replaces = {
|
||||
"NEW_DOMAIN": info.domain,
|
||||
"NEW_NAME": info.name,
|
||||
"NEW_CODEOWNER": info.codeowner,
|
||||
# Special case because we need to keep the list empty if there is none.
|
||||
'"MANIFEST_NEW_REQUIREMENT"': (
|
||||
json.dumps(info.requirement) if info.requirement else ""
|
||||
),
|
||||
}
|
||||
|
||||
for src_dir, target_dir in (
|
||||
(TEMPLATE_INTEGRATION, integration_dir),
|
||||
(TEMPLATE_TESTS, test_dir),
|
||||
):
|
||||
# Guard making it for test purposes.
|
||||
if not target_dir.exists():
|
||||
target_dir.mkdir()
|
||||
|
||||
for source_file in src_dir.glob("**/*"):
|
||||
content = source_file.read_text()
|
||||
|
||||
for to_search, to_replace in replaces.items():
|
||||
content = content.replace(to_search, to_replace)
|
||||
|
||||
target_file = target_dir / source_file.relative_to(src_dir)
|
||||
print(f"Writing {target_file}")
|
||||
target_file.write_text(content)
|
||||
def generate(template: str, info: Info) -> None:
|
||||
"""Generate a template."""
|
||||
_validate(template, info)
|
||||
|
||||
print(f"Scaffolding {template} for the {info.domain} integration...")
|
||||
_ensure_tests_dir_exists(info)
|
||||
_generate(TEMPLATE_DIR / template / "integration", info.integration_dir, info)
|
||||
_generate(TEMPLATE_DIR / template / "tests", info.tests_dir, info)
|
||||
_custom_tasks(template, info)
|
||||
print()
|
||||
|
||||
|
||||
def _validate(template, info):
|
||||
"""Validate we can run this task."""
|
||||
if template == "config_flow":
|
||||
if (info.integration_dir / "config_flow.py").exists():
|
||||
raise ExitApp(f"Integration {info.domain} already has a config flow.")
|
||||
|
||||
|
||||
def _generate(src_dir, target_dir, info: Info) -> None:
|
||||
"""Generate an integration."""
|
||||
replaces = {"NEW_DOMAIN": info.domain, "NEW_NAME": info.name}
|
||||
|
||||
if not target_dir.exists():
|
||||
target_dir.mkdir()
|
||||
|
||||
for source_file in src_dir.glob("**/*"):
|
||||
content = source_file.read_text()
|
||||
|
||||
for to_search, to_replace in replaces.items():
|
||||
content = content.replace(to_search, to_replace)
|
||||
|
||||
target_file = target_dir / source_file.relative_to(src_dir)
|
||||
print(f"Writing {target_file}")
|
||||
target_file.write_text(content)
|
||||
|
||||
|
||||
def _ensure_tests_dir_exists(info: Info) -> None:
|
||||
"""Ensure a test dir exists."""
|
||||
if info.tests_dir.exists():
|
||||
return
|
||||
|
||||
info.tests_dir.mkdir()
|
||||
print(f"Writing {info.tests_dir / '__init__.py'}")
|
||||
(info.tests_dir / "__init__.py").write_text(
|
||||
f'"""Tests for the {info.name} integration."""\n'
|
||||
)
|
||||
|
||||
|
||||
def _custom_tasks(template, info) -> None:
|
||||
"""Handle custom tasks for templates."""
|
||||
if template == "integration":
|
||||
changes = {"codeowners": [info.codeowner]}
|
||||
|
||||
if info.requirement:
|
||||
changes["requirements"] = [info.requirement]
|
||||
|
||||
info.update_manifest(**changes)
|
||||
|
||||
if template == "config_flow":
|
||||
info.update_manifest(config_flow=True)
|
||||
info.update_strings(
|
||||
config={
|
||||
"title": info.name,
|
||||
"step": {
|
||||
"user": {"title": "Connect to the device", "data": {"host": "Host"}}
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect, please try again",
|
||||
"invalid_auth": "Invalid authentication",
|
||||
"unknown": "Unexpected error",
|
||||
},
|
||||
"abort": {"already_configured": "Device is already configured"},
|
||||
}
|
||||
)
|
||||
|
||||
if template == "config_flow_discovery":
|
||||
info.update_manifest(config_flow=True)
|
||||
info.update_strings(
|
||||
config={
|
||||
"title": info.name,
|
||||
"step": {
|
||||
"confirm": {
|
||||
"title": info.name,
|
||||
"description": f"Do you want to set up {info.name}?",
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": f"Only a single configuration of {info.name} is possible.",
|
||||
"no_devices_found": f"No {info.name} devices found on the network.",
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
if template in ("config_flow", "config_flow_discovery"):
|
||||
init_file = info.integration_dir / "__init__.py"
|
||||
init_file.write_text(
|
||||
init_file.read_text()
|
||||
+ """
|
||||
|
||||
async def async_setup_entry(hass, entry):
|
||||
\"\"\"Set up a config entry for NEW_NAME.\"\"\"
|
||||
# TODO forward the entry for each platform that you want to set up.
|
||||
# hass.async_create_task(
|
||||
# hass.config_entries.async_forward_entry_setup(entry, "media_player")
|
||||
# )
|
||||
|
||||
return True
|
||||
"""
|
||||
)
|
||||
|
Reference in New Issue
Block a user