Coverage for rendercv/data/models/rendercv_settings.py: 100%
42 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-26 00:25 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-01-26 00:25 +0000
1"""
2The `rendercv.models.rendercv_settings` module contains the data model of the
3`rendercv_settings` field of the input file.
4"""
6import datetime
7import pathlib
8from typing import Optional
10import pydantic
12from .base import RenderCVBaseModelWithoutExtraKeys
13from .computers import convert_string_to_path, replace_placeholders
15file_path_placeholder_description = (
16 "The following placeholders can be used:\n- FULL_MONTH_NAME: Full name of the"
17 " month\n- MONTH_ABBREVIATION: Abbreviation of the month\n- MONTH: Month as a"
18 " number\n- MONTH_IN_TWO_DIGITS: Month as a number in two digits\n- YEAR: Year as a"
19 " number\n- YEAR_IN_TWO_DIGITS: Year as a number in two digits\n- NAME: The name of"
20 " the CV owner\n- NAME_IN_SNAKE_CASE: The name of the CV owner in snake case\n-"
21 " NAME_IN_LOWER_SNAKE_CASE: The name of the CV owner in lower snake case\n-"
22 " NAME_IN_UPPER_SNAKE_CASE: The name of the CV owner in upper snake case\n-"
23 " NAME_IN_KEBAB_CASE: The name of the CV owner in kebab case\n-"
24 " NAME_IN_LOWER_KEBAB_CASE: The name of the CV owner in lower kebab case\n-"
25 " NAME_IN_UPPER_KEBAB_CASE: The name of the CV owner in upper kebab case\n-"
26 " FULL_MONTH_NAME: Full name of the month\n- MONTH_ABBREVIATION: Abbreviation of"
27 " the month\n- MONTH: Month as a number\n- MONTH_IN_TWO_DIGITS: Month as a number"
28 " in two digits\n- YEAR: Year as a number\n- YEAR_IN_TWO_DIGITS: Year as a number"
29 ' in two digits\nThe default value is "MONTH_ABBREVIATION YEAR".\nThe default value'
30 " is null."
31)
33file_path_placeholder_description_without_default = (
34 file_path_placeholder_description.replace("\nThe default value is null.", "")
35)
37DATE_INPUT = datetime.date.today()
40class RenderCommandSettings(RenderCVBaseModelWithoutExtraKeys):
41 """This class is the data model of the `render` command's settings."""
43 design: Optional[pathlib.Path] = pydantic.Field(
44 default=None,
45 title="`design` Field's YAML File",
46 description=(
47 "The file path to the yaml file containing the `design` field separately."
48 ),
49 )
51 rendercv_settings: Optional[pathlib.Path] = pydantic.Field(
52 default=None,
53 title="`rendercv_settings` Field's YAML File",
54 description=(
55 "The file path to the yaml file containing the `rendercv_settings` field"
56 " separately."
57 ),
58 )
60 locale: Optional[pathlib.Path] = pydantic.Field(
61 default=None,
62 title="`locale` Field's YAML File",
63 description=(
64 "The file path to the yaml file containing the `locale` field separately."
65 ),
66 )
68 output_folder_name: str = pydantic.Field(
69 default="rendercv_output",
70 title="Output Folder Name",
71 description=(
72 "The name of the folder where the output files will be saved."
73 f" {file_path_placeholder_description_without_default}\nThe default value"
74 ' is "rendercv_output".'
75 ),
76 )
78 pdf_path: Optional[pathlib.Path] = pydantic.Field(
79 default=None,
80 title="PDF Path",
81 description=(
82 "The path to copy the PDF file to. If it is not provided, the PDF file will"
83 f" not be copied. {file_path_placeholder_description}"
84 ),
85 )
87 typst_path: Optional[pathlib.Path] = pydantic.Field(
88 default=None,
89 title="Typst Path",
90 description=(
91 "The path to copy the Typst file to. If it is not provided, the Typst file"
92 f" will not be copied. {file_path_placeholder_description}"
93 ),
94 )
96 html_path: Optional[pathlib.Path] = pydantic.Field(
97 default=None,
98 title="HTML Path",
99 description=(
100 "The path to copy the HTML file to. If it is not provided, the HTML file"
101 f" will not be copied. {file_path_placeholder_description}"
102 ),
103 )
105 png_path: Optional[pathlib.Path] = pydantic.Field(
106 default=None,
107 title="PNG Path",
108 description=(
109 "The path to copy the PNG file to. If it is not provided, the PNG file will"
110 f" not be copied. {file_path_placeholder_description}"
111 ),
112 )
114 markdown_path: Optional[pathlib.Path] = pydantic.Field(
115 default=None,
116 title="Markdown Path",
117 description=(
118 "The path to copy the Markdown file to. If it is not provided, the Markdown"
119 f" file will not be copied. {file_path_placeholder_description}"
120 ),
121 )
123 dont_generate_html: bool = pydantic.Field(
124 default=False,
125 title="Don't Generate HTML",
126 description=(
127 "A boolean value to determine whether the HTML file will be generated. The"
128 " default value is False."
129 ),
130 )
132 dont_generate_markdown: bool = pydantic.Field(
133 default=False,
134 title="Don't Generate Markdown",
135 description=(
136 "A boolean value to determine whether the Markdown file will be generated."
137 ' The default value is "false".'
138 ),
139 )
141 dont_generate_png: bool = pydantic.Field(
142 default=False,
143 title="Don't Generate PNG",
144 description=(
145 "A boolean value to determine whether the PNG file will be generated. The"
146 " default value is False."
147 ),
148 )
150 watch: bool = pydantic.Field(
151 default=False,
152 title="Re-run RenderCV When the Input File is Updated",
153 description=(
154 "A boolean value to determine whether to re-run RenderCV when the input"
155 'file is updated. The default value is "false".'
156 ),
157 )
159 @pydantic.field_validator(
160 "output_folder_name",
161 mode="before",
162 )
163 @classmethod
164 def replace_placeholders(cls, value: str) -> str:
165 """Replaces the placeholders in a string with the corresponding values."""
166 return replace_placeholders(value)
168 @pydantic.field_validator(
169 "design",
170 "locale",
171 "rendercv_settings",
172 "pdf_path",
173 "typst_path",
174 "html_path",
175 "png_path",
176 "markdown_path",
177 mode="before",
178 )
179 @classmethod
180 def convert_string_to_path(cls, value: Optional[str]) -> Optional[pathlib.Path]:
181 """Converts a string to a `pathlib.Path` object by replacing the placeholders
182 with the corresponding values. If the path is not an absolute path, it is
183 converted to an absolute path by prepending the current working directory.
184 """
185 if value is None:
186 return None
188 return convert_string_to_path(value)
191class RenderCVSettings(RenderCVBaseModelWithoutExtraKeys):
192 """This class is the data model of the RenderCV settings."""
194 date: datetime.date = pydantic.Field(
195 default=datetime.date.today(),
196 title="Date",
197 description=(
198 "The date that will be used everywhere (e.g., in the output file names,"
199 " last updated date, computation of time spans for the events that are"
200 " currently happening, etc.). The default value is the current date."
201 ),
202 json_schema_extra={
203 "default": None,
204 },
205 )
206 render_command: Optional[RenderCommandSettings] = pydantic.Field(
207 default=None,
208 title="Render Command Settings",
209 description=(
210 "RenderCV's `render` command settings. They are the same as the command"
211 " line arguments. CLI arguments have higher priority than the settings in"
212 " the input file."
213 ),
214 )
215 bold_keywords: list[str] = pydantic.Field(
216 default=[],
217 title="Bold Keywords",
218 description=(
219 "The keywords that will be bold in the output. The default value is an"
220 " empty list."
221 ),
222 )
224 @pydantic.field_validator("date")
225 @classmethod
226 def mock_today(cls, value: datetime.date) -> datetime.date:
227 """Mocks the current date for testing."""
229 global DATE_INPUT # NOQA: PLW0603
231 DATE_INPUT = value
233 return value