codeplain 0.2.6__tar.gz → 0.2.8__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.6 → codeplain-0.2.8}/PKG-INFO +2 -2
- {codeplain-0.2.6 → codeplain-0.2.8}/config/system_config.yaml +1 -1
- codeplain-0.2.8/docs/plain2code_cli.md +63 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/git_utils.py +20 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/install/walkthrough.sh +47 -50
- {codeplain-0.2.6 → codeplain-0.2.8}/module_renderer.py +8 -1
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code.py +43 -5
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_arguments.py +26 -21
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_events.py +2 -1
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_utils.py +5 -5
- {codeplain-0.2.6 → codeplain-0.2.8}/pyproject.toml +2 -2
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/plain2code_tui.py +7 -7
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/state_handlers.py +8 -4
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/widget_helpers.py +11 -3
- codeplain-0.2.6/docs/plain2code_cli.md +0 -66
- {codeplain-0.2.6 → codeplain-0.2.8}/.flake8 +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/.github/workflows/publish-to-pypi.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/.gitignore +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/.vscode/launch.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/.vscode/settings.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/LICENSE +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/README.md +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/codeplain_REST_api.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/concept_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/config/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/diff_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/docs/generate_cli.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/docs/plain_language_specification.md +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/event_bus.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/examples/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/file_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/hash_key.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/install/examples.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/install/install.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/memory_management.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_console.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_exceptions.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_logger.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_nodes.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_read_config.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain2code_state.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain_file.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain_modules.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/plain_spec.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/pytest.ini +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/fix_conformance_test.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/prepare_repositories.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/run_conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/code_renderer.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/conformance_test_helpers.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/implementation_code_helpers.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/render_context.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/render_types.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/render_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/states.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/render_machine/triggers.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/requirements.txt +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/resources/codeplain_overview.png +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/resources/plain_example.png +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/standard_template_library/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/system_config.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/conftest.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/simple.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/templates/header.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/test_git_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/test_imports.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/test_plainfile.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/test_plainfileparser.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/test_plainspec.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tests/test_requires.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/components.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/models.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/spinner.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.8}/tui/styles.css +0 -0
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codeplain
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Transform plain language specifications into working code
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Classifier: Environment :: Console
|
|
7
7
|
Classifier: Intended Audience :: Developers
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
|
9
9
|
Classifier: Topic :: Software Development :: Code Generators
|
|
10
|
-
Requires-Python:
|
|
10
|
+
Requires-Python: ~=3.11.0
|
|
11
11
|
Requires-Dist: gitpython==3.1.42
|
|
12
12
|
Requires-Dist: mistletoe==1.3.0
|
|
13
13
|
Requires-Dist: networkx==3.6.1
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# Plain2Code CLI Reference
|
|
2
|
+
|
|
3
|
+
```text
|
|
4
|
+
usage: generate_cli.py [-h] [--verbose] [--base-folder BASE_FOLDER] [--build-folder BUILD_FOLDER] [--log-to-file | --no-log-to-file] [--log-file-name LOG_FILE_NAME] [--config-name CONFIG_NAME] [--render-range RENDER_RANGE | --render-from RENDER_FROM] [--force-render]
|
|
5
|
+
[--unittests-script UNITTESTS_SCRIPT] [--conformance-tests-folder CONFORMANCE_TESTS_FOLDER] [--conformance-tests-script CONFORMANCE_TESTS_SCRIPT] [--prepare-environment-script PREPARE_ENVIRONMENT_SCRIPT] [--api [API]] [--api-key API_KEY]
|
|
6
|
+
[--full-plain] [--dry-run] [--replay-with REPLAY_WITH] [--template-dir TEMPLATE_DIR] [--copy-build] [--build-dest BUILD_DEST] [--copy-conformance-tests] [--conformance-tests-dest CONFORMANCE_TESTS_DEST] [--render-machine-graph]
|
|
7
|
+
[--logging-config-path]
|
|
8
|
+
filename
|
|
9
|
+
|
|
10
|
+
Render plain code to target code.
|
|
11
|
+
|
|
12
|
+
positional arguments:
|
|
13
|
+
filename Path to the plain file to render. The directory containing this file has highest precedence for template loading, so you can place custom templates here to override the defaults. See --template-dir for more details about template loading.
|
|
14
|
+
|
|
15
|
+
options:
|
|
16
|
+
-h, --help show this help message and exit
|
|
17
|
+
--verbose, -v Enable verbose output
|
|
18
|
+
--base-folder BASE_FOLDER
|
|
19
|
+
Base folder for the build files
|
|
20
|
+
--build-folder BUILD_FOLDER
|
|
21
|
+
Folder for build files
|
|
22
|
+
--log-to-file, --no-log-to-file
|
|
23
|
+
Enable logging to a file. Defaults to True. Use --no-log-to-file to disable.
|
|
24
|
+
--log-file-name LOG_FILE_NAME
|
|
25
|
+
Name of the log file. Defaults to 'codeplain.log'.Always resolved relative to the plain file directory.If file on this path already exists, it will be overwritten by the current logs.
|
|
26
|
+
--render-range RENDER_RANGE
|
|
27
|
+
Specify a range of functional requirements to render (e.g. '1.1,2.3'). Use comma to separate start and end IDs. If only one ID is provided, only that requirement is rendered. Range is inclusive of both start and end IDs.
|
|
28
|
+
--render-from RENDER_FROM
|
|
29
|
+
Continue generation starting from this specific functional requirement (e.g. '2.1'). The requirement with this ID will be included in the output. The ID must match one of the functional requirements in your plain file.
|
|
30
|
+
--force-render Force re-render of all the required modules.
|
|
31
|
+
--unittests-script UNITTESTS_SCRIPT
|
|
32
|
+
Shell script to run unit tests on generated code. Receives the build folder path as its first argument (default: 'plain_modules').
|
|
33
|
+
--conformance-tests-folder CONFORMANCE_TESTS_FOLDER
|
|
34
|
+
Folder for conformance test files
|
|
35
|
+
--conformance-tests-script CONFORMANCE_TESTS_SCRIPT
|
|
36
|
+
Path to conformance tests shell script. The script should accept two arguments: 1) First argument: path to a folder (e.g. 'plain_modules/module_name') containing generated source code, 2) Second argument: path to a subfolder of the conformance
|
|
37
|
+
tests folder (e.g. 'conformance_tests/subfoldername') containing test files.
|
|
38
|
+
--prepare-environment-script PREPARE_ENVIRONMENT_SCRIPT
|
|
39
|
+
Path to a shell script that prepares the testing environment. The script should accept the build folder path as its first argument (default: 'plain_modules').
|
|
40
|
+
--api [API] Alternative base URL for the API. Default: `https://api.codeplain.ai`
|
|
41
|
+
--api-key API_KEY API key used to access the API. If not provided, the CODEPLAIN_API_KEY environment variable is used.
|
|
42
|
+
--full-plain Display the complete plain specification before code generation. This shows your plain file with any included template content expanded. Useful for understanding what content is being processed.
|
|
43
|
+
--dry-run Preview of what Codeplain would do without actually making any changes.
|
|
44
|
+
--replay-with REPLAY_WITH
|
|
45
|
+
--template-dir TEMPLATE_DIR
|
|
46
|
+
Path to a custom template directory. Templates are searched in the following order: 1) directory containing the plain file, 2) this custom template directory (if provided), 3) built-in standard_template_library directory
|
|
47
|
+
--copy-build If set, copy the build folder to `--build-dest` after every successful rendering.
|
|
48
|
+
--build-dest BUILD_DEST
|
|
49
|
+
Target folder to copy build output to (used only if --copy-build is set).
|
|
50
|
+
--copy-conformance-tests
|
|
51
|
+
If set, copy the conformance tests folder to `--conformance-tests-dest` after every successful rendering. Requires --conformance-tests-script.
|
|
52
|
+
--conformance-tests-dest CONFORMANCE_TESTS_DEST
|
|
53
|
+
Target folder to copy conformance tests output to (used only if --copy-conformance-tests is set).
|
|
54
|
+
--render-machine-graph
|
|
55
|
+
If set, render the state machine graph.
|
|
56
|
+
--logging-config-path
|
|
57
|
+
Path to the logging configuration file.
|
|
58
|
+
|
|
59
|
+
configuration:
|
|
60
|
+
--config-name CONFIG_NAME
|
|
61
|
+
Path to the config file, defaults to config.yaml
|
|
62
|
+
|
|
63
|
+
```
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from configparser import NoOptionError, NoSectionError
|
|
2
3
|
from typing import Optional, Union
|
|
3
4
|
|
|
4
5
|
from git import Repo
|
|
@@ -42,6 +43,24 @@ def _get_full_commit_message(message, module_name, frid, render_id) -> str:
|
|
|
42
43
|
return full_message
|
|
43
44
|
|
|
44
45
|
|
|
46
|
+
def _ensure_git_config(repo: Repo) -> None:
|
|
47
|
+
config = repo.config_reader()
|
|
48
|
+
|
|
49
|
+
try:
|
|
50
|
+
config.get_value("user", "name")
|
|
51
|
+
except (NoSectionError, NoOptionError):
|
|
52
|
+
# user.name not configured, set a default at repo level
|
|
53
|
+
with repo.config_writer(config_level="repository") as writer:
|
|
54
|
+
writer.set_value("user", "name", "Codeplain")
|
|
55
|
+
|
|
56
|
+
try:
|
|
57
|
+
config.get_value("user", "email")
|
|
58
|
+
except (NoSectionError, NoOptionError):
|
|
59
|
+
# user.email not configured, set a default at repo level
|
|
60
|
+
with repo.config_writer(config_level="repository") as writer:
|
|
61
|
+
writer.set_value("user", "email", "codeplain@localhost")
|
|
62
|
+
|
|
63
|
+
|
|
45
64
|
def init_git_repo(
|
|
46
65
|
path_to_repo: Union[str, os.PathLike], module_name: Optional[str] = None, render_id: Optional[str] = None
|
|
47
66
|
) -> Repo:
|
|
@@ -56,6 +75,7 @@ def init_git_repo(
|
|
|
56
75
|
os.makedirs(path_to_repo)
|
|
57
76
|
|
|
58
77
|
repo = Repo.init(path_to_repo)
|
|
78
|
+
_ensure_git_config(repo)
|
|
59
79
|
repo.git.commit(
|
|
60
80
|
"--allow-empty", "-m", _get_full_commit_message(INITIAL_COMMIT_MESSAGE, module_name, None, render_id)
|
|
61
81
|
)
|
|
@@ -13,13 +13,13 @@ NC="${NC:-\033[0m}"
|
|
|
13
13
|
# Onboarding Step 1: Introduction to Plain
|
|
14
14
|
clear
|
|
15
15
|
echo ""
|
|
16
|
-
echo -e "${GRAY}
|
|
17
|
-
echo -e " ${YELLOW}${BOLD}
|
|
18
|
-
echo -e "${GRAY}
|
|
16
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
17
|
+
echo -e " ${YELLOW}${BOLD}***plain specification language intro${NC} - Step 1 of 5"
|
|
18
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
19
19
|
echo ""
|
|
20
|
-
echo -e " ***plain is a language of spec-driven development that allows developers to express intent
|
|
20
|
+
echo -e " ***plain is a language of spec-driven development that allows developers to express intent at any level of detail."
|
|
21
21
|
echo ""
|
|
22
|
-
echo -e " write specs in
|
|
22
|
+
echo -e " write specs in natural language extended with additional syntax based on markdown."
|
|
23
23
|
echo ""
|
|
24
24
|
echo -e " render production-ready code with *codeplain."
|
|
25
25
|
echo ""
|
|
@@ -28,8 +28,8 @@ echo ""
|
|
|
28
28
|
echo -e "${GRAY} ┌────────────────────────────────────────────────────────┐${NC}"
|
|
29
29
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
30
30
|
echo -e "${GRAY} │${NC} ${YELLOW}***definitions***${NC} - key concepts in your app ${GRAY}│${NC}"
|
|
31
|
-
echo -e "${GRAY} │${NC} ${YELLOW}***implementation reqs***${NC} - implementation details
|
|
32
|
-
echo -e "${GRAY} │${NC} ${YELLOW}***test reqs***${NC} - testing requirements
|
|
31
|
+
echo -e "${GRAY} │${NC} ${YELLOW}***implementation reqs***${NC} - implementation details ${GRAY}│${NC}"
|
|
32
|
+
echo -e "${GRAY} │${NC} ${YELLOW}***test reqs***${NC} - testing requirements ${GRAY}│${NC}"
|
|
33
33
|
echo -e "${GRAY} │${NC} ${YELLOW}***functional specs***${NC} - what the app should do ${GRAY}│${NC}"
|
|
34
34
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
35
35
|
echo -e "${GRAY} └────────────────────────────────────────────────────────┘${NC}"
|
|
@@ -41,33 +41,32 @@ read -r -p " press [Enter] to continue..." < /dev/tty
|
|
|
41
41
|
# Onboarding Step 2: Functional Specification
|
|
42
42
|
clear
|
|
43
43
|
echo ""
|
|
44
|
-
echo -e "${GRAY}
|
|
45
|
-
echo -e " ${YELLOW}${BOLD}
|
|
46
|
-
echo -e "${GRAY}
|
|
44
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
45
|
+
echo -e " ${YELLOW}${BOLD}***plain specification language intro${NC} - Step 2 of 5"
|
|
46
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
47
47
|
echo ""
|
|
48
48
|
echo -e " ${WHITE}${BOLD}FUNCTIONAL SPECS${NC} - what should the app do?"
|
|
49
49
|
echo ""
|
|
50
50
|
echo -e " This is where you describe ${GREEN}what your app should do${NC},"
|
|
51
|
-
echo -e " written in
|
|
51
|
+
echo -e " written in natural language. No code, just requirements."
|
|
52
52
|
echo ""
|
|
53
53
|
echo -e "${GRAY} ┌────────────────────────────────────────────────────────┐${NC}"
|
|
54
54
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
55
|
-
echo -e "${GRAY} │${NC} ${GRAY}***definitions***${NC}
|
|
55
|
+
echo -e "${GRAY} │${NC} ${GRAY}***definitions***${NC} ${GRAY}│${NC}"
|
|
56
56
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
57
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :App: is a console application.${NC}
|
|
57
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :App: is a console application.${NC} ${GRAY}│${NC}"
|
|
58
58
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
59
|
-
echo -e "${GRAY} │${NC} ${GRAY}***implementation reqs***${NC}
|
|
59
|
+
echo -e "${GRAY} │${NC} ${GRAY}***implementation reqs***${NC} ${GRAY}│${NC}"
|
|
60
60
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
61
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :Implementation: should be in Python.${NC}
|
|
62
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :UnitTests: should use Unittest framework.${NC} ${GRAY}│${NC}"
|
|
61
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :Implementation: should be in Python.${NC} ${GRAY}│${NC}"
|
|
63
62
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
64
|
-
echo -e "${GRAY} │${NC} ${GRAY}***test reqs***${NC}
|
|
63
|
+
echo -e "${GRAY} │${NC} ${GRAY}***test reqs***${NC} ${GRAY}│${NC}"
|
|
65
64
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
66
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :ConformanceTests: should use
|
|
65
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :ConformanceTests: should use pytest.${NC} ${GRAY}│${NC}"
|
|
67
66
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
68
|
-
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***functional specs***${NC}
|
|
67
|
+
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***functional specs***${NC} ${GRAY}│${NC}"
|
|
69
68
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
70
|
-
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :App: should display \"hello, world\".${NC}
|
|
69
|
+
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :App: should display \"hello, world\".${NC} ${GRAY}│${NC}"
|
|
71
70
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
72
71
|
echo -e "${GRAY} └────────────────────────────────────────────────────────┘${NC}"
|
|
73
72
|
echo ""
|
|
@@ -79,37 +78,36 @@ read -r -p " press [Enter] to continue..." < /dev/tty
|
|
|
79
78
|
# Onboarding Step 3: Definitions
|
|
80
79
|
clear
|
|
81
80
|
echo ""
|
|
82
|
-
echo -e "${GRAY}
|
|
83
|
-
echo -e " ${YELLOW}${BOLD}
|
|
84
|
-
echo -e "${GRAY}
|
|
81
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
82
|
+
echo -e " ${YELLOW}${BOLD}***plain specification language intro${NC} - Step 3 of 5"
|
|
83
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
85
84
|
echo ""
|
|
86
|
-
echo -e " ${WHITE}${BOLD}DEFINITIONS${NC} -
|
|
85
|
+
echo -e " ${WHITE}${BOLD}DEFINITIONS${NC} - definitions and descriptions of key concepts"
|
|
87
86
|
echo ""
|
|
88
|
-
echo -e " Define ${GREEN}reusable concepts${NC}
|
|
87
|
+
echo -e " Define ${GREEN}reusable concepts${NC} using the ${YELLOW}:Concept:${NC} notation."
|
|
89
88
|
echo -e " These become building blocks you can reference anywhere."
|
|
90
89
|
echo ""
|
|
91
90
|
echo -e "${GRAY} ┌────────────────────────────────────────────────────────┐${NC}"
|
|
92
91
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
93
|
-
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***definitions***${NC}
|
|
92
|
+
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***definitions***${NC} ${GRAY}│${NC}"
|
|
94
93
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
95
|
-
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :App: is a console application.${NC}
|
|
94
|
+
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :App: is a console application.${NC} ${GRAY}│${NC}"
|
|
96
95
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
97
|
-
echo -e "${GRAY} │${NC} ${GRAY}***implementation reqs***${NC}
|
|
96
|
+
echo -e "${GRAY} │${NC} ${GRAY}***implementation reqs***${NC} ${GRAY}│${NC}"
|
|
98
97
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
99
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :Implementation: should be in Python.${NC}
|
|
100
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :UnitTests: should use Unittest framework.${NC} ${GRAY}│${NC}"
|
|
98
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :Implementation: should be in Python.${NC} ${GRAY}│${NC}"
|
|
101
99
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
102
|
-
echo -e "${GRAY} │${NC} ${GRAY}***test reqs***${NC}
|
|
100
|
+
echo -e "${GRAY} │${NC} ${GRAY}***test reqs***${NC} ${GRAY}│${NC}"
|
|
103
101
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
104
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :ConformanceTests: should use
|
|
102
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :ConformanceTests: should use pytest.${NC} ${GRAY}│${NC}"
|
|
105
103
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
106
|
-
echo -e "${GRAY} │${NC} ${GRAY}***functional specs***${NC}
|
|
104
|
+
echo -e "${GRAY} │${NC} ${GRAY}***functional specs***${NC} ${GRAY}│${NC}"
|
|
107
105
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
108
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :App: should display \"hello, world\".${NC}
|
|
106
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :App: should display \"hello, world\".${NC} ${GRAY}│${NC}"
|
|
109
107
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
110
108
|
echo -e "${GRAY} └────────────────────────────────────────────────────────┘${NC}"
|
|
111
109
|
echo ""
|
|
112
|
-
echo -e " ${GREEN}▲${NC} The ${YELLOW}:App:${NC} concept is defined once and used throughout."
|
|
110
|
+
echo -e " ${GREEN}▲${NC} The ${YELLOW}:App:${NC} concept is defined once and used throughout the specs."
|
|
113
111
|
echo -e " Concepts help keep your specs consistent and clear."
|
|
114
112
|
echo ""
|
|
115
113
|
read -r -p " press [Enter] to continue..." < /dev/tty
|
|
@@ -117,9 +115,9 @@ read -r -p " press [Enter] to continue..." < /dev/tty
|
|
|
117
115
|
# Onboarding Step 4: Implementation & Test Reqs
|
|
118
116
|
clear
|
|
119
117
|
echo ""
|
|
120
|
-
echo -e "${GRAY}
|
|
121
|
-
echo -e " ${YELLOW}${BOLD}
|
|
122
|
-
echo -e "${GRAY}
|
|
118
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
119
|
+
echo -e " ${YELLOW}${BOLD}***plain specification language intro${NC} - Step 4 of 5"
|
|
120
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
123
121
|
echo ""
|
|
124
122
|
echo -e " ${WHITE}${BOLD}IMPLEMENTATION & TEST REQS${NC} - how to implement and test"
|
|
125
123
|
echo ""
|
|
@@ -128,22 +126,21 @@ echo -e " This guides how the code should be generated and verified."
|
|
|
128
126
|
echo ""
|
|
129
127
|
echo -e "${GRAY} ┌────────────────────────────────────────────────────────┐${NC}"
|
|
130
128
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
131
|
-
echo -e "${GRAY} │${NC} ${GRAY}***definitions***${NC}
|
|
129
|
+
echo -e "${GRAY} │${NC} ${GRAY}***definitions***${NC} ${GRAY}│${NC}"
|
|
132
130
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
133
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :App: is a console application.${NC}
|
|
131
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :App: is a console application.${NC} ${GRAY}│${NC}"
|
|
134
132
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
135
|
-
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***implementation reqs***${NC}
|
|
133
|
+
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***implementation reqs***${NC} ${GRAY}│${NC}"
|
|
136
134
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
137
|
-
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :Implementation: should be in Python.${NC}
|
|
138
|
-
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :UnitTests: should use Unittest framework.${NC} ${GRAY}│${NC}"
|
|
135
|
+
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :Implementation: should be in Python.${NC} ${GRAY}│${NC}"
|
|
139
136
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
140
|
-
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***test reqs***${NC}
|
|
137
|
+
echo -e "${GRAY} │${NC} ${YELLOW}${BOLD}***test reqs***${NC} ${GRAY}│${NC}"
|
|
141
138
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
142
|
-
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :ConformanceTests: should use
|
|
139
|
+
echo -e "${GRAY} │${NC} ${GREEN}${BOLD}- :ConformanceTests: should use pytest.${NC} ${GRAY}│${NC}"
|
|
143
140
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
144
|
-
echo -e "${GRAY} │${NC} ${GRAY}***functional specs***${NC}
|
|
141
|
+
echo -e "${GRAY} │${NC} ${GRAY}***functional specs***${NC} ${GRAY}│${NC}"
|
|
145
142
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
146
|
-
echo -e "${GRAY} │${NC} ${GRAY}- :App: should display \"hello, world\".${NC}
|
|
143
|
+
echo -e "${GRAY} │${NC} ${GRAY}- :App: should display \"hello, world\".${NC} ${GRAY}│${NC}"
|
|
147
144
|
echo -e "${GRAY} │${NC} ${GRAY}│${NC}"
|
|
148
145
|
echo -e "${GRAY} └────────────────────────────────────────────────────────┘${NC}"
|
|
149
146
|
echo ""
|
|
@@ -155,9 +152,9 @@ read -r -p " press [Enter] to continue..." < /dev/tty
|
|
|
155
152
|
# Onboarding Step 5: Rendering Code
|
|
156
153
|
clear
|
|
157
154
|
echo ""
|
|
158
|
-
echo -e "${GRAY}
|
|
159
|
-
echo -e " ${YELLOW}${BOLD}
|
|
160
|
-
echo -e "${GRAY}
|
|
155
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
156
|
+
echo -e " ${YELLOW}${BOLD}***plain specification language intro${NC} - Step 5 of 5"
|
|
157
|
+
echo -e "${GRAY}─────────────────────────────────────────────────────────${NC}"
|
|
161
158
|
echo ""
|
|
162
159
|
echo -e " ${WHITE}${BOLD}RENDERING CODE${NC} - generate your app"
|
|
163
160
|
echo ""
|
|
@@ -260,4 +260,11 @@ class ModuleRenderer:
|
|
|
260
260
|
self.loaded_modules = list[PlainModule]()
|
|
261
261
|
_, _, rendering_failed = self._render_module(self.filename, self.render_range, True)
|
|
262
262
|
if not rendering_failed:
|
|
263
|
-
|
|
263
|
+
# Get the last module that completed rendering
|
|
264
|
+
if self.args.copy_build:
|
|
265
|
+
rendered_code_path = f"{self.args.build_dest}/"
|
|
266
|
+
else:
|
|
267
|
+
last_module_name = self.filename.replace(plain_file.PLAIN_SOURCE_FILE_EXTENSION, "")
|
|
268
|
+
rendered_code_path = f"{os.path.join(self.args.build_folder, last_module_name)}/"
|
|
269
|
+
|
|
270
|
+
self.event_bus.publish(RenderCompleted(rendered_code_path=rendered_code_path))
|
|
@@ -3,6 +3,7 @@ import logging
|
|
|
3
3
|
import logging.config
|
|
4
4
|
import os
|
|
5
5
|
import sys
|
|
6
|
+
from pathlib import Path
|
|
6
7
|
from typing import Optional
|
|
7
8
|
|
|
8
9
|
import yaml
|
|
@@ -42,6 +43,7 @@ from plain2code_logger import (
|
|
|
42
43
|
get_log_file_path,
|
|
43
44
|
)
|
|
44
45
|
from plain2code_state import RunState
|
|
46
|
+
from plain2code_utils import print_dry_run_output
|
|
45
47
|
from system_config import system_config
|
|
46
48
|
from tui.plain2code_tui import Plain2CodeTUI
|
|
47
49
|
|
|
@@ -72,6 +74,23 @@ def get_render_range_from(start, plain_source):
|
|
|
72
74
|
return _get_frids_range(plain_source, start)
|
|
73
75
|
|
|
74
76
|
|
|
77
|
+
def compute_render_range(args, plain_source_tree):
|
|
78
|
+
"""Compute render range from --render-range or --render-from arguments.
|
|
79
|
+
|
|
80
|
+
Args:
|
|
81
|
+
args: Parsed command line arguments
|
|
82
|
+
plain_source_tree: Parsed plain source tree
|
|
83
|
+
|
|
84
|
+
Returns:
|
|
85
|
+
List of FRIDs to render, or None to render all
|
|
86
|
+
"""
|
|
87
|
+
if args.render_range:
|
|
88
|
+
return get_render_range(args.render_range, plain_source_tree)
|
|
89
|
+
elif args.render_from:
|
|
90
|
+
return get_render_range_from(args.render_from, plain_source_tree)
|
|
91
|
+
return None
|
|
92
|
+
|
|
93
|
+
|
|
75
94
|
def _get_frids_range(plain_source, start, end=None):
|
|
76
95
|
frids = list(plain_spec.get_frids(plain_source))
|
|
77
96
|
|
|
@@ -196,11 +215,7 @@ def render(args, run_state: RunState, event_bus: EventBus): # noqa: C901
|
|
|
196
215
|
if args.render_range or args.render_from:
|
|
197
216
|
# Parse the plain file to get the plain_source for FRID extraction
|
|
198
217
|
_, plain_source, _ = plain_file.plain_file_parser(args.filename, template_dirs)
|
|
199
|
-
|
|
200
|
-
if args.render_range:
|
|
201
|
-
render_range = get_render_range(args.render_range, plain_source)
|
|
202
|
-
elif args.render_from:
|
|
203
|
-
render_range = get_render_range_from(args.render_from, plain_source)
|
|
218
|
+
render_range = compute_render_range(args, plain_source)
|
|
204
219
|
|
|
205
220
|
codeplainAPI = codeplain_api.CodeplainAPI(args.api_key, console)
|
|
206
221
|
codeplainAPI.verbose = args.verbose
|
|
@@ -242,6 +257,29 @@ def render(args, run_state: RunState, event_bus: EventBus): # noqa: C901
|
|
|
242
257
|
def main(): # noqa: C901
|
|
243
258
|
args = parse_arguments()
|
|
244
259
|
|
|
260
|
+
# Handle early-exit flags before heavy initialization
|
|
261
|
+
if args.dry_run or args.full_plain:
|
|
262
|
+
template_dirs = file_utils.get_template_directories(args.filename, args.template_dir, DEFAULT_TEMPLATE_DIRS)
|
|
263
|
+
|
|
264
|
+
try:
|
|
265
|
+
if args.full_plain:
|
|
266
|
+
module_name = Path(args.filename).stem
|
|
267
|
+
plain_source = plain_file.read_module_plain_source(module_name, template_dirs)
|
|
268
|
+
[full_plain_source, _] = file_utils.get_loaded_templates(template_dirs, plain_source)
|
|
269
|
+
console.info("Full plain text:\n")
|
|
270
|
+
console.info(full_plain_source)
|
|
271
|
+
return
|
|
272
|
+
|
|
273
|
+
if args.dry_run:
|
|
274
|
+
console.info("Printing dry run output...\n")
|
|
275
|
+
_, plain_source_tree, _ = plain_file.plain_file_parser(args.filename, template_dirs)
|
|
276
|
+
render_range = compute_render_range(args, plain_source_tree)
|
|
277
|
+
print_dry_run_output(plain_source_tree, render_range)
|
|
278
|
+
return
|
|
279
|
+
except Exception as e:
|
|
280
|
+
console.error(f"Error: {str(e)}")
|
|
281
|
+
return
|
|
282
|
+
|
|
245
283
|
event_bus = EventBus()
|
|
246
284
|
|
|
247
285
|
if not args.api:
|
|
@@ -15,6 +15,7 @@ DEFAULT_CONFORMANCE_TESTS_DEST = "dist_conformance_tests"
|
|
|
15
15
|
UNIT_TESTS_SCRIPT_NAME = "unittests_script"
|
|
16
16
|
CONFORMANCE_TESTS_SCRIPT_NAME = "conformance_tests_script"
|
|
17
17
|
DEFAULT_LOG_FILE_NAME = "codeplain.log"
|
|
18
|
+
PREPARE_ENVIRONMENT_SCRIPT_NAME = "prepare_environment_script"
|
|
18
19
|
|
|
19
20
|
|
|
20
21
|
def process_test_script_path(script_arg_name, config):
|
|
@@ -134,7 +135,7 @@ def create_parser():
|
|
|
134
135
|
"--log-to-file",
|
|
135
136
|
action=argparse.BooleanOptionalAction,
|
|
136
137
|
default=True,
|
|
137
|
-
help="Enable logging to a file. Defaults to True.
|
|
138
|
+
help="Enable logging to a file. Defaults to True. Set to False to disable.",
|
|
138
139
|
)
|
|
139
140
|
parser.add_argument(
|
|
140
141
|
"--log-file-name",
|
|
@@ -142,7 +143,7 @@ def create_parser():
|
|
|
142
143
|
default=DEFAULT_LOG_FILE_NAME,
|
|
143
144
|
help=f"Name of the log file. Defaults to '{DEFAULT_LOG_FILE_NAME}'."
|
|
144
145
|
"Always resolved relative to the plain file directory."
|
|
145
|
-
"If file on this path already exists,
|
|
146
|
+
"If file on this path already exists, the already existing log file will be overwritten by the current logs.",
|
|
146
147
|
)
|
|
147
148
|
|
|
148
149
|
# Add config file arguments
|
|
@@ -158,14 +159,14 @@ def create_parser():
|
|
|
158
159
|
render_range_group.add_argument(
|
|
159
160
|
"--render-range",
|
|
160
161
|
type=frid_range_string,
|
|
161
|
-
help="Specify a range of functional requirements to render (e.g.
|
|
162
|
+
help="Specify a range of functional requirements to render (e.g. `1` , `2`, `3`). "
|
|
162
163
|
"Use comma to separate start and end IDs. If only one ID is provided, only that requirement is rendered. "
|
|
163
164
|
"Range is inclusive of both start and end IDs.",
|
|
164
165
|
)
|
|
165
166
|
render_range_group.add_argument(
|
|
166
167
|
"--render-from",
|
|
167
168
|
type=frid_string,
|
|
168
|
-
help="Continue generation starting from this specific functional requirement (e.g.
|
|
169
|
+
help="Continue generation starting from this specific functional requirement (e.g. `2`). "
|
|
169
170
|
"The requirement with this ID will be included in the output. The ID must match one of the functional requirements in your plain file.",
|
|
170
171
|
)
|
|
171
172
|
|
|
@@ -190,15 +191,15 @@ def create_parser():
|
|
|
190
191
|
parser.add_argument(
|
|
191
192
|
"--conformance-tests-script",
|
|
192
193
|
type=str,
|
|
193
|
-
help="Path to conformance tests shell script.
|
|
194
|
-
"1)
|
|
195
|
-
"2)
|
|
194
|
+
help="Path to conformance tests shell script. Every conformance test script should accept two arguments: "
|
|
195
|
+
"1) Path to a folder (e.g. `plain_modules/module_name`) containing generated source code, "
|
|
196
|
+
"2) Path to a subfolder of the conformance tests folder (e.g. `conformance_tests/subfoldername`) containing test files.",
|
|
196
197
|
)
|
|
197
198
|
|
|
198
199
|
parser.add_argument(
|
|
199
200
|
"--prepare-environment-script",
|
|
200
201
|
type=str,
|
|
201
|
-
help="Path to a shell script that prepares the testing environment. The script should accept the
|
|
202
|
+
help="Path to a shell script that prepares the testing environment. The script should accept the source code folder path as its first argument.",
|
|
202
203
|
)
|
|
203
204
|
|
|
204
205
|
parser.add_argument(
|
|
@@ -212,17 +213,18 @@ def create_parser():
|
|
|
212
213
|
"--api-key",
|
|
213
214
|
type=str,
|
|
214
215
|
default=CODEPLAIN_API_KEY,
|
|
215
|
-
help="API key used to access the API. If not provided, the CODEPLAIN_API_KEY environment variable is used.",
|
|
216
|
+
help="API key used to access the API. If not provided, the `CODEPLAIN_API_KEY` environment variable is used.",
|
|
216
217
|
)
|
|
217
218
|
parser.add_argument(
|
|
218
219
|
"--full-plain",
|
|
219
220
|
action="store_true",
|
|
220
|
-
help="
|
|
221
|
-
"
|
|
222
|
-
"any included template content expanded. Useful for understanding what content is being processed.",
|
|
221
|
+
help="Full preview ***plain specification before code generation."
|
|
222
|
+
"Use when you want to preview context of all ***plain primitives that are going to be included in order to render the given module.",
|
|
223
223
|
)
|
|
224
224
|
parser.add_argument(
|
|
225
|
-
"--dry-run",
|
|
225
|
+
"--dry-run",
|
|
226
|
+
action="store_true",
|
|
227
|
+
help="Dry run preview of the code generation (without actually making any changes).",
|
|
226
228
|
)
|
|
227
229
|
parser.add_argument(
|
|
228
230
|
"--replay-with",
|
|
@@ -236,33 +238,33 @@ def create_parser():
|
|
|
236
238
|
type=str,
|
|
237
239
|
default=None,
|
|
238
240
|
help="Path to a custom template directory. Templates are searched in the following order: "
|
|
239
|
-
"1)
|
|
240
|
-
"2)
|
|
241
|
-
"3)
|
|
241
|
+
"1) Directory containing the plain file, "
|
|
242
|
+
"2) Custom template directory (if provided through this argument), "
|
|
243
|
+
"3) Built-in standard_template_library directory",
|
|
242
244
|
)
|
|
243
245
|
parser.add_argument(
|
|
244
246
|
"--copy-build",
|
|
245
247
|
action="store_true",
|
|
246
248
|
default=False,
|
|
247
|
-
help="If set, copy the
|
|
249
|
+
help="If set, copy the rendered contents of code in `--base-folder` folder to `--build-dest` folder after successful rendering.",
|
|
248
250
|
)
|
|
249
251
|
parser.add_argument(
|
|
250
252
|
"--build-dest",
|
|
251
253
|
type=non_empty_string,
|
|
252
254
|
default=DEFAULT_BUILD_DEST,
|
|
253
|
-
help="Target folder to copy
|
|
255
|
+
help="Target folder to copy rendered contents of code to (used only if --copy-build is set).",
|
|
254
256
|
)
|
|
255
257
|
parser.add_argument(
|
|
256
258
|
"--copy-conformance-tests",
|
|
257
259
|
action="store_true",
|
|
258
260
|
default=False,
|
|
259
|
-
help="If set, copy the conformance tests folder to `--conformance-tests-dest`
|
|
261
|
+
help="If set, copy the conformance tests of code in `--conformance-tests-folder` folder to `--conformance-tests-dest` folder successful rendering. Requires --conformance-tests-script.",
|
|
260
262
|
)
|
|
261
263
|
parser.add_argument(
|
|
262
264
|
"--conformance-tests-dest",
|
|
263
265
|
type=non_empty_string,
|
|
264
266
|
default=DEFAULT_CONFORMANCE_TESTS_DEST,
|
|
265
|
-
help="Target folder to copy conformance tests
|
|
267
|
+
help="Target folder to copy conformance tests of code to (used only if --copy-conformance-tests is set).",
|
|
266
268
|
)
|
|
267
269
|
|
|
268
270
|
parser.add_argument(
|
|
@@ -301,7 +303,10 @@ def parse_arguments():
|
|
|
301
303
|
if not args.log_to_file and args.log_file_name != DEFAULT_LOG_FILE_NAME:
|
|
302
304
|
parser.error("--log-file-name cannot be used when --log-to-file is False.")
|
|
303
305
|
|
|
304
|
-
|
|
306
|
+
if args.full_plain and args.dry_run:
|
|
307
|
+
parser.error("--full-plain and --dry-run are mutually exclusive")
|
|
308
|
+
|
|
309
|
+
script_arg_names = [UNIT_TESTS_SCRIPT_NAME, CONFORMANCE_TESTS_SCRIPT_NAME, PREPARE_ENVIRONMENT_SCRIPT_NAME]
|
|
305
310
|
for script_name in script_arg_names:
|
|
306
311
|
args = process_test_script_path(script_name, args)
|
|
307
312
|
|
|
@@ -22,14 +22,14 @@ def print_dry_run_output(plain_source_tree: dict, render_range: Optional[list[st
|
|
|
22
22
|
specifications, _ = plain_spec.get_specifications_for_frid(plain_source_tree, frid)
|
|
23
23
|
functional_requirement_text = specifications[plain_spec.FUNCTIONAL_REQUIREMENTS][-1]
|
|
24
24
|
console.info(
|
|
25
|
-
"
|
|
26
|
-
f"Rendering functional requirement {frid}"
|
|
27
|
-
f"{functional_requirement_text}"
|
|
28
|
-
"
|
|
25
|
+
"-------------------------------------\n"
|
|
26
|
+
f"Rendering functional requirement {frid}\n"
|
|
27
|
+
f"{functional_requirement_text}\n"
|
|
28
|
+
"-------------------------------------\n"
|
|
29
29
|
)
|
|
30
30
|
if plain_spec.ACCEPTANCE_TESTS in specifications:
|
|
31
31
|
for i, acceptance_test in enumerate(specifications[plain_spec.ACCEPTANCE_TESTS], 1):
|
|
32
|
-
console.info(f"Generating acceptance test #{i}:\n\n{acceptance_test}")
|
|
32
|
+
console.info(f"Generating acceptance test #{i}:\n\n{acceptance_test}\n")
|
|
33
33
|
else:
|
|
34
34
|
console.info(
|
|
35
35
|
"-------------------------------------\n"
|
|
@@ -4,10 +4,10 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "codeplain"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.8"
|
|
8
8
|
description = "Transform plain language specifications into working code"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
requires-python = "
|
|
10
|
+
requires-python = "~=3.11.0"
|
|
11
11
|
classifiers = [
|
|
12
12
|
"Environment :: Console",
|
|
13
13
|
"Intended Audience :: Developers",
|