codeplain 0.2.11__tar.gz → 0.2.12__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 (197) hide show
  1. {codeplain-0.2.11 → codeplain-0.2.12}/PKG-INFO +1 -1
  2. codeplain-0.2.12/_version.py +1 -0
  3. {codeplain-0.2.11 → codeplain-0.2.12}/config/system_config.yaml +0 -2
  4. {codeplain-0.2.11 → codeplain-0.2.12}/docs/plain_language_specification.md +30 -67
  5. {codeplain-0.2.11 → codeplain-0.2.12}/file_utils.py +5 -0
  6. {codeplain-0.2.11 → codeplain-0.2.12}/memory_management.py +25 -0
  7. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_console.py +1 -1
  8. {codeplain-0.2.11 → codeplain-0.2.12}/pyproject.toml +4 -1
  9. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/analyze_specification_ambiguity.py +5 -2
  10. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/run_conformance_tests.py +1 -3
  11. codeplain-0.2.12/render_machine/implementation_code_helpers.py +49 -0
  12. {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/python-console-app-template.plain +1 -3
  13. {codeplain-0.2.11 → codeplain-0.2.12}/system_config.py +2 -3
  14. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/circular_imports_2.plain +1 -1
  15. codeplain-0.2.11/render_machine/implementation_code_helpers.py +0 -26
  16. {codeplain-0.2.11 → codeplain-0.2.12}/.flake8 +0 -0
  17. {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/lint-and-test.yml +0 -0
  18. {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
  19. {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/publish-install-script.yml +0 -0
  20. {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/publish-to-pypi.yml +0 -0
  21. {codeplain-0.2.11 → codeplain-0.2.12}/.gitignore +0 -0
  22. {codeplain-0.2.11 → codeplain-0.2.12}/.vscode/launch.json +0 -0
  23. {codeplain-0.2.11 → codeplain-0.2.12}/.vscode/settings.json +0 -0
  24. {codeplain-0.2.11 → codeplain-0.2.12}/LICENSE +0 -0
  25. {codeplain-0.2.11 → codeplain-0.2.12}/README.md +0 -0
  26. {codeplain-0.2.11 → codeplain-0.2.12}/codeplain_REST_api.py +0 -0
  27. {codeplain-0.2.11 → codeplain-0.2.12}/concept_utils.py +0 -0
  28. {codeplain-0.2.11 → codeplain-0.2.12}/config/__init__.py +0 -0
  29. {codeplain-0.2.11 → codeplain-0.2.12}/diff_utils.py +0 -0
  30. {codeplain-0.2.11 → codeplain-0.2.12}/docs/generate_cli.py +0 -0
  31. {codeplain-0.2.11 → codeplain-0.2.12}/docs/plain2code_cli.md +0 -0
  32. {codeplain-0.2.11 → codeplain-0.2.12}/docs/starting_a_plain_project_from_scratch.md +0 -0
  33. {codeplain-0.2.11 → codeplain-0.2.12}/event_bus.py +0 -0
  34. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/config.yaml +0 -0
  35. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
  36. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
  37. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/run.sh +0 -0
  38. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/config.yaml +0 -0
  39. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
  40. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/hello_world_python.plain +0 -0
  41. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/run.sh +0 -0
  42. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/config.yaml +0 -0
  43. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
  44. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
  45. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
  46. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
  47. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
  48. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/hello_world_react.plain +0 -0
  49. {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/run.sh +0 -0
  50. {codeplain-0.2.11 → codeplain-0.2.12}/examples/run.sh +0 -0
  51. {codeplain-0.2.11 → codeplain-0.2.12}/git_utils.py +0 -0
  52. {codeplain-0.2.11 → codeplain-0.2.12}/hash_key.py +0 -0
  53. {codeplain-0.2.11 → codeplain-0.2.12}/install/bash/examples.sh +0 -0
  54. {codeplain-0.2.11 → codeplain-0.2.12}/install/bash/install.sh +0 -0
  55. {codeplain-0.2.11 → codeplain-0.2.12}/install/bash/walkthrough.sh +0 -0
  56. {codeplain-0.2.11 → codeplain-0.2.12}/install/powershell/examples.ps1 +0 -0
  57. {codeplain-0.2.11 → codeplain-0.2.12}/install/powershell/install.ps1 +0 -0
  58. {codeplain-0.2.11 → codeplain-0.2.12}/install/powershell/walkthrough.ps1 +0 -0
  59. {codeplain-0.2.11 → codeplain-0.2.12}/module_renderer.py +0 -0
  60. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code.py +0 -0
  61. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_arguments.py +0 -0
  62. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_events.py +0 -0
  63. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_exceptions.py +0 -0
  64. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_logger.py +0 -0
  65. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_nodes.py +0 -0
  66. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_read_config.py +0 -0
  67. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_state.py +0 -0
  68. {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_utils.py +0 -0
  69. {codeplain-0.2.11 → codeplain-0.2.12}/plain_file.py +0 -0
  70. {codeplain-0.2.11 → codeplain-0.2.12}/plain_modules.py +0 -0
  71. {codeplain-0.2.11 → codeplain-0.2.12}/plain_spec.py +0 -0
  72. {codeplain-0.2.11 → codeplain-0.2.12}/pytest.ini +0 -0
  73. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/__init__.py +0 -0
  74. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/base_action.py +0 -0
  75. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
  76. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/commit_implementation_code_changes.py +0 -0
  77. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/create_dist.py +0 -0
  78. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/exit_with_error.py +0 -0
  79. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/finish_functional_requirement.py +0 -0
  80. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/fix_conformance_test.py +0 -0
  81. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/fix_unit_tests.py +0 -0
  82. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/prepare_repositories.py +0 -0
  83. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/prepare_testing_environment.py +0 -0
  84. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/refactor_code.py +0 -0
  85. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/render_conformance_tests.py +0 -0
  86. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/render_functional_requirement.py +0 -0
  87. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/run_unit_tests.py +0 -0
  88. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/summarize_conformance_tests.py +0 -0
  89. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/code_renderer.py +0 -0
  90. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/conformance_test_helpers.py +0 -0
  91. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/conformance_tests.py +0 -0
  92. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/render_context.py +0 -0
  93. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/render_types.py +0 -0
  94. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/render_utils.py +0 -0
  95. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/state_machine_config.py +0 -0
  96. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/states.py +0 -0
  97. {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/triggers.py +0 -0
  98. {codeplain-0.2.11 → codeplain-0.2.12}/requirements.txt +0 -0
  99. {codeplain-0.2.11 → codeplain-0.2.12}/resources/codeplain_overview.png +0 -0
  100. {codeplain-0.2.11 → codeplain-0.2.12}/resources/plain_example.png +0 -0
  101. {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/__init__.py +0 -0
  102. {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/golang-console-app-template.plain +0 -0
  103. {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
  104. {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/typescript-react-app-template.plain +0 -0
  105. {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_conformance_tests_cypress.sh +0 -0
  106. {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_conformance_tests_golang.sh +0 -0
  107. {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_conformance_tests_python.sh +0 -0
  108. {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_unittests_golang.sh +0 -0
  109. {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_unittests_python.sh +0 -0
  110. {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_unittests_react.sh +0 -0
  111. {codeplain-0.2.11 → codeplain-0.2.12}/tests/__init__.py +0 -0
  112. {codeplain-0.2.11 → codeplain-0.2.12}/tests/conftest.py +0 -0
  113. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/circular_imports_1.plain +0 -0
  114. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/circular_imports_main.plain +0 -0
  115. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_import_1.plain +0 -0
  116. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_import_2.plain +0 -0
  117. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_import_common.plain +0 -0
  118. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_imports_main.plain +0 -0
  119. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/non_existent_import.plain +0 -0
  120. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
  121. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/invalid_specification_order.plain +0 -0
  122. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
  123. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
  124. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
  125. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
  126. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
  127. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
  128. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
  129. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
  130. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
  131. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
  132. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
  133. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
  134. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
  135. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
  136. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
  137. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
  138. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts.plain +0 -0
  139. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
  140. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
  141. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
  142. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
  143. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
  144. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
  145. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
  146. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
  147. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
  148. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
  149. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
  150. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
  151. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts.plain +0 -0
  152. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
  153. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
  154. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
  155. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
  156. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
  157. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
  158. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
  159. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
  160. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/topological_sort.plain +0 -0
  161. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
  162. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/circular_requires_main.plain +0 -0
  163. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/circular_requires_sub.plain +0 -0
  164. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_1.plain +0 -0
  165. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_2.plain +0 -0
  166. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_common.plain +0 -0
  167. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_main.plain +0 -0
  168. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/independent_requires_1.plain +0 -0
  169. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/independent_requires_2.plain +0 -0
  170. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/independent_requires_main.plain +0 -0
  171. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/non_existent_require.plain +0 -0
  172. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_1.plain +0 -0
  173. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_2.plain +0 -0
  174. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_common.plain +0 -0
  175. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_main.plain +0 -0
  176. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/simple.plain +0 -0
  177. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/block_level_include.plain +0 -0
  178. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/code_variables.plain +0 -0
  179. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/header.plain +0 -0
  180. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/implement.plain +0 -0
  181. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/implement_2.plain +0 -0
  182. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/template_include.plain +0 -0
  183. {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/test_hardest_problem.plain +0 -0
  184. {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_git_utils.py +0 -0
  185. {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_imports.py +0 -0
  186. {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_plainfile.py +0 -0
  187. {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_plainfileparser.py +0 -0
  188. {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_plainspec.py +0 -0
  189. {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_requires.py +0 -0
  190. {codeplain-0.2.11 → codeplain-0.2.12}/tui/__init__.py +0 -0
  191. {codeplain-0.2.11 → codeplain-0.2.12}/tui/components.py +0 -0
  192. {codeplain-0.2.11 → codeplain-0.2.12}/tui/models.py +0 -0
  193. {codeplain-0.2.11 → codeplain-0.2.12}/tui/plain2code_tui.py +0 -0
  194. {codeplain-0.2.11 → codeplain-0.2.12}/tui/spinner.py +0 -0
  195. {codeplain-0.2.11 → codeplain-0.2.12}/tui/state_handlers.py +0 -0
  196. {codeplain-0.2.11 → codeplain-0.2.12}/tui/styles.css +0 -0
  197. {codeplain-0.2.11 → codeplain-0.2.12}/tui/widget_helpers.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codeplain
3
- Version: 0.2.11
3
+ Version: 0.2.12
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.12"
@@ -1,5 +1,3 @@
1
- client_version: "0.2.11"
2
-
3
1
  error_messages:
4
2
  template_not_found:
5
3
  message: |
@@ -13,68 +13,31 @@
13
13
  Here's an example of a "hello, world" program in ***plain.
14
14
 
15
15
  ```plain
16
- ***Non-Functional Requirements:***
16
+ ***implementation reqs***
17
17
 
18
18
  - :Implementation: should be in Python.
19
19
 
20
- ***Functional Requirements:***
20
+ ***functional specs***
21
21
 
22
22
  - Display "hello, world"
23
23
  ```
24
24
 
25
- # Source structure
26
-
27
- ## Source organization
28
-
29
- ***plain source can be organized in sections and subsection using markdown headers.
30
-
31
- ```plain
32
- # Section 1
33
-
34
- # Section 2
35
-
36
- ***Non-Functional Requirements:***
37
-
38
- - First simple non-functional requirement
39
-
40
- ***Functional Requirements:***
41
-
42
- - First simple functional requirement
43
-
44
- ## Section 2.1
45
-
46
- ***Non-Functional Requirements:***
47
-
48
- - Second simple non-functional requirement
49
-
50
- ***Functional Requirements:***
51
-
52
- - Second simple functional requirement
53
- ```
54
-
55
- This enables hierarchical organization of the specification.
56
-
57
- In example above:
58
-
59
- - While rendering the "First simple functional requirement", the renderer will not have access to the "Second simple non-functional requirement".
60
- - While rendering the "Second simple functional requirement", the renderer will not have access to the "First simple non-functional requirement".
61
-
62
25
  ### Specifications
63
26
 
64
27
  There are four types of specifications:
65
28
 
66
- - `***Definitions:***`
67
- - `***Non-Functional Requirements:***`
68
- - `***Functional Requirements:***`
69
- - `***Test Requirements:***`
29
+ - `***definitions***`
30
+ - `***implementation reqs***`
31
+ - `***functional specs***`
32
+ - `***test reqs***`
70
33
 
71
- Every plain source file requires at least one functional requirement and an associated non-functional requirement.
34
+ Every plain source file requires at least one functional spec and an associated implementation req.
72
35
 
73
- Functional requirements must reside in leaf sections while other specifications can be placed also in non-leaf sections. Specifications in non-leaf sections apply not just to the section itself but to all of its subsections.
36
+ Functional specs must reside in leaf sections while other specifications can be placed also in non-leaf sections. Specifications in non-leaf sections apply not just to the section itself but to all of its subsections.
74
37
 
75
38
  ## Definitions
76
39
 
77
- The `***Definitions:***` specification is a list of definitions of new concepts.
40
+ The `***definitions***` specification is a list of definitions of new concepts.
78
41
 
79
42
  Here's an example of a simple definiton.
80
43
 
@@ -89,9 +52,9 @@ While providing definitions, you should adhere to the following 4 rules:
89
52
  - Every definition must start with the name of the concept you are defining.
90
53
  - Each concept name must be enclosed in colons (`:`) at both the beginning and end.
91
54
  - Valid characters for concept name include: Plus sign (`+`), Minus sign (`-`), Dot sign (`.`), Digits (`0`-`9`), Uppercase letters (`A`-`Z`), Underscore (`_`), Lowercase letters (`a`-`z`)
92
- - Examples: `:App:`, `:Tasks:`, `:ListOfUsers:`, `:CLI:`.
55
+ - Examples: `:App:`, `:Tasks:`, `:ListOfUsers:`, `:CLI:`.
93
56
  - Concept names must be globally unique (meaning, you cannot provide two definitions with the same concept name).
94
- - When referencing concepts in ***Test Requirements:***, ***Functional Requirements:***, ***Non-Functional Requirements:*** and ***Acceptance Tests:***, the concept name must exist in the ***Definitions:*** section.
57
+ - When referencing concepts in ***test reqs***, ***functional specs***, ***implementation reqs*** and ***acceptance tests***, the concept name must exist in the ***definitions*** section.
95
58
 
96
59
  Furthermore, there are special concepts that are already defined and are ready to use. They should not be redefined:
97
60
 
@@ -111,9 +74,9 @@ Definitions are the mechanism for definining data structures in ***plain. Here's
111
74
  - Due Date - optional date by which :User: is supposed to complete :Task:.
112
75
  ```
113
76
 
114
- ## Non-Functional Requirements
77
+ ## Implementation Reqs
115
78
 
116
- The `***Non-Functional Requirements:***` specification is a list of instructions that steer software code implementation and provide details of execution environment.
79
+ The `***implementation reqs***` specification is a list of instructions that steer software code implementation and provide details of execution environment.
117
80
 
118
81
  Here's an example of a simple instruction specifying only that the ***plain specification should be rendered to Python software code.
119
82
 
@@ -133,9 +96,9 @@ Here's an example of more complex instructions.
133
96
  - The main executable file of :App: should be called hello_world.py
134
97
  ```
135
98
 
136
- ## Functional Requirements
99
+ ## Functional Specs
137
100
 
138
- The `***Functional Requirements:***` specification provides a description of functionality that should be rendered to software code. The descriptions should be provided in natural language as a markdown list.
101
+ The `***functional specs***` specification provides a description of functionality that should be rendered to software code. The descriptions should be provided in natural language as a markdown list.
139
102
 
140
103
  Here's an example of a simple description of the functionality of the "hello, world" application.
141
104
 
@@ -143,7 +106,7 @@ Here's an example of a simple description of the functionality of the "hello, wo
143
106
  - Display "hello, world"
144
107
  ```
145
108
 
146
- Each functional requirement must be limited in complexity. For example, for the functional requirement
109
+ Each functional spec must be limited in complexity. For example, for the functional spec
147
110
 
148
111
  ```plain
149
112
  - :App: should implement a task manager application.
@@ -152,10 +115,10 @@ Each functional requirement must be limited in complexity. For example, for the
152
115
  the renderer of ***plain source to software code should respond with
153
116
 
154
117
  ```
155
- Functional requirement too complex!
118
+ Functional spec too complex!
156
119
  ```
157
120
 
158
- In such case you need to break down the functioanlity into smaller, less-complex functional requirements.
121
+ In such case you need to break down the functioanlity into smaller, less-complex functional specs.
159
122
 
160
123
  Here's an example how to do such a break down in the case of a task manager application.
161
124
 
@@ -173,38 +136,38 @@ Here's an example how to do such a break down in the case of a task manager appl
173
136
  - :User: should be able to mark :Task: as completed.
174
137
  ```
175
138
 
176
- Functional requirements are rendered incrementally one by one. Consequently earlier functional requirements cannot reference later functional requirements.
139
+ Functional specs are rendered incrementally one by one. Consequently earlier functional specs cannot reference later functional specs.
177
140
 
178
141
  ### Acceptance Tests
179
142
 
180
- Acceptance tests can be used to further refine the functional requirement and especially to incorporate constraints on the implementation.
143
+ Acceptance tests can be used to further refine the functional spec and especially to incorporate constraints on the implementation.
181
144
 
182
- Acceptance tests are specified with a keyword `***Acceptance Tests:***` as a subsection within `***Functional Requirements:***` section. Each acceptance tests must be an item in a list.
145
+ Acceptance tests are specified with a keyword `***acceptance tests***` as a subsection within `***functional specs***` section. Each acceptance tests must be an item in a list.
183
146
 
184
147
  Here's an example of a "Hello, World" application with one acceptance test.
185
148
 
186
149
  ```plain
187
- ***Functional Requirements:***
150
+ ***functional specs***
188
151
 
189
152
  - Display "hello, world"
190
153
 
191
- ***Acceptance Tests:***
192
-
154
+ ***acceptance tests***
155
+
193
156
  - :App: shouldn't show logging output in the console output (neither in stdout nor stderr).
194
157
  ```
195
158
 
196
- Acceptance tests extend **conformance tests**. The acceptance tests are implemented according to the ***Test Requirements:*** specification (see next section).
159
+ Acceptance tests extend **conformance tests**. The acceptance tests are implemented according to the ***test reqs*** specification (see below).
197
160
 
198
- ## Test Requirements
161
+ ## Test Reqs
199
162
 
200
- The `***Test Requirements:***` specification is a list of instructions that steer implementation of conformance tests and provide details of testing environment.
163
+ The `***test reqs***` specification is a list of instructions that steer implementation of conformance tests and provide details of testing environment.
201
164
 
202
- **Conformance tests** is the generated code used to verify that the functional requirement is implemented according to the specification.
165
+ **Conformance tests** is the generated code used to verify that the functional spec is implemented according to the specification.
203
166
 
204
- Here's an example specification of test requirements.
167
+ Here's an example specification of test reqs.
205
168
 
206
169
  ```plain
207
- - :ConformanceTests: of :App: should be implemented in Python using Unittest framework.
170
+ - :ConformanceTests: of :App: should be implemented in Python using Unittest framework.
208
171
  ```
209
172
 
210
173
  # Extended Syntax
@@ -47,6 +47,11 @@ FILE_EXTENSION_MAPPING = {
47
47
  SYSTEM_FOLDERS = [".git", CODEPLAIN_METADATA_FOLDER, CODEPLAIN_MEMORY_SUBFOLDER]
48
48
 
49
49
 
50
+ def is_system_folder_path(file_path: str) -> bool:
51
+ parts = Path(file_path).parts
52
+ return bool(parts) and parts[0] in SYSTEM_FOLDERS
53
+
54
+
50
55
  def get_file_type(file_name):
51
56
 
52
57
  # Extract the file extension
@@ -1,3 +1,4 @@
1
+ import json
1
2
  import os
2
3
 
3
4
  import file_utils
@@ -20,6 +21,7 @@ class MemoryManager:
20
21
  return {}, {}
21
22
  memory_files = file_utils.list_all_text_files(memory_path)
22
23
  memory_files_content = file_utils.get_existing_files_content(memory_path, memory_files)
24
+ console.info(f"Loaded {len(memory_files_content)} memory files.")
23
25
  return memory_files, memory_files_content
24
26
 
25
27
  def __init__(self, codeplain_api, module_build_folder: str):
@@ -95,3 +97,26 @@ class MemoryManager:
95
97
  if len(response_files) > 0:
96
98
  memory_folder_path = os.path.join(self.memory_folder, CONFORMANCE_TEST_MEMORY_SUBFOLDER)
97
99
  file_utils.store_response_files(memory_folder_path, response_files, existing_files)
100
+
101
+ def delete_unresolved_memory_files(self):
102
+ """Delete memory files whose resolution_status is not 'RESOLVED'."""
103
+ memory_path = os.path.join(self.memory_folder, CONFORMANCE_TEST_MEMORY_SUBFOLDER)
104
+ if not os.path.exists(memory_path):
105
+ return
106
+
107
+ memory_files = file_utils.list_all_text_files(memory_path)
108
+ for file_name in memory_files:
109
+ file_path = os.path.join(memory_path, file_name)
110
+ try:
111
+ with open(file_path, "r") as f:
112
+ content = json.load(f)
113
+ if content.get("resolution_status") == "RESOLVED":
114
+ continue
115
+ else:
116
+ os.remove(file_path)
117
+ except (json.JSONDecodeError, OSError):
118
+ # Not a valid JSON file, unlikely to be a valid memory file, delete it
119
+ console.error(f"Memory file is not a valid JSON file: {file_name}. Deleting it.")
120
+ os.remove(file_path)
121
+
122
+ console.debug(f"Deleted temporary memory file: {file_name}")
@@ -97,7 +97,7 @@ class Plain2CodeConsole(Console):
97
97
 
98
98
  def print_resources(self, resources_list, linked_resources):
99
99
  if len(resources_list) == 0:
100
- self.input("No linked resources found.")
100
+ self.input("Linked resources: None")
101
101
  return
102
102
 
103
103
  self.input("Linked resources:")
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "codeplain"
7
- version = "0.2.11"
7
+ dynamic = ["version"]
8
8
  description = "Transform plain language specifications into working code"
9
9
  readme = "README.md"
10
10
  requires-python = "==3.11"
@@ -40,6 +40,9 @@ dev = [
40
40
  [project.scripts]
41
41
  codeplain = "plain2code:main"
42
42
 
43
+ [tool.hatch.version]
44
+ path = "_version.py"
45
+
43
46
  [tool.hatch.build.targets.wheel]
44
47
  include = [
45
48
  "*.py",
@@ -7,6 +7,7 @@ from plain2code_console import console
7
7
  from plain2code_exceptions import InternalClientError
8
8
  from plain2code_utils import AMBIGUITY_CAUSES
9
9
  from render_machine.actions.base_action import BaseAction
10
+ from render_machine.implementation_code_helpers import ImplementationCodeHelpers
10
11
  from render_machine.render_context import RenderContext
11
12
 
12
13
 
@@ -14,19 +15,21 @@ class AnalyzeSpecificationAmbiguity(BaseAction):
14
15
  SUCCESSFUL_OUTCOME = "conformance_tests_postanalyzed"
15
16
 
16
17
  def execute(self, render_context: RenderContext, _previous_action_payload: Any | None):
17
- fixed_implementation_code_diff = git_utils.get_fixed_implementation_code_diff(
18
+
19
+ fixed_implementation_code_diff = ImplementationCodeHelpers.get_fixed_implementation_code_diff(
18
20
  render_context.build_folder, render_context.frid_context.frid
19
21
  )
20
22
  if fixed_implementation_code_diff is None:
21
23
  raise InternalClientError(
22
24
  "Fixes to the implementation code found during conformance testing are not committed to git."
23
25
  )
26
+
24
27
  previous_frid = plain_spec.get_previous_frid(render_context.plain_source_tree, render_context.frid_context.frid)
25
28
  git_utils.checkout_commit_with_frid(render_context.build_folder, previous_frid)
26
29
  existing_files = file_utils.list_all_text_files(render_context.build_folder)
27
30
  existing_files_content = file_utils.get_existing_files_content(render_context.build_folder, existing_files)
28
31
  git_utils.checkout_previous_branch(render_context.build_folder)
29
- implementation_code_diff = git_utils.get_implementation_code_diff(
32
+ implementation_code_diff = ImplementationCodeHelpers.get_implementation_code_diff(
30
33
  render_context.build_folder, render_context.frid_context.frid, previous_frid
31
34
  )
32
35
  rendering_analysis = render_context.codeplain_api.analyze_rendering(
@@ -54,9 +54,7 @@ class RunConformanceTests(BaseAction):
54
54
  )
55
55
 
56
56
  if exit_code == 0:
57
- conformance_tests_issue = "All conformance tests passed successfully!"
58
-
59
- if exit_code == 0:
57
+ render_context.memory_manager.delete_unresolved_memory_files()
60
58
  return self.SUCCESSFUL_OUTCOME, None
61
59
 
62
60
  if exit_code in UNRECOVERABLE_ERROR_EXIT_CODES:
@@ -0,0 +1,49 @@
1
+ import json
2
+
3
+ import file_utils
4
+ import git_utils
5
+ import plain_spec
6
+
7
+
8
+ class ImplementationCodeHelpers:
9
+ @staticmethod
10
+ def calculate_build_folder_hash(build_folder: str) -> str:
11
+ _, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(build_folder)
12
+ return plain_spec.hash_text(f"folder={build_folder}|{json.dumps(existing_files_content)}")
13
+
14
+ @staticmethod
15
+ def fetch_existing_files(build_folder: str):
16
+ existing_files = file_utils.list_all_text_files(build_folder)
17
+ existing_files_content = file_utils.get_existing_files_content(build_folder, existing_files)
18
+ return existing_files, existing_files_content
19
+
20
+ @staticmethod
21
+ def remove_system_folder_paths_from_code_diff(code_diff: dict):
22
+ for file_name in list(code_diff.keys()):
23
+ if file_utils.is_system_folder_path(file_name):
24
+ del code_diff[file_name]
25
+
26
+ return code_diff
27
+
28
+ @staticmethod
29
+ def get_code_diff(build_folder: str, plain_source_tree: dict, frid: str):
30
+ previous_frid_code_diff = git_utils.diff(
31
+ build_folder,
32
+ plain_spec.get_previous_frid(plain_source_tree, frid),
33
+ )
34
+
35
+ return ImplementationCodeHelpers.remove_system_folder_paths_from_code_diff(previous_frid_code_diff)
36
+
37
+ @staticmethod
38
+ def get_fixed_implementation_code_diff(build_folder: str, frid: str):
39
+ fixed_implementation_code_diff = git_utils.get_fixed_implementation_code_diff(build_folder, frid)
40
+ if fixed_implementation_code_diff is None:
41
+ return None
42
+
43
+ return ImplementationCodeHelpers.remove_system_folder_paths_from_code_diff(fixed_implementation_code_diff)
44
+
45
+ @staticmethod
46
+ def get_implementation_code_diff(build_folder: str, frid: str, previous_frid: str):
47
+ implementation_code_diff = git_utils.get_implementation_code_diff(build_folder, frid, previous_frid)
48
+
49
+ return ImplementationCodeHelpers.remove_system_folder_paths_from_code_diff(implementation_code_diff)
@@ -2,8 +2,6 @@
2
2
 
3
3
  - :App: is a console application.
4
4
 
5
- - :Unittests: are the unit tests of :App: and are part of :Implementation:.
6
-
7
5
  - :MainExecutableFile: is the main executable code file of :App:.
8
6
 
9
7
 
@@ -11,7 +9,7 @@
11
9
 
12
10
  - :Implementation: should be in Python.
13
11
 
14
- - :Implementation: should include :Unittests: using Unittest framework! If :Unittests: are put in the subfolder, make sure to include __init__.py to make them discoverable.
12
+ - :Implementation: should include :UnitTests: using Unittest framework! If :UnitTests: are put in the subfolder, make sure to include __init__.py to make them discoverable.
15
13
 
16
14
  ***test reqs***
17
15
 
@@ -3,6 +3,7 @@ import sys
3
3
 
4
4
  import yaml
5
5
 
6
+ from _version import __version__
6
7
  from plain2code_console import console
7
8
 
8
9
 
@@ -11,12 +12,10 @@ class SystemConfig:
11
12
 
12
13
  def __init__(self):
13
14
  self.config = self._load_config()
14
- if "client_version" not in self.config:
15
- raise KeyError("Missing 'client_version' in system_config.yaml")
16
15
  if "error_messages" not in self.config:
17
16
  raise KeyError("Missing 'error_messages' section in system_config.yaml")
18
17
 
19
- self.client_version = self.config["client_version"]
18
+ self.client_version = __version__
20
19
  self.error_messages = self.config["error_messages"]
21
20
 
22
21
  def _load_config(self):
@@ -5,4 +5,4 @@ import:
5
5
 
6
6
  ***implementation reqs***
7
7
 
8
- - :Implementation: should include :Unittests: using Unittest framework!
8
+ - :Implementation: should include :UnitTests: using Unittest framework!
@@ -1,26 +0,0 @@
1
- import json
2
-
3
- import file_utils
4
- import git_utils
5
- import plain_spec
6
-
7
-
8
- class ImplementationCodeHelpers:
9
- @staticmethod
10
- def calculate_build_folder_hash(build_folder: str) -> str:
11
- _, existing_files_content = ImplementationCodeHelpers.fetch_existing_files(build_folder)
12
- return plain_spec.hash_text(f"folder={build_folder}|{json.dumps(existing_files_content)}")
13
-
14
- @staticmethod
15
- def fetch_existing_files(build_folder: str):
16
- existing_files = file_utils.list_all_text_files(build_folder)
17
- existing_files_content = file_utils.get_existing_files_content(build_folder, existing_files)
18
- return existing_files, existing_files_content
19
-
20
- @staticmethod
21
- def get_code_diff(build_folder: str, plain_source_tree: dict, frid: str):
22
- previous_frid_code_diff = git_utils.diff(
23
- build_folder,
24
- plain_spec.get_previous_frid(plain_source_tree, frid),
25
- )
26
- return previous_frid_code_diff
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