Coverage for src / rendercv / cli / create_theme_command / create_init_file_for_theme.py: 100%
12 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-25 13:49 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-03-25 13:49 +0000
1import pathlib
3from rendercv.exception import RenderCVUserError
4from rendercv.schema.models.design.design import custom_theme_name_pattern
7def create_init_file_for_theme(theme_name: str, init_file_path: pathlib.Path) -> None:
8 """Generate `__init__.py` for custom theme by templating from ClassicTheme.
10 Why:
11 Custom themes need Pydantic models defining design options. Generating
12 from ClassicTheme provides working example with all standard fields
13 users can modify or extend.
15 Args:
16 theme_name: Snake_case theme identifier.
17 init_file_path: Destination path for __init__.py.
18 """
19 if not custom_theme_name_pattern.match(theme_name):
20 message = (
21 "The custom theme name should only contain lowercase letters and digits."
22 f" The provided value is `{theme_name}`."
23 )
24 raise RenderCVUserError(message)
26 classic_theme_file = (
27 pathlib.Path(__file__).parent.parent.parent
28 / "schema"
29 / "models"
30 / "design"
31 / "classic_theme.py"
32 )
33 new_init_file_contents = classic_theme_file.read_text(encoding="utf-8")
35 new_init_file_contents = new_init_file_contents.replace(
36 "class ClassicTheme(BaseModelWithoutExtraKeys):",
37 f"class {theme_name.capitalize()}Theme(BaseModelWithoutExtraKeys):",
38 )
39 new_init_file_contents = new_init_file_contents.replace(
40 'theme: Literal["classic"] = "classic"',
41 f'theme: Literal["{theme_name}"] = "{theme_name}"',
42 )
43 init_file_path.write_text(new_init_file_contents, encoding="utf-8")