zrb 0.0.86__py3-none-any.whl → 0.0.88__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (121) hide show
  1. zrb/__init__.py +3 -1
  2. zrb/action/runner.py +7 -3
  3. zrb/builtin/__init__.py +1 -1
  4. zrb/builtin/base64.py +1 -1
  5. zrb/builtin/devtool/devtool_install.py +13 -4
  6. zrb/builtin/devtool/helix/install-language-server.sh +33 -0
  7. zrb/builtin/env.py +6 -3
  8. zrb/builtin/explain.py +3 -1
  9. zrb/builtin/generator/__init__.py +4 -8
  10. zrb/builtin/generator/app_generator/add.py +15 -6
  11. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/add.py +62 -52
  12. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/_automate/snake_zrb_app_name/cmd/app-start.sh +1 -6
  13. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/_automate/snake_zrb_app_name/container.py +1 -1
  14. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/_automate/snake_zrb_app_name/deployment.py +2 -2
  15. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/_automate/snake_zrb_app_name/image.py +1 -1
  16. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/_automate/snake_zrb_app_name/local.py +4 -2
  17. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/src/kebab-zrb-app-name/src/.gitignore +2 -0
  18. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/src/kebab-zrb-app-name/src/Dockerfile +10 -5
  19. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/src/kebab-zrb-app-name/src/go.work +1 -0
  20. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/src/kebab-zrb-app-name/src/main.go +28 -0
  21. zrb/builtin/generator/cmd_task/add.py +6 -6
  22. zrb/builtin/generator/cmd_task/template/_automate/snake_zrb_task_name.py +1 -1
  23. zrb/builtin/generator/{_common → common}/helper.py +6 -0
  24. zrb/builtin/generator/{_common → common}/task_factory.py +9 -5
  25. zrb/builtin/generator/docker_compose_task/add.py +8 -8
  26. zrb/builtin/generator/docker_compose_task/template/_automate/snake_zrb_task_name.py +1 -1
  27. zrb/builtin/generator/fastapp/add.py +24 -24
  28. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/_common.py +2 -1
  29. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/container.py +1 -1
  30. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/deployment.py +1 -1
  31. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/frontend.py +1 -1
  32. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/image.py +1 -1
  33. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/load_test.py +3 -2
  34. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/local.py +1 -1
  35. zrb/builtin/generator/fastapp/template/_automate/snake_zrb_app_name/test.py +2 -4
  36. zrb/builtin/generator/fastapp_crud/add.py +8 -121
  37. zrb/builtin/generator/fastapp_crud/helper.py +115 -0
  38. zrb/builtin/generator/fastapp_crud/{add_navigation.py → task_factory.py} +5 -3
  39. zrb/builtin/generator/fastapp_field/add.py +8 -280
  40. zrb/builtin/generator/fastapp_field/helper.py +283 -0
  41. zrb/builtin/generator/fastapp_module/add.py +19 -328
  42. zrb/builtin/generator/fastapp_module/helper.py +326 -0
  43. zrb/builtin/generator/pip_package/add.py +8 -8
  44. zrb/builtin/generator/pip_package/template/_automate/snake_zrb_package_name/local.py +1 -1
  45. zrb/builtin/generator/project/create.py +10 -3
  46. zrb/builtin/generator/project/template/template.env +1 -1
  47. zrb/builtin/generator/project_task/task_factory.py +33 -21
  48. zrb/builtin/generator/project_task/template/_automate/_project/build_project_images.py +1 -1
  49. zrb/builtin/generator/project_task/template/_automate/_project/deploy_project.py +1 -1
  50. zrb/builtin/generator/project_task/template/_automate/_project/destroy_project.py +1 -1
  51. zrb/builtin/generator/project_task/template/_automate/_project/push_project_images.py +1 -1
  52. zrb/builtin/generator/project_task/template/_automate/_project/remove_project_containers.py +1 -1
  53. zrb/builtin/generator/project_task/template/_automate/_project/start_project.py +1 -1
  54. zrb/builtin/generator/project_task/template/_automate/_project/start_project_containers.py +1 -1
  55. zrb/builtin/generator/project_task/template/_automate/_project/stop_project_containers.py +1 -1
  56. zrb/builtin/generator/python_task/add.py +6 -6
  57. zrb/builtin/generator/python_task/template/_automate/snake_zrb_task_name.py +1 -1
  58. zrb/builtin/generator/simple_python_app/add.py +28 -30
  59. zrb/builtin/generator/simple_python_app/template/_automate/snake_zrb_app_name/container.py +1 -1
  60. zrb/builtin/generator/simple_python_app/template/_automate/snake_zrb_app_name/deployment.py +1 -1
  61. zrb/builtin/generator/simple_python_app/template/_automate/snake_zrb_app_name/image.py +1 -1
  62. zrb/builtin/generator/simple_python_app/template/_automate/snake_zrb_app_name/local.py +1 -1
  63. zrb/builtin/git.py +1 -1
  64. zrb/builtin/md5.py +1 -1
  65. zrb/builtin/project.py +1 -1
  66. zrb/builtin/ubuntu.py +3 -3
  67. zrb/config/config.py +8 -6
  68. zrb/helper/accessories/color.py +5 -1
  69. zrb/helper/accessories/icon.py +2 -0
  70. zrb/helper/accessories/name.py +2 -0
  71. zrb/helper/advertisement.py +1 -0
  72. zrb/helper/cli.py +5 -1
  73. zrb/helper/codemod/add_argument_to_function.py +3 -0
  74. zrb/helper/codemod/add_argument_to_function_call.py +3 -0
  75. zrb/helper/codemod/add_assert_resource.py +2 -0
  76. zrb/helper/codemod/add_function_call.py +2 -0
  77. zrb/helper/codemod/add_import_module.py +3 -0
  78. zrb/helper/codemod/add_key_value_to_dict.py +2 -0
  79. zrb/helper/codemod/add_property_to_class.py +3 -0
  80. zrb/helper/codemod/add_upstream_to_task.py +3 -0
  81. zrb/helper/codemod/append_code_to_function.py +3 -0
  82. zrb/helper/codemod/format_code.py +2 -0
  83. zrb/helper/default_env.py +2 -0
  84. zrb/helper/docker_compose/fetch_external_env.py +3 -0
  85. zrb/helper/docker_compose/file.py +4 -0
  86. zrb/helper/env_map/fetch.py +7 -0
  87. zrb/helper/file/text.py +4 -0
  88. zrb/helper/git/detect_changes.py +4 -0
  89. zrb/helper/loader/load_module.py +2 -0
  90. zrb/helper/map/conversion.py +2 -0
  91. zrb/helper/string/conversion.py +5 -0
  92. zrb/helper/string/double_quote.py +6 -2
  93. zrb/helper/string/jinja.py +2 -0
  94. zrb/helper/string/parse_replacement.py +2 -0
  95. zrb/helper/util.py +13 -0
  96. zrb/task/any_task.py +2 -2
  97. zrb/task/base_task.py +15 -15
  98. zrb/task/base_task_composite.py +3 -3
  99. zrb/task/cmd_task.py +2 -2
  100. zrb/task/decorator.py +2 -2
  101. zrb/task/docker_compose_task.py +2 -2
  102. zrb/task/flow_task.py +5 -5
  103. zrb/task/http_checker.py +2 -2
  104. zrb/task/path_checker.py +2 -2
  105. zrb/task/port_checker.py +2 -2
  106. zrb/task/resource_maker.py +3 -5
  107. zrb/task_input/any_input.py +23 -0
  108. zrb/task_input/base_input.py +46 -43
  109. zrb/task_input/float_input.py +0 -1
  110. {zrb-0.0.86.dist-info → zrb-0.0.88.dist-info}/METADATA +1 -1
  111. {zrb-0.0.86.dist-info → zrb-0.0.88.dist-info}/RECORD +118 -114
  112. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/src/kebab-zrb-app-name/src/main.py +0 -20
  113. zrb/builtin/generator/app_generator/template/_automate/snake_zrb_meta_template_name/template/src/kebab-zrb-app-name/src/requirements.txt +0 -1
  114. zrb/config.toml +0 -0
  115. /zrb/builtin/generator/{_common → common}/__init__.py +0 -0
  116. /zrb/builtin/generator/{_common → common}/task_input.py +0 -0
  117. /zrb/builtin/{_group.py → group.py} +0 -0
  118. /zrb/task_input/{_constant.py → constant.py} +0 -0
  119. {zrb-0.0.86.dist-info → zrb-0.0.88.dist-info}/LICENSE +0 -0
  120. {zrb-0.0.86.dist-info → zrb-0.0.88.dist-info}/WHEEL +0 -0
  121. {zrb-0.0.86.dist-info → zrb-0.0.88.dist-info}/entry_points.txt +0 -0
@@ -1,21 +1,22 @@
1
1
  from typing import Any
2
- from .._common.task_input import (
2
+ from .helper import (
3
+ add_column_to_delete_page, add_column_to_detail_page,
4
+ add_column_to_insert_page, add_column_to_list_page, add_column_to_repo,
5
+ add_column_to_schema, add_column_to_test, add_column_to_update_page
6
+ )
7
+ from ..common.task_input import (
3
8
  project_dir_input, app_name_input, module_name_input, entity_name_input,
4
9
  column_name_input, column_type_input
5
10
  )
6
- from .._common.helper import validate_existing_project_dir
7
- from ..._group import project_add_group
11
+ from ..common.helper import validate_existing_project_dir
12
+ from ...group import project_add_group
8
13
  from ....task.task import Task
9
14
  from ....task.decorator import python_task
10
15
  from ....runner import runner
11
16
  from ....helper import util
12
- from ....helper.codemod.add_property_to_class import add_property_to_class
13
- from ....helper.codemod.add_key_value_to_dict import add_key_value_to_dict
14
- from ....helper.file.text import read_text_file_async, write_text_file_async
15
17
 
16
18
  import asyncio
17
19
  import os
18
- import re
19
20
 
20
21
  CURRENT_DIR = os.path.dirname(__file__)
21
22
 
@@ -135,276 +136,3 @@ async def add_fastapp_field(*args: Any, **kwargs: Any):
135
136
  )),
136
137
  )
137
138
  task.print_out('Success')
138
-
139
-
140
- ###############################################################################
141
- # Helper Definitions
142
- ###############################################################################
143
-
144
-
145
- async def add_column_to_insert_page(
146
- task: Task,
147
- project_dir: str,
148
- kebab_app_name: str,
149
- kebab_module_name: str,
150
- kebab_entity_name: str,
151
- kebab_column_name: str,
152
- snake_column_name: str,
153
- capitalized_human_readable_column_name: str
154
- ):
155
- list_page_file_path = os.path.join(
156
- project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
157
- kebab_module_name, kebab_entity_name, 'new', '+page.svelte'
158
- )
159
- task.print_out(f'Read HTML from: {list_page_file_path}')
160
- html_content = await read_text_file_async(list_page_file_path)
161
- task.print_out('Add default value to insert page')
162
- default_value_regex = r"(.*)(// DON'T DELETE: set field default value here)" # noqa
163
- default_value_subst = '\\n'.join([
164
- f"\\1row.{snake_column_name} = '';",
165
- '\\1\\2'
166
- ])
167
- html_content = re.sub(
168
- default_value_regex, default_value_subst, html_content, 0, re.MULTILINE
169
- )
170
- task.print_out('Add field to insert page')
171
- field_regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
172
- field_subst = '\\n'.join([
173
- '\\1<div class="mb-4">',
174
- f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
175
- f'\\1 <input type="text" class="input w-full" id="{kebab_column_name}" placeholder="{capitalized_human_readable_column_name}" bind:value=' + '{row.' + snake_column_name + '} />', # noqa
176
- '\\1</div>',
177
- '\\1\\2'
178
- ])
179
- html_content = re.sub(
180
- field_regex, field_subst, html_content, 0, re.MULTILINE
181
- )
182
- task.print_out(f'Write modified HTML to: {list_page_file_path}')
183
- await write_text_file_async(list_page_file_path, html_content)
184
-
185
-
186
- async def add_column_to_update_page(
187
- task: Task,
188
- project_dir: str,
189
- kebab_app_name: str,
190
- kebab_module_name: str,
191
- kebab_entity_name: str,
192
- kebab_column_name: str,
193
- snake_column_name: str,
194
- capitalized_human_readable_column_name: str
195
- ):
196
- list_page_file_path = os.path.join(
197
- project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
198
- kebab_module_name, kebab_entity_name, 'update', '[id]', '+page.svelte'
199
- )
200
- task.print_out(f'Read HTML from: {list_page_file_path}')
201
- html_content = await read_text_file_async(list_page_file_path)
202
- task.print_out('Add field to update page')
203
- regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
204
- subst = '\\n'.join([
205
- '\\1<div class="mb-4">',
206
- f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
207
- f'\\1 <input type="text" class="input w-full" id="{kebab_column_name}" placeholder="{capitalized_human_readable_column_name}" bind:value=' + '{row.' + snake_column_name + '} />', # noqa
208
- '\\1</div>',
209
- '\\1\\2'
210
- ])
211
- html_content = re.sub(
212
- regex, subst, html_content, 0, re.MULTILINE
213
- )
214
- task.print_out(f'Write modified HTML to: {list_page_file_path}')
215
- await write_text_file_async(list_page_file_path, html_content)
216
-
217
-
218
- async def add_column_to_delete_page(
219
- task: Task,
220
- project_dir: str,
221
- kebab_app_name: str,
222
- kebab_module_name: str,
223
- kebab_entity_name: str,
224
- kebab_column_name: str,
225
- snake_column_name: str,
226
- capitalized_human_readable_column_name: str
227
- ):
228
- list_page_file_path = os.path.join(
229
- project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
230
- kebab_module_name, kebab_entity_name, 'delete', '[id]', '+page.svelte'
231
- )
232
- task.print_out(f'Read HTML from: {list_page_file_path}')
233
- html_content = await read_text_file_async(list_page_file_path)
234
- task.print_out('Add field to delete page')
235
- regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
236
- subst = '\\n'.join([
237
- '\\1<div class="mb-4">',
238
- f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
239
- f'\\1 <span id="{kebab_column_name}">' + '{row.' + snake_column_name + '}</span>', # noqa
240
- '\\1</div>',
241
- '\\1\\2'
242
- ])
243
- html_content = re.sub(
244
- regex, subst, html_content, 0, re.MULTILINE
245
- )
246
- task.print_out(f'Write modified HTML to: {list_page_file_path}')
247
- await write_text_file_async(list_page_file_path, html_content)
248
-
249
-
250
- async def add_column_to_detail_page(
251
- task: Task,
252
- project_dir: str,
253
- kebab_app_name: str,
254
- kebab_module_name: str,
255
- kebab_entity_name: str,
256
- kebab_column_name: str,
257
- snake_column_name: str,
258
- capitalized_human_readable_column_name: str
259
- ):
260
- list_page_file_path = os.path.join(
261
- project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
262
- kebab_module_name, kebab_entity_name, 'detail', '[id]', '+page.svelte'
263
- )
264
- task.print_out(f'Read HTML from: {list_page_file_path}')
265
- html_content = await read_text_file_async(list_page_file_path)
266
- task.print_out('Add field to detail page')
267
- regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
268
- subst = '\\n'.join([
269
- '\\1<div class="mb-4">',
270
- f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
271
- f'\\1 <span id="{kebab_column_name}">' + '{row.' + snake_column_name + '}</span>', # noqa
272
- '\\1</div>',
273
- '\\1\\2'
274
- ])
275
- html_content = re.sub(
276
- regex, subst, html_content, 0, re.MULTILINE
277
- )
278
- task.print_out(f'Write modified HTML to: {list_page_file_path}')
279
- await write_text_file_async(list_page_file_path, html_content)
280
-
281
-
282
- async def add_column_to_list_page(
283
- task: Task,
284
- project_dir: str,
285
- kebab_app_name: str,
286
- kebab_module_name: str,
287
- kebab_entity_name: str,
288
- snake_column_name: str,
289
- capitalized_human_readable_column_name: str
290
- ):
291
- list_page_file_path = os.path.join(
292
- project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
293
- kebab_module_name, kebab_entity_name, '+page.svelte'
294
- )
295
- task.print_out(f'Read HTML from: {list_page_file_path}')
296
- html_content = await read_text_file_async(list_page_file_path)
297
- # process header
298
- task.print_out('Add column header to table')
299
- header_regex = r"(.*)(<!-- DON'T DELETE: insert new column header here-->)"
300
- header_subst = '\\n'.join([
301
- f'\\1<th>{capitalized_human_readable_column_name}</th>',
302
- '\\1\\2'
303
- ])
304
- html_content = re.sub(
305
- header_regex, header_subst, html_content, 0, re.MULTILINE
306
- )
307
- # process column
308
- task.print_out('Add column to table')
309
- column_regex = r"(.*)(<!-- DON'T DELETE: insert new column here-->)"
310
- column_subst = '\\n'.join([
311
- '\\1<td>{row.' + snake_column_name + '}</td>',
312
- '\\1\\2'
313
- ])
314
- html_content = re.sub(
315
- column_regex, column_subst, html_content, 0, re.MULTILINE
316
- )
317
- task.print_out(f'Write modified HTML to: {list_page_file_path}')
318
- await write_text_file_async(list_page_file_path, html_content)
319
-
320
-
321
- async def add_column_to_test(
322
- task: Task,
323
- project_dir: str,
324
- kebab_app_name: str,
325
- snake_module_name: str,
326
- snake_entity_name: str,
327
- snake_column_name: str,
328
- column_type: str
329
- ):
330
- test_file_path = os.path.join(
331
- project_dir, 'src', kebab_app_name, 'test', snake_module_name,
332
- f'test_{snake_entity_name}.py'
333
- )
334
- task.print_out(f'Read code from: {test_file_path}')
335
- code = await read_text_file_async(test_file_path)
336
- task.print_out(
337
- f'Add column "{snake_column_name}" to the test'
338
- )
339
- dict_names = [
340
- 'inserted_success_data', 'to_be_updated_success_data',
341
- 'updated_success_data', 'to_be_deleted_success_data'
342
- ]
343
- for dict_name in dict_names:
344
- code = add_key_value_to_dict(
345
- code=code,
346
- dict_name=dict_name,
347
- key=f"'{snake_column_name}'",
348
- value="''"
349
- )
350
- task.print_out(f'Write modified code to: {test_file_path}')
351
- await write_text_file_async(test_file_path, code)
352
-
353
-
354
- async def add_column_to_schema(
355
- task: Task,
356
- project_dir: str,
357
- kebab_app_name: str,
358
- snake_module_name: str,
359
- snake_entity_name: str,
360
- pascal_entity_name: str,
361
- snake_column_name: str,
362
- column_type: str
363
- ):
364
- schema_file_path = os.path.join(
365
- project_dir, 'src', kebab_app_name, 'src', 'module', snake_module_name,
366
- 'schema', f'{snake_entity_name}.py'
367
- )
368
- task.print_out(f'Read code from: {schema_file_path}')
369
- code = await read_text_file_async(schema_file_path)
370
- task.print_out(
371
- f'Add column "{snake_column_name}" to the schema'
372
- )
373
- code = add_property_to_class(
374
- code=code,
375
- class_name=f'{pascal_entity_name}Data',
376
- property_name=snake_column_name,
377
- property_type='str'
378
- )
379
- task.print_out(f'Write modified code to: {schema_file_path}')
380
- await write_text_file_async(schema_file_path, code)
381
-
382
-
383
- async def add_column_to_repo(
384
- task: Task,
385
- project_dir: str,
386
- kebab_app_name: str,
387
- snake_module_name: str,
388
- snake_entity_name: str,
389
- pascal_entity_name: str,
390
- snake_column_name: str,
391
- column_type: str
392
- ):
393
- repo_file_path = os.path.join(
394
- project_dir, 'src', kebab_app_name, 'src', 'module', snake_module_name,
395
- 'entity', snake_entity_name, 'repo.py'
396
- )
397
- task.print_out(f'Read code from: {repo_file_path}')
398
- code = await read_text_file_async(repo_file_path)
399
- task.print_out(
400
- f'Add column "{snake_column_name}" to the repo'
401
- )
402
- code = add_property_to_class(
403
- code=code,
404
- class_name=f'DBEntity{pascal_entity_name}',
405
- property_name=snake_column_name,
406
- property_type='Column',
407
- property_value='Column(String)'
408
- )
409
- task.print_out(f'Write modified code to: {repo_file_path}')
410
- await write_text_file_async(repo_file_path, code)
@@ -0,0 +1,283 @@
1
+ from typeguard import typechecked
2
+ from ....task.task import Task
3
+ from ....helper.codemod.add_property_to_class import add_property_to_class
4
+ from ....helper.codemod.add_key_value_to_dict import add_key_value_to_dict
5
+ from ....helper.file.text import read_text_file_async, write_text_file_async
6
+ import os
7
+ import re
8
+
9
+
10
+ @typechecked
11
+ async def add_column_to_insert_page(
12
+ task: Task,
13
+ project_dir: str,
14
+ kebab_app_name: str,
15
+ kebab_module_name: str,
16
+ kebab_entity_name: str,
17
+ kebab_column_name: str,
18
+ snake_column_name: str,
19
+ capitalized_human_readable_column_name: str
20
+ ):
21
+ list_page_file_path = os.path.join(
22
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
23
+ kebab_module_name, kebab_entity_name, 'new', '+page.svelte'
24
+ )
25
+ task.print_out(f'Read HTML from: {list_page_file_path}')
26
+ html_content = await read_text_file_async(list_page_file_path)
27
+ task.print_out('Add default value to insert page')
28
+ default_value_regex = r"(.*)(// DON'T DELETE: set field default value here)" # noqa
29
+ default_value_subst = '\\n'.join([
30
+ f"\\1row.{snake_column_name} = '';",
31
+ '\\1\\2'
32
+ ])
33
+ html_content = re.sub(
34
+ default_value_regex, default_value_subst, html_content, 0, re.MULTILINE
35
+ )
36
+ task.print_out('Add field to insert page')
37
+ field_regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
38
+ field_subst = '\\n'.join([
39
+ '\\1<div class="mb-4">',
40
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
41
+ f'\\1 <input type="text" class="input w-full" id="{kebab_column_name}" placeholder="{capitalized_human_readable_column_name}" bind:value=' + '{row.' + snake_column_name + '} />', # noqa
42
+ '\\1</div>',
43
+ '\\1\\2'
44
+ ])
45
+ html_content = re.sub(
46
+ field_regex, field_subst, html_content, 0, re.MULTILINE
47
+ )
48
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
49
+ await write_text_file_async(list_page_file_path, html_content)
50
+
51
+
52
+ @typechecked
53
+ async def add_column_to_update_page(
54
+ task: Task,
55
+ project_dir: str,
56
+ kebab_app_name: str,
57
+ kebab_module_name: str,
58
+ kebab_entity_name: str,
59
+ kebab_column_name: str,
60
+ snake_column_name: str,
61
+ capitalized_human_readable_column_name: str
62
+ ):
63
+ list_page_file_path = os.path.join(
64
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
65
+ kebab_module_name, kebab_entity_name, 'update', '[id]', '+page.svelte'
66
+ )
67
+ task.print_out(f'Read HTML from: {list_page_file_path}')
68
+ html_content = await read_text_file_async(list_page_file_path)
69
+ task.print_out('Add field to update page')
70
+ regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
71
+ subst = '\\n'.join([
72
+ '\\1<div class="mb-4">',
73
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
74
+ f'\\1 <input type="text" class="input w-full" id="{kebab_column_name}" placeholder="{capitalized_human_readable_column_name}" bind:value=' + '{row.' + snake_column_name + '} />', # noqa
75
+ '\\1</div>',
76
+ '\\1\\2'
77
+ ])
78
+ html_content = re.sub(
79
+ regex, subst, html_content, 0, re.MULTILINE
80
+ )
81
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
82
+ await write_text_file_async(list_page_file_path, html_content)
83
+
84
+
85
+ @typechecked
86
+ async def add_column_to_delete_page(
87
+ task: Task,
88
+ project_dir: str,
89
+ kebab_app_name: str,
90
+ kebab_module_name: str,
91
+ kebab_entity_name: str,
92
+ kebab_column_name: str,
93
+ snake_column_name: str,
94
+ capitalized_human_readable_column_name: str
95
+ ):
96
+ list_page_file_path = os.path.join(
97
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
98
+ kebab_module_name, kebab_entity_name, 'delete', '[id]', '+page.svelte'
99
+ )
100
+ task.print_out(f'Read HTML from: {list_page_file_path}')
101
+ html_content = await read_text_file_async(list_page_file_path)
102
+ task.print_out('Add field to delete page')
103
+ regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
104
+ subst = '\\n'.join([
105
+ '\\1<div class="mb-4">',
106
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
107
+ f'\\1 <span id="{kebab_column_name}">' + '{row.' + snake_column_name + '}</span>', # noqa
108
+ '\\1</div>',
109
+ '\\1\\2'
110
+ ])
111
+ html_content = re.sub(
112
+ regex, subst, html_content, 0, re.MULTILINE
113
+ )
114
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
115
+ await write_text_file_async(list_page_file_path, html_content)
116
+
117
+
118
+ @typechecked
119
+ async def add_column_to_detail_page(
120
+ task: Task,
121
+ project_dir: str,
122
+ kebab_app_name: str,
123
+ kebab_module_name: str,
124
+ kebab_entity_name: str,
125
+ kebab_column_name: str,
126
+ snake_column_name: str,
127
+ capitalized_human_readable_column_name: str
128
+ ):
129
+ list_page_file_path = os.path.join(
130
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
131
+ kebab_module_name, kebab_entity_name, 'detail', '[id]', '+page.svelte'
132
+ )
133
+ task.print_out(f'Read HTML from: {list_page_file_path}')
134
+ html_content = await read_text_file_async(list_page_file_path)
135
+ task.print_out('Add field to detail page')
136
+ regex = r"(.*)(<!-- DON'T DELETE: insert new field here-->)"
137
+ subst = '\\n'.join([
138
+ '\\1<div class="mb-4">',
139
+ f'\\1 <label class="block text-gray-700 font-bold mb-2" for="{kebab_column_name}">{capitalized_human_readable_column_name}</label>', # noqa
140
+ f'\\1 <span id="{kebab_column_name}">' + '{row.' + snake_column_name + '}</span>', # noqa
141
+ '\\1</div>',
142
+ '\\1\\2'
143
+ ])
144
+ html_content = re.sub(
145
+ regex, subst, html_content, 0, re.MULTILINE
146
+ )
147
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
148
+ await write_text_file_async(list_page_file_path, html_content)
149
+
150
+
151
+ @typechecked
152
+ async def add_column_to_list_page(
153
+ task: Task,
154
+ project_dir: str,
155
+ kebab_app_name: str,
156
+ kebab_module_name: str,
157
+ kebab_entity_name: str,
158
+ snake_column_name: str,
159
+ capitalized_human_readable_column_name: str
160
+ ):
161
+ list_page_file_path = os.path.join(
162
+ project_dir, 'src', kebab_app_name, 'src', 'frontend', 'src', 'routes',
163
+ kebab_module_name, kebab_entity_name, '+page.svelte'
164
+ )
165
+ task.print_out(f'Read HTML from: {list_page_file_path}')
166
+ html_content = await read_text_file_async(list_page_file_path)
167
+ # process header
168
+ task.print_out('Add column header to table')
169
+ header_regex = r"(.*)(<!-- DON'T DELETE: insert new column header here-->)"
170
+ header_subst = '\\n'.join([
171
+ f'\\1<th>{capitalized_human_readable_column_name}</th>',
172
+ '\\1\\2'
173
+ ])
174
+ html_content = re.sub(
175
+ header_regex, header_subst, html_content, 0, re.MULTILINE
176
+ )
177
+ # process column
178
+ task.print_out('Add column to table')
179
+ column_regex = r"(.*)(<!-- DON'T DELETE: insert new column here-->)"
180
+ column_subst = '\\n'.join([
181
+ '\\1<td>{row.' + snake_column_name + '}</td>',
182
+ '\\1\\2'
183
+ ])
184
+ html_content = re.sub(
185
+ column_regex, column_subst, html_content, 0, re.MULTILINE
186
+ )
187
+ task.print_out(f'Write modified HTML to: {list_page_file_path}')
188
+ await write_text_file_async(list_page_file_path, html_content)
189
+
190
+
191
+ @typechecked
192
+ async def add_column_to_test(
193
+ task: Task,
194
+ project_dir: str,
195
+ kebab_app_name: str,
196
+ snake_module_name: str,
197
+ snake_entity_name: str,
198
+ snake_column_name: str,
199
+ column_type: str
200
+ ):
201
+ test_file_path = os.path.join(
202
+ project_dir, 'src', kebab_app_name, 'test', snake_module_name,
203
+ f'test_{snake_entity_name}.py'
204
+ )
205
+ task.print_out(f'Read code from: {test_file_path}')
206
+ code = await read_text_file_async(test_file_path)
207
+ task.print_out(
208
+ f'Add column "{snake_column_name}" to the test'
209
+ )
210
+ dict_names = [
211
+ 'inserted_success_data', 'to_be_updated_success_data',
212
+ 'updated_success_data', 'to_be_deleted_success_data'
213
+ ]
214
+ for dict_name in dict_names:
215
+ code = add_key_value_to_dict(
216
+ code=code,
217
+ dict_name=dict_name,
218
+ key=f"'{snake_column_name}'",
219
+ value="''"
220
+ )
221
+ task.print_out(f'Write modified code to: {test_file_path}')
222
+ await write_text_file_async(test_file_path, code)
223
+
224
+
225
+ @typechecked
226
+ async def add_column_to_schema(
227
+ task: Task,
228
+ project_dir: str,
229
+ kebab_app_name: str,
230
+ snake_module_name: str,
231
+ snake_entity_name: str,
232
+ pascal_entity_name: str,
233
+ snake_column_name: str,
234
+ column_type: str
235
+ ):
236
+ schema_file_path = os.path.join(
237
+ project_dir, 'src', kebab_app_name, 'src', 'module', snake_module_name,
238
+ 'schema', f'{snake_entity_name}.py'
239
+ )
240
+ task.print_out(f'Read code from: {schema_file_path}')
241
+ code = await read_text_file_async(schema_file_path)
242
+ task.print_out(
243
+ f'Add column "{snake_column_name}" to the schema'
244
+ )
245
+ code = add_property_to_class(
246
+ code=code,
247
+ class_name=f'{pascal_entity_name}Data',
248
+ property_name=snake_column_name,
249
+ property_type='str'
250
+ )
251
+ task.print_out(f'Write modified code to: {schema_file_path}')
252
+ await write_text_file_async(schema_file_path, code)
253
+
254
+
255
+ @typechecked
256
+ async def add_column_to_repo(
257
+ task: Task,
258
+ project_dir: str,
259
+ kebab_app_name: str,
260
+ snake_module_name: str,
261
+ snake_entity_name: str,
262
+ pascal_entity_name: str,
263
+ snake_column_name: str,
264
+ column_type: str
265
+ ):
266
+ repo_file_path = os.path.join(
267
+ project_dir, 'src', kebab_app_name, 'src', 'module', snake_module_name,
268
+ 'entity', snake_entity_name, 'repo.py'
269
+ )
270
+ task.print_out(f'Read code from: {repo_file_path}')
271
+ code = await read_text_file_async(repo_file_path)
272
+ task.print_out(
273
+ f'Add column "{snake_column_name}" to the repo'
274
+ )
275
+ code = add_property_to_class(
276
+ code=code,
277
+ class_name=f'DBEntity{pascal_entity_name}',
278
+ property_name=snake_column_name,
279
+ property_type='Column',
280
+ property_value='Column(String)'
281
+ )
282
+ task.print_out(f'Write modified code to: {repo_file_path}')
283
+ await write_text_file_async(repo_file_path, code)