codeplain 0.2.13__tar.gz → 0.2.14__tar.gz

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 (198) hide show
  1. {codeplain-0.2.13 → codeplain-0.2.14}/PKG-INFO +1 -1
  2. codeplain-0.2.14/_version.py +1 -0
  3. {codeplain-0.2.13 → codeplain-0.2.14}/docs/starting_a_plain_project_from_scratch.md +24 -24
  4. {codeplain-0.2.13 → codeplain-0.2.14}/memory_management.py +2 -2
  5. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code.py +0 -11
  6. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_arguments.py +48 -2
  7. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_exceptions.py +6 -0
  8. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_read_config.py +0 -6
  9. codeplain-0.2.14/tests/test_resolve_config_file.py +89 -0
  10. {codeplain-0.2.13 → codeplain-0.2.14}/tui/components.py +3 -2
  11. {codeplain-0.2.13 → codeplain-0.2.14}/tui/state_handlers.py +13 -2
  12. codeplain-0.2.13/_version.py +0 -1
  13. {codeplain-0.2.13 → codeplain-0.2.14}/.flake8 +0 -0
  14. {codeplain-0.2.13 → codeplain-0.2.14}/.github/workflows/lint-and-test.yml +0 -0
  15. {codeplain-0.2.13 → codeplain-0.2.14}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
  16. {codeplain-0.2.13 → codeplain-0.2.14}/.github/workflows/publish-install-script.yml +0 -0
  17. {codeplain-0.2.13 → codeplain-0.2.14}/.github/workflows/publish-to-pypi.yml +0 -0
  18. {codeplain-0.2.13 → codeplain-0.2.14}/.gitignore +0 -0
  19. {codeplain-0.2.13 → codeplain-0.2.14}/.vscode/launch.json +0 -0
  20. {codeplain-0.2.13 → codeplain-0.2.14}/.vscode/settings.json +0 -0
  21. {codeplain-0.2.13 → codeplain-0.2.14}/LICENSE +0 -0
  22. {codeplain-0.2.13 → codeplain-0.2.14}/README.md +0 -0
  23. {codeplain-0.2.13 → codeplain-0.2.14}/codeplain_REST_api.py +0 -0
  24. {codeplain-0.2.13 → codeplain-0.2.14}/concept_utils.py +0 -0
  25. {codeplain-0.2.13 → codeplain-0.2.14}/config/__init__.py +0 -0
  26. {codeplain-0.2.13 → codeplain-0.2.14}/config/system_config.yaml +0 -0
  27. {codeplain-0.2.13 → codeplain-0.2.14}/diff_utils.py +0 -0
  28. {codeplain-0.2.13 → codeplain-0.2.14}/docs/generate_cli.py +0 -0
  29. {codeplain-0.2.13 → codeplain-0.2.14}/docs/plain2code_cli.md +0 -0
  30. {codeplain-0.2.13 → codeplain-0.2.14}/event_bus.py +0 -0
  31. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_golang/config.yaml +0 -0
  32. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
  33. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
  34. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_golang/run.sh +0 -0
  35. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_python/config.yaml +0 -0
  36. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
  37. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_python/hello_world_python.plain +0 -0
  38. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_python/python-console-app-boilerplate.plain +0 -0
  39. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_python/run.sh +0 -0
  40. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/config.yaml +0 -0
  41. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
  42. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
  43. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
  44. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
  45. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
  46. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/hello_world_react.plain +0 -0
  47. {codeplain-0.2.13 → codeplain-0.2.14}/examples/example_hello_world_react/run.sh +0 -0
  48. {codeplain-0.2.13 → codeplain-0.2.14}/examples/run.sh +0 -0
  49. {codeplain-0.2.13 → codeplain-0.2.14}/file_utils.py +0 -0
  50. {codeplain-0.2.13 → codeplain-0.2.14}/git_utils.py +0 -0
  51. {codeplain-0.2.13 → codeplain-0.2.14}/hash_key.py +0 -0
  52. {codeplain-0.2.13 → codeplain-0.2.14}/install/bash/examples.sh +0 -0
  53. {codeplain-0.2.13 → codeplain-0.2.14}/install/bash/install.sh +0 -0
  54. {codeplain-0.2.13 → codeplain-0.2.14}/install/bash/walkthrough.sh +0 -0
  55. {codeplain-0.2.13 → codeplain-0.2.14}/install/powershell/examples.ps1 +0 -0
  56. {codeplain-0.2.13 → codeplain-0.2.14}/install/powershell/install.ps1 +0 -0
  57. {codeplain-0.2.13 → codeplain-0.2.14}/install/powershell/walkthrough.ps1 +0 -0
  58. {codeplain-0.2.13 → codeplain-0.2.14}/module_renderer.py +0 -0
  59. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_console.py +0 -0
  60. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_events.py +0 -0
  61. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_logger.py +0 -0
  62. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_nodes.py +0 -0
  63. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_state.py +0 -0
  64. {codeplain-0.2.13 → codeplain-0.2.14}/plain2code_utils.py +0 -0
  65. {codeplain-0.2.13 → codeplain-0.2.14}/plain_file.py +0 -0
  66. {codeplain-0.2.13 → codeplain-0.2.14}/plain_modules.py +0 -0
  67. {codeplain-0.2.13 → codeplain-0.2.14}/plain_spec.py +0 -0
  68. {codeplain-0.2.13 → codeplain-0.2.14}/pyproject.toml +0 -0
  69. {codeplain-0.2.13 → codeplain-0.2.14}/pytest.ini +0 -0
  70. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/__init__.py +0 -0
  71. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
  72. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/base_action.py +0 -0
  73. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
  74. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/commit_implementation_code_changes.py +0 -0
  75. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/create_dist.py +0 -0
  76. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/exit_with_error.py +0 -0
  77. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/finish_functional_requirement.py +0 -0
  78. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/fix_conformance_test.py +0 -0
  79. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/fix_unit_tests.py +0 -0
  80. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/prepare_repositories.py +0 -0
  81. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/prepare_testing_environment.py +0 -0
  82. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/refactor_code.py +0 -0
  83. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/render_conformance_tests.py +0 -0
  84. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/render_functional_requirement.py +0 -0
  85. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/run_conformance_tests.py +0 -0
  86. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/run_unit_tests.py +0 -0
  87. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/actions/summarize_conformance_tests.py +0 -0
  88. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/code_renderer.py +0 -0
  89. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/conformance_test_helpers.py +0 -0
  90. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/conformance_tests.py +0 -0
  91. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/implementation_code_helpers.py +0 -0
  92. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/render_context.py +0 -0
  93. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/render_types.py +0 -0
  94. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/render_utils.py +0 -0
  95. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/state_machine_config.py +0 -0
  96. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/states.py +0 -0
  97. {codeplain-0.2.13 → codeplain-0.2.14}/render_machine/triggers.py +0 -0
  98. {codeplain-0.2.13 → codeplain-0.2.14}/requirements.txt +0 -0
  99. {codeplain-0.2.13 → codeplain-0.2.14}/resources/codeplain_overview.png +0 -0
  100. {codeplain-0.2.13 → codeplain-0.2.14}/resources/plain_example.png +0 -0
  101. {codeplain-0.2.13 → codeplain-0.2.14}/standard_template_library/__init__.py +0 -0
  102. {codeplain-0.2.13 → codeplain-0.2.14}/standard_template_library/golang-console-app-template.plain +0 -0
  103. {codeplain-0.2.13 → codeplain-0.2.14}/standard_template_library/python-console-app-template.plain +0 -0
  104. {codeplain-0.2.13 → codeplain-0.2.14}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
  105. {codeplain-0.2.13 → codeplain-0.2.14}/standard_template_library/typescript-react-app-template.plain +0 -0
  106. {codeplain-0.2.13 → codeplain-0.2.14}/system_config.py +0 -0
  107. {codeplain-0.2.13 → codeplain-0.2.14}/test_scripts/run_conformance_tests_cypress.sh +0 -0
  108. {codeplain-0.2.13 → codeplain-0.2.14}/test_scripts/run_conformance_tests_golang.sh +0 -0
  109. {codeplain-0.2.13 → codeplain-0.2.14}/test_scripts/run_conformance_tests_python.sh +0 -0
  110. {codeplain-0.2.13 → codeplain-0.2.14}/test_scripts/run_unittests_golang.sh +0 -0
  111. {codeplain-0.2.13 → codeplain-0.2.14}/test_scripts/run_unittests_python.sh +0 -0
  112. {codeplain-0.2.13 → codeplain-0.2.14}/test_scripts/run_unittests_react.sh +0 -0
  113. {codeplain-0.2.13 → codeplain-0.2.14}/tests/__init__.py +0 -0
  114. {codeplain-0.2.13 → codeplain-0.2.14}/tests/conftest.py +0 -0
  115. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/circular_imports_1.plain +0 -0
  116. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/circular_imports_2.plain +0 -0
  117. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/circular_imports_main.plain +0 -0
  118. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/diamond_import_1.plain +0 -0
  119. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/diamond_import_2.plain +0 -0
  120. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/diamond_import_common.plain +0 -0
  121. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/diamond_imports_main.plain +0 -0
  122. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/imports/non_existent_import.plain +0 -0
  123. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  124. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  125. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  126. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  127. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  128. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
  129. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  130. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  131. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  132. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  133. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  134. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  135. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  136. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  137. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  138. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  139. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  140. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  141. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  142. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  143. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  144. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
  145. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
  146. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  147. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  148. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  149. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  150. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  151. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  152. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  153. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  154. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts.plain +0 -0
  155. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  156. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  157. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  158. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  159. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  160. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  161. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  162. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  163. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/topological_sort.plain +0 -0
  164. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  165. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/circular_requires_main.plain +0 -0
  166. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/circular_requires_sub.plain +0 -0
  167. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/diamond_requires_1.plain +0 -0
  168. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/diamond_requires_2.plain +0 -0
  169. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/diamond_requires_common.plain +0 -0
  170. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/diamond_requires_main.plain +0 -0
  171. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/independent_requires_1.plain +0 -0
  172. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/independent_requires_2.plain +0 -0
  173. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/independent_requires_main.plain +0 -0
  174. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/non_existent_require.plain +0 -0
  175. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/normal_requires_1.plain +0 -0
  176. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/normal_requires_2.plain +0 -0
  177. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/normal_requires_common.plain +0 -0
  178. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/requires/normal_requires_main.plain +0 -0
  179. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/simple.plain +0 -0
  180. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/templates/block_level_include.plain +0 -0
  181. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/templates/code_variables.plain +0 -0
  182. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/templates/header.plain +0 -0
  183. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/templates/implement.plain +0 -0
  184. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/templates/implement_2.plain +0 -0
  185. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/templates/template_include.plain +0 -0
  186. {codeplain-0.2.13 → codeplain-0.2.14}/tests/data/templates/test_hardest_problem.plain +0 -0
  187. {codeplain-0.2.13 → codeplain-0.2.14}/tests/test_git_utils.py +0 -0
  188. {codeplain-0.2.13 → codeplain-0.2.14}/tests/test_imports.py +0 -0
  189. {codeplain-0.2.13 → codeplain-0.2.14}/tests/test_plainfile.py +0 -0
  190. {codeplain-0.2.13 → codeplain-0.2.14}/tests/test_plainfileparser.py +0 -0
  191. {codeplain-0.2.13 → codeplain-0.2.14}/tests/test_plainspec.py +0 -0
  192. {codeplain-0.2.13 → codeplain-0.2.14}/tests/test_requires.py +0 -0
  193. {codeplain-0.2.13 → codeplain-0.2.14}/tui/__init__.py +0 -0
  194. {codeplain-0.2.13 → codeplain-0.2.14}/tui/models.py +0 -0
  195. {codeplain-0.2.13 → codeplain-0.2.14}/tui/plain2code_tui.py +0 -0
  196. {codeplain-0.2.13 → codeplain-0.2.14}/tui/spinner.py +0 -0
  197. {codeplain-0.2.13 → codeplain-0.2.14}/tui/styles.css +0 -0
  198. {codeplain-0.2.13 → codeplain-0.2.14}/tui/widget_helpers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeplain
3
- Version: 0.2.13
3
+ Version: 0.2.14
4
4
  Summary: Transform plain language specifications into working code
5
5
  License-File: LICENSE
6
6
  Classifier: Environment :: Console
@@ -0,0 +1 @@
1
+ __version__ = "0.2.14"
@@ -21,35 +21,40 @@ my-new-project/
21
21
  ├── config.yaml # CLI configuration
22
22
  ├── run_unittests_[language].sh # Unit test script
23
23
  ├── run_conformance_tests_[language].sh # Conformance test script
24
- ├── build/ # Generated
25
- └── conformance_tests/ # Generated
24
+ ├── build/ # Generated final code
25
+ ├── plain_modules/ # Generated modules code
26
+ └── conformance_tests/ # Generated conformanece tests code
26
27
  ```
27
28
 
28
29
  In this guide we will cover how to create each of these step by step.
29
30
 
30
31
  ## 1. Define Your .plain File
31
32
 
32
- Create a `.plain` file. The following example shows how to specify the array sorting problem. For more details, see [***plain language specifications](https://www.plainlang.org/docs/intro/).
33
+ Create a `.plain` file. The following example shows how to specify the array sorting problem. For more details, see [***plain language specifications](https://www.plainlang.org/docs/).
33
34
 
34
35
  **Example: `array_sorting.plain`**
35
36
  ```plain
36
- {% include "python-console-app-template.plain", main_executable_file_name: "array_sorting.py" %}
37
+ ---
38
+ description: 'Example showing how to specify the array sorting problem'
39
+ import:
40
+ - python-console-app-template
41
+ ---
37
42
 
38
- ***Definitions:***
39
- - The Array is an array of integers received as input.
43
+ ***definitions***
44
+ - :Array: is an array of integers received as input.
40
45
 
41
- ***Functional Requirements:***
42
- - The App should be extended to receive The Array
43
- - Sort The Array.
44
- - Display The Array.
46
+ ***functional specs***
47
+ - :App: should be extended to receive :Array:
48
+ - Sort :Array:
49
+ - Display :Array:
45
50
 
46
- ***Acceptance Tests:***
47
- - When given input "5 2 8 1 9", The App should output "1 2 5 8 9"
48
- - When given input "1 2 3 4 5", The App should output "1 2 3 4 5"
51
+ ***acceptance tests***
52
+ - When given input "5 2 8 1 9", :App: should output "1 2 5 8 9"
53
+ - When given input "1 2 3 4 5", :App: should output "1 2 3 4 5"
49
54
 
50
55
  ```
51
56
 
52
- - When including templates, use `--full-plain` flag to preview the complete specification including all template content before rendering. You can find predefined templates in [standard template library](../standard_template_library/). (This flag can be configured in your config file.)
57
+ `python-console-app-template` is predefined template providing specification of a typical Python console application. Check [standard template library](../standard_template_library/) for available predefined templates.
53
58
 
54
59
  ## 2. Add Test Scripts
55
60
 
@@ -59,7 +64,7 @@ Include the appropriate test scripts to your project:
59
64
  cp /path/to/plain2code_client/test_scripts/run_unittests_python.sh ./
60
65
  cp /path/to/plain2code_client/test_scripts/run_conformance_tests_python.sh ./
61
66
  ```
62
- - You may need to modify these scripts based on your specific project requirements.
67
+ You may need to modify these scripts based on your specific project requirements.
63
68
 
64
69
  ## 3. Configure Parameters
65
70
 
@@ -71,6 +76,8 @@ Example of a basic `config.yaml` file:
71
76
 
72
77
  unittests-script: ./run_unittests_python.sh
73
78
  conformance-tests-script: ./run_conformance_tests_python.sh
79
+ copy-build: true
80
+ build-dest: build
74
81
  verbose: true
75
82
 
76
83
  ```
@@ -81,14 +88,7 @@ verbose: true
81
88
  ## 4. Generate & Run Your Project
82
89
 
83
90
  ```bash
84
- python ../plain2code_client/plain2code.py my_app.plain
91
+ codeplain my_app.plain
85
92
  ```
86
- - Generated code will appear in build/ and conformance_tests/.
87
93
 
88
-
89
- ## 5. Notes
90
- - `build/` and `conformance_tests/` folders are generated automatically
91
- - These folders are excluded from git via `.gitignore`
92
- - `dist/` and `dist_conformance_tests/` are created if you set `copy-build: true` and `copy-conformance-tests: true` in your config.yaml
93
- - Always review generated code before using in production
94
- - The `.plain` file is your source of truth - keep it well-documented and version-controlled
94
+ After rendering is completed the generated code will be available in build/ folder.
@@ -14,11 +14,11 @@ CONFORMANCE_TEST_MEMORY_SUBFOLDER = "conformance_test_memory"
14
14
  class MemoryManager:
15
15
 
16
16
  @staticmethod
17
- def fetch_memory_files(memory_folder: str):
17
+ def fetch_memory_files(memory_folder: str) -> tuple[list[str], dict[str, str]]:
18
18
  """Fetch memory files from memory_folder/conformance_test_memory."""
19
19
  memory_path = os.path.join(memory_folder, CONFORMANCE_TEST_MEMORY_SUBFOLDER)
20
20
  if not os.path.exists(memory_path):
21
- return {}, {}
21
+ return [], {}
22
22
  memory_files = file_utils.list_all_text_files(memory_path)
23
23
  memory_files_content = file_utils.get_existing_files_content(memory_path, memory_files)
24
24
  console.info(f"Loaded {len(memory_files_content)} memory files.")
@@ -51,17 +51,6 @@ from tui.plain2code_tui import Plain2CodeTUI
51
51
 
52
52
  DEFAULT_TEMPLATE_DIRS = importlib.resources.files("standard_template_library")
53
53
 
54
- MAX_UNITTEST_FIX_ATTEMPTS = 20
55
- MAX_CONFORMANCE_TEST_FIX_ATTEMPTS = 20
56
- MAX_CONFORMANCE_TEST_RUNS = 20
57
- MAX_REFACTORING_ITERATIONS = 5
58
- MAX_UNIT_TEST_RENDER_RETRIES = 2
59
-
60
- MAX_ISSUE_LENGTH = 10000 # Characters.
61
-
62
- UNRECOVERABLE_ERROR_EXIT_CODES = [69]
63
- TIMEOUT_ERROR_EXIT_CODE = 124
64
-
65
54
 
66
55
  def get_render_range(render_range, plain_source):
67
56
  render_range = render_range.split(",")
@@ -2,6 +2,8 @@ import argparse
2
2
  import os
3
3
  import re
4
4
 
5
+ from plain2code_console import console
6
+ from plain2code_exceptions import AmbiguousConfigFileError
5
7
  from plain2code_read_config import get_args_from_config
6
8
 
7
9
  CODEPLAIN_API_KEY = os.getenv("CODEPLAIN_API_KEY")
@@ -83,9 +85,51 @@ def frid_range_string(s):
83
85
  return s
84
86
 
85
87
 
88
+ def resolve_config_file(config_name: str, plain_file_path: str):
89
+ """
90
+ Resolve the config file path by searching in two locations:
91
+ 1. Directory of the plain file
92
+ 2. Current working directory (where render is called from)
93
+
94
+ Returns the resolved absolute path, or None if the file is not found in either location.
95
+ Raises AmbiguousConfigFileError if the file exists in both locations (and they differ).
96
+ """
97
+ plain_file_dir = os.path.dirname(os.path.abspath(plain_file_path))
98
+ cwd = os.getcwd()
99
+
100
+ plain_dir_config = os.path.normpath(os.path.join(plain_file_dir, config_name))
101
+ cwd_config = os.path.normpath(os.path.join(cwd, config_name))
102
+
103
+ in_plain_dir = os.path.exists(plain_dir_config)
104
+ in_cwd = os.path.exists(cwd_config)
105
+ same_location = plain_dir_config == cwd_config
106
+
107
+ if in_plain_dir and in_cwd and not same_location:
108
+ raise AmbiguousConfigFileError(
109
+ f"Config file '{config_name}' was found in two locations:\n"
110
+ f" - Plain file directory: {plain_file_dir}\n"
111
+ f" - Current working directory: {cwd}\n"
112
+ f"Remove the config file from one of these locations to resolve the ambiguity."
113
+ )
114
+
115
+ if in_plain_dir:
116
+ return plain_dir_config
117
+ if in_cwd:
118
+ return cwd_config
119
+ return None
120
+
121
+
86
122
  def update_args_with_config(args, parser):
87
123
  try:
88
- config_args = get_args_from_config(args.config_name, parser)
124
+ resolved_config = resolve_config_file(args.config_name, args.filename)
125
+
126
+ if resolved_config is None:
127
+ console.info(f"No config file '{args.config_name}' found. Proceeding without one.")
128
+ return args
129
+
130
+ args.config_name = resolved_config
131
+ config_args = get_args_from_config(resolved_config, parser)
132
+
89
133
  # Get all action types from the parser
90
134
  action_types = {action.dest: action for action in parser._actions}
91
135
 
@@ -109,6 +153,8 @@ def update_args_with_config(args, parser):
109
153
  else:
110
154
  parser.error(f"Invalid argument: {key}")
111
155
 
156
+ except AmbiguousConfigFileError as e:
157
+ parser.error(str(e))
112
158
  except Exception as e:
113
159
  parser.error(f"Error reading config file: {str(e)}")
114
160
 
@@ -152,7 +198,7 @@ def create_parser():
152
198
  "--config-name",
153
199
  type=non_empty_string,
154
200
  default="config.yaml",
155
- help="Path to the config file, defaults to config.yaml",
201
+ help="Name of the config file to look for. Looked up in the plain file directory and the current working directory. Defaults to config.yaml.",
156
202
  )
157
203
 
158
204
  render_range_group = parser.add_mutually_exclusive_group()
@@ -73,3 +73,9 @@ class NetworkConnectionError(Exception):
73
73
  """Raised when there is a network connectivity issue with the API server."""
74
74
 
75
75
  pass
76
+
77
+
78
+ class AmbiguousConfigFileError(Exception):
79
+ """Raised when a config file is found in both the plain file directory and the current working directory."""
80
+
81
+ pass
@@ -1,4 +1,3 @@
1
- import os
2
1
  from argparse import ArgumentParser, Namespace
3
2
  from typing import Any, Dict
4
3
 
@@ -46,11 +45,6 @@ def get_args_from_config(config_file: str, parser: ArgumentParser) -> Namespace:
46
45
 
47
46
  args = Namespace()
48
47
 
49
- if config_file == "config.yaml":
50
- if not os.path.exists(config_file):
51
- console.info(f"Default config file {config_file} not found. No config file is read.")
52
- return args
53
-
54
48
  # Load config
55
49
  config = load_config(config_file)
56
50
  config = validate_config(config, parser)
@@ -0,0 +1,89 @@
1
+ import os
2
+ import tempfile
3
+ from pathlib import Path
4
+ from unittest.mock import patch
5
+
6
+ import pytest
7
+
8
+ from plain2code_arguments import resolve_config_file
9
+ from plain2code_exceptions import AmbiguousConfigFileError
10
+
11
+
12
+ @pytest.fixture
13
+ def two_dirs():
14
+ """Provide two separate temporary directories: one for the plain file, one as CWD."""
15
+ with tempfile.TemporaryDirectory() as plain_dir:
16
+ with tempfile.TemporaryDirectory() as cwd:
17
+ yield plain_dir, cwd
18
+
19
+
20
+ def _plain_file(plain_dir):
21
+ return os.path.join(plain_dir, "module.plain")
22
+
23
+
24
+ def test_config_in_plain_file_dir_only(two_dirs):
25
+ plain_dir, cwd = two_dirs
26
+ config = Path(plain_dir) / "config.yaml"
27
+ config.write_text("verbose: true\n")
28
+
29
+ with patch("os.getcwd", return_value=cwd):
30
+ result = resolve_config_file("config.yaml", _plain_file(plain_dir))
31
+
32
+ assert result == os.path.normpath(str(config))
33
+
34
+
35
+ def test_config_in_cwd_only(two_dirs):
36
+ plain_dir, cwd = two_dirs
37
+ config = Path(cwd) / "config.yaml"
38
+ config.write_text("verbose: true\n")
39
+
40
+ with patch("os.getcwd", return_value=cwd):
41
+ result = resolve_config_file("config.yaml", _plain_file(plain_dir))
42
+
43
+ assert result == os.path.normpath(str(config))
44
+
45
+
46
+ def test_config_in_both_locations_raises(two_dirs):
47
+ plain_dir, cwd = two_dirs
48
+ (Path(plain_dir) / "config.yaml").write_text("verbose: true\n")
49
+ (Path(cwd) / "config.yaml").write_text("verbose: false\n")
50
+
51
+ with patch("os.getcwd", return_value=cwd):
52
+ with pytest.raises(AmbiguousConfigFileError) as exc_info:
53
+ resolve_config_file("config.yaml", _plain_file(plain_dir))
54
+
55
+ assert plain_dir in str(exc_info.value)
56
+ assert cwd in str(exc_info.value)
57
+
58
+
59
+ def test_config_not_found_returns_none(two_dirs):
60
+ plain_dir, cwd = two_dirs
61
+
62
+ with patch("os.getcwd", return_value=cwd):
63
+ result = resolve_config_file("config.yaml", _plain_file(plain_dir))
64
+
65
+ assert result is None
66
+
67
+
68
+ def test_config_same_dir_no_error():
69
+ """When the plain file and CWD are in the same directory, a single config file is fine."""
70
+ with tempfile.TemporaryDirectory() as d:
71
+ config = Path(d) / "config.yaml"
72
+ config.write_text("verbose: true\n")
73
+
74
+ with patch("os.getcwd", return_value=d):
75
+ result = resolve_config_file("config.yaml", os.path.join(d, "module.plain"))
76
+
77
+ assert result == os.path.normpath(str(config))
78
+
79
+
80
+ def test_custom_config_name_found_in_plain_file_dir(two_dirs):
81
+ """A custom --config-name is also looked up in the two locations."""
82
+ plain_dir, cwd = two_dirs
83
+ config = Path(plain_dir) / "myconfig.yaml"
84
+ config.write_text("verbose: true\n")
85
+
86
+ with patch("os.getcwd", return_value=cwd):
87
+ result = resolve_config_file("myconfig.yaml", _plain_file(plain_dir))
88
+
89
+ assert result == os.path.normpath(str(config))
@@ -271,6 +271,7 @@ class RenderingInfoBox(Vertical):
271
271
  """Initialize default labels on mount."""
272
272
  self.module_text = "Module: "
273
273
  self.functionality_text = "Functionality:"
274
+
274
275
  self._refresh_content()
275
276
 
276
277
  def compose(self):
@@ -355,7 +356,7 @@ class FRIDProgress(Vertical):
355
356
  CONFORMANCE_TEST_VALIDATION_TEXT = "Conformance tests"
356
357
 
357
358
  RENDERING_MODULE_TEXT = "Module: "
358
- RENDERING_FUNCTIONALITY_TEXT = "Functionality:"
359
+ RENDERING_FUNCTIONALITY_TEXT = "Functionality "
359
360
 
360
361
  def __init__(
361
362
  self,
@@ -367,7 +368,7 @@ class FRIDProgress(Vertical):
367
368
  self.unittests_script = unittests_script
368
369
  self.conformance_tests_script = conformance_tests_script
369
370
 
370
- def update_fr_text(self, text: str) -> None:
371
+ def update_functionality_text(self, text: str) -> None:
371
372
  try:
372
373
  # Update the rendering info box instead
373
374
  info_box = self.query_one(RenderingInfoBox)
@@ -66,8 +66,9 @@ class FridReadyHandler(StateHandler):
66
66
  def handle(self, _: list[str], snapshot: RenderContextSnapshot, _previous_state_segments: list[str]) -> None:
67
67
  """Handle READY_FOR_FRID_IMPLEMENTATION state."""
68
68
  # Update FRID text
69
- rendering_functionality_text = f"{tui_components.FRIDProgress.RENDERING_FUNCTIONALITY_TEXT} {snapshot.frid_context.functional_requirement_text}"
70
- get_frid_progress(self.tui).update_fr_text(rendering_functionality_text)
69
+
70
+ rendering_functionality_text = f"{tui_components.FRIDProgress.RENDERING_FUNCTIONALITY_TEXT}{snapshot.frid_context.frid}: {snapshot.frid_context.functional_requirement_text}"
71
+ get_frid_progress(self.tui).update_functionality_text(rendering_functionality_text)
71
72
 
72
73
  # Set progress states
73
74
  update_progress_item_status(self.tui, TUIComponents.FRID_PROGRESS_RENDER_FR.value, ProgressItem.PROCESSING)
@@ -216,11 +217,21 @@ class ConformanceTestsHandler(StateHandler):
216
217
  )
217
218
  elif segments[2] == States.CONFORMANCE_TEST_ENV_PREPARED.value:
218
219
  running_text = f"Running conformance tests for functional requirement {snapshot.conformance_tests_running_context.current_testing_frid}"
220
+ if snapshot.conformance_tests_running_context.current_testing_module_name != snapshot.module_name:
221
+ running_text += (
222
+ f" of module {snapshot.conformance_tests_running_context.current_testing_module_name}"
223
+ )
224
+
219
225
  update_progress_item_substates(
220
226
  self.tui, TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value, [Substate(running_text)]
221
227
  )
222
228
  elif segments[2] == States.CONFORMANCE_TEST_FAILED.value:
223
229
  fixing_text = f"Fixing conformance tests for functional requirement {snapshot.conformance_tests_running_context.current_testing_frid}"
230
+ if snapshot.conformance_tests_running_context.current_testing_module_name != snapshot.module_name:
231
+ fixing_text += (
232
+ f" of module {snapshot.conformance_tests_running_context.current_testing_module_name}"
233
+ )
234
+
224
235
  update_progress_item_substates(
225
236
  self.tui, TUIComponents.FRID_PROGRESS_CONFORMANCE_TEST.value, [Substate(fixing_text)]
226
237
  )
@@ -1 +0,0 @@
1
- __version__ = "0.2.13"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes