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.
- {codeplain-0.2.11 → codeplain-0.2.12}/PKG-INFO +1 -1
- codeplain-0.2.12/_version.py +1 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/config/system_config.yaml +0 -2
- {codeplain-0.2.11 → codeplain-0.2.12}/docs/plain_language_specification.md +30 -67
- {codeplain-0.2.11 → codeplain-0.2.12}/file_utils.py +5 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/memory_management.py +25 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_console.py +1 -1
- {codeplain-0.2.11 → codeplain-0.2.12}/pyproject.toml +4 -1
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/analyze_specification_ambiguity.py +5 -2
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/run_conformance_tests.py +1 -3
- codeplain-0.2.12/render_machine/implementation_code_helpers.py +49 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/python-console-app-template.plain +1 -3
- {codeplain-0.2.11 → codeplain-0.2.12}/system_config.py +2 -3
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/circular_imports_2.plain +1 -1
- codeplain-0.2.11/render_machine/implementation_code_helpers.py +0 -26
- {codeplain-0.2.11 → codeplain-0.2.12}/.flake8 +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/.github/workflows/publish-to-pypi.yml +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/.gitignore +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/.vscode/launch.json +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/.vscode/settings.json +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/LICENSE +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/README.md +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/codeplain_REST_api.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/concept_utils.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/config/__init__.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/diff_utils.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/docs/generate_cli.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/docs/plain2code_cli.md +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/event_bus.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/config.yaml +0 -0
- {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
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/examples/run.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/git_utils.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/hash_key.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/install/bash/examples.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/install/bash/install.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/install/powershell/examples.ps1 +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/install/powershell/install.ps1 +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/install/powershell/walkthrough.ps1 +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/module_renderer.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_arguments.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_events.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_exceptions.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_logger.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_nodes.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_read_config.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_state.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain2code_utils.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain_file.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain_modules.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/plain_spec.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/pytest.ini +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/__init__.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/fix_conformance_test.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/prepare_repositories.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/code_renderer.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/conformance_test_helpers.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/render_context.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/render_types.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/render_utils.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/states.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/render_machine/triggers.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/requirements.txt +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/resources/codeplain_overview.png +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/resources/plain_example.png +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/__init__.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/__init__.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/conftest.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/simple.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/header.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_git_utils.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_imports.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_plainfile.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_plainfileparser.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_plainspec.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tests/test_requires.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/__init__.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/components.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/models.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/plain2code_tui.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/spinner.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/state_handlers.py +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/styles.css +0 -0
- {codeplain-0.2.11 → codeplain-0.2.12}/tui/widget_helpers.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.12"
|
|
@@ -13,68 +13,31 @@
|
|
|
13
13
|
Here's an example of a "hello, world" program in ***plain.
|
|
14
14
|
|
|
15
15
|
```plain
|
|
16
|
-
***
|
|
16
|
+
***implementation reqs***
|
|
17
17
|
|
|
18
18
|
- :Implementation: should be in Python.
|
|
19
19
|
|
|
20
|
-
***
|
|
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
|
-
- `***
|
|
67
|
-
- `***
|
|
68
|
-
- `***
|
|
69
|
-
- `***
|
|
29
|
+
- `***definitions***`
|
|
30
|
+
- `***implementation reqs***`
|
|
31
|
+
- `***functional specs***`
|
|
32
|
+
- `***test reqs***`
|
|
70
33
|
|
|
71
|
-
Every plain source file requires at least one functional
|
|
34
|
+
Every plain source file requires at least one functional spec and an associated implementation req.
|
|
72
35
|
|
|
73
|
-
Functional
|
|
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 `***
|
|
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 ***
|
|
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
|
-
##
|
|
77
|
+
## Implementation Reqs
|
|
115
78
|
|
|
116
|
-
The `***
|
|
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
|
|
99
|
+
## Functional Specs
|
|
137
100
|
|
|
138
|
-
The `***
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 `***
|
|
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
|
-
***
|
|
150
|
+
***functional specs***
|
|
188
151
|
|
|
189
152
|
- Display "hello, world"
|
|
190
153
|
|
|
191
|
-
***
|
|
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 ***
|
|
159
|
+
Acceptance tests extend **conformance tests**. The acceptance tests are implemented according to the ***test reqs*** specification (see below).
|
|
197
160
|
|
|
198
|
-
## Test
|
|
161
|
+
## Test Reqs
|
|
199
162
|
|
|
200
|
-
The `***
|
|
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
|
|
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
|
|
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("
|
|
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
|
-
|
|
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",
|
{codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/analyze_specification_ambiguity.py
RENAMED
|
@@ -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
|
-
|
|
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 =
|
|
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
|
-
|
|
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)
|
{codeplain-0.2.11 → codeplain-0.2.12}/standard_template_library/python-console-app-template.plain
RENAMED
|
@@ -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 :
|
|
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 =
|
|
18
|
+
self.client_version = __version__
|
|
20
19
|
self.error_messages = self.config["error_messages"]
|
|
21
20
|
|
|
22
21
|
def _load_config(self):
|
|
@@ -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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_golang/hello_world_golang.plain
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_python/hello_world_python.plain
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.2.11 → codeplain-0.2.12}/examples/example_hello_world_react/hello_world_react.plain
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/commit_conformance_tests_changes.py
RENAMED
|
File without changes
|
{codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/commit_implementation_code_changes.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.2.11 → codeplain-0.2.12}/render_machine/actions/finish_functional_requirement.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|