codeplain 0.2.6__tar.gz → 0.2.7__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.7}/PKG-INFO +1 -1
- {codeplain-0.2.6 → codeplain-0.2.7}/config/system_config.yaml +1 -1
- codeplain-0.2.7/docs/plain2code_cli.md +63 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/git_utils.py +20 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/install/walkthrough.sh +47 -50
- {codeplain-0.2.6 → codeplain-0.2.7}/module_renderer.py +3 -1
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code.py +43 -5
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_arguments.py +24 -20
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_events.py +3 -1
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_utils.py +5 -5
- {codeplain-0.2.6 → codeplain-0.2.7}/pyproject.toml +1 -1
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/plain2code_tui.py +7 -7
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/state_handlers.py +9 -4
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/widget_helpers.py +14 -3
- codeplain-0.2.6/docs/plain2code_cli.md +0 -66
- {codeplain-0.2.6 → codeplain-0.2.7}/.flake8 +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/.github/workflows/publish-to-pypi.yml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/.gitignore +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/.vscode/launch.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/.vscode/settings.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/LICENSE +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/README.md +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/codeplain_REST_api.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/concept_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/config/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/diff_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/docs/generate_cli.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/docs/plain_language_specification.md +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/event_bus.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/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.7}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/examples/run.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/file_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/hash_key.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/install/examples.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/install/install.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/memory_management.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_console.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_exceptions.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_logger.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_nodes.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_read_config.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain2code_state.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain_file.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain_modules.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/plain_spec.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/pytest.ini +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/fix_conformance_test.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/prepare_repositories.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/run_conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/code_renderer.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/conformance_test_helpers.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/implementation_code_helpers.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/render_context.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/render_types.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/render_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/states.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/render_machine/triggers.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/requirements.txt +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/resources/codeplain_overview.png +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/resources/plain_example.png +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/standard_template_library/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/system_config.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/conftest.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/simple.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/templates/header.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/test_git_utils.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/test_imports.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/test_plainfile.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/test_plainfileparser.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/test_plainspec.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tests/test_requires.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/__init__.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/components.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/models.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/spinner.py +0 -0
- {codeplain-0.2.6 → codeplain-0.2.7}/tui/styles.css +0 -0
|
@@ -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,6 @@ 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
|
+
last_module_name = self.loaded_modules[-1].name if self.loaded_modules else ""
|
|
265
|
+
self.event_bus.publish(RenderCompleted(module_name=last_module_name, build_folder=self.args.build_folder))
|
|
@@ -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:
|
|
@@ -134,7 +134,7 @@ def create_parser():
|
|
|
134
134
|
"--log-to-file",
|
|
135
135
|
action=argparse.BooleanOptionalAction,
|
|
136
136
|
default=True,
|
|
137
|
-
help="Enable logging to a file. Defaults to True.
|
|
137
|
+
help="Enable logging to a file. Defaults to True. Set to False to disable.",
|
|
138
138
|
)
|
|
139
139
|
parser.add_argument(
|
|
140
140
|
"--log-file-name",
|
|
@@ -142,7 +142,7 @@ def create_parser():
|
|
|
142
142
|
default=DEFAULT_LOG_FILE_NAME,
|
|
143
143
|
help=f"Name of the log file. Defaults to '{DEFAULT_LOG_FILE_NAME}'."
|
|
144
144
|
"Always resolved relative to the plain file directory."
|
|
145
|
-
"If file on this path already exists,
|
|
145
|
+
"If file on this path already exists, the already existing log file will be overwritten by the current logs.",
|
|
146
146
|
)
|
|
147
147
|
|
|
148
148
|
# Add config file arguments
|
|
@@ -158,14 +158,14 @@ def create_parser():
|
|
|
158
158
|
render_range_group.add_argument(
|
|
159
159
|
"--render-range",
|
|
160
160
|
type=frid_range_string,
|
|
161
|
-
help="Specify a range of functional requirements to render (e.g.
|
|
161
|
+
help="Specify a range of functional requirements to render (e.g. `1` , `2`, `3`). "
|
|
162
162
|
"Use comma to separate start and end IDs. If only one ID is provided, only that requirement is rendered. "
|
|
163
163
|
"Range is inclusive of both start and end IDs.",
|
|
164
164
|
)
|
|
165
165
|
render_range_group.add_argument(
|
|
166
166
|
"--render-from",
|
|
167
167
|
type=frid_string,
|
|
168
|
-
help="Continue generation starting from this specific functional requirement (e.g.
|
|
168
|
+
help="Continue generation starting from this specific functional requirement (e.g. `2`). "
|
|
169
169
|
"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
170
|
)
|
|
171
171
|
|
|
@@ -190,15 +190,15 @@ def create_parser():
|
|
|
190
190
|
parser.add_argument(
|
|
191
191
|
"--conformance-tests-script",
|
|
192
192
|
type=str,
|
|
193
|
-
help="Path to conformance tests shell script.
|
|
194
|
-
"1)
|
|
195
|
-
"2)
|
|
193
|
+
help="Path to conformance tests shell script. Every conformance test script should accept two arguments: "
|
|
194
|
+
"1) Path to a folder (e.g. `plain_modules/module_name`) containing generated source code, "
|
|
195
|
+
"2) Path to a subfolder of the conformance tests folder (e.g. `conformance_tests/subfoldername`) containing test files.",
|
|
196
196
|
)
|
|
197
197
|
|
|
198
198
|
parser.add_argument(
|
|
199
199
|
"--prepare-environment-script",
|
|
200
200
|
type=str,
|
|
201
|
-
help="Path to a shell script that prepares the testing environment. The script should accept the
|
|
201
|
+
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
202
|
)
|
|
203
203
|
|
|
204
204
|
parser.add_argument(
|
|
@@ -212,17 +212,18 @@ def create_parser():
|
|
|
212
212
|
"--api-key",
|
|
213
213
|
type=str,
|
|
214
214
|
default=CODEPLAIN_API_KEY,
|
|
215
|
-
help="API key used to access the API. If not provided, the CODEPLAIN_API_KEY environment variable is used.",
|
|
215
|
+
help="API key used to access the API. If not provided, the `CODEPLAIN_API_KEY` environment variable is used.",
|
|
216
216
|
)
|
|
217
217
|
parser.add_argument(
|
|
218
218
|
"--full-plain",
|
|
219
219
|
action="store_true",
|
|
220
|
-
help="
|
|
221
|
-
"
|
|
222
|
-
"any included template content expanded. Useful for understanding what content is being processed.",
|
|
220
|
+
help="Full preview ***plain specification before code generation."
|
|
221
|
+
"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
222
|
)
|
|
224
223
|
parser.add_argument(
|
|
225
|
-
"--dry-run",
|
|
224
|
+
"--dry-run",
|
|
225
|
+
action="store_true",
|
|
226
|
+
help="Dry run preview of the code generation (without actually making any changes).",
|
|
226
227
|
)
|
|
227
228
|
parser.add_argument(
|
|
228
229
|
"--replay-with",
|
|
@@ -236,33 +237,33 @@ def create_parser():
|
|
|
236
237
|
type=str,
|
|
237
238
|
default=None,
|
|
238
239
|
help="Path to a custom template directory. Templates are searched in the following order: "
|
|
239
|
-
"1)
|
|
240
|
-
"2)
|
|
241
|
-
"3)
|
|
240
|
+
"1) Directory containing the plain file, "
|
|
241
|
+
"2) Custom template directory (if provided through this argument), "
|
|
242
|
+
"3) Built-in standard_template_library directory",
|
|
242
243
|
)
|
|
243
244
|
parser.add_argument(
|
|
244
245
|
"--copy-build",
|
|
245
246
|
action="store_true",
|
|
246
247
|
default=False,
|
|
247
|
-
help="If set, copy the
|
|
248
|
+
help="If set, copy the rendered contents of code in `--base-folder` folder to `--build-dest` folder after successful rendering.",
|
|
248
249
|
)
|
|
249
250
|
parser.add_argument(
|
|
250
251
|
"--build-dest",
|
|
251
252
|
type=non_empty_string,
|
|
252
253
|
default=DEFAULT_BUILD_DEST,
|
|
253
|
-
help="Target folder to copy
|
|
254
|
+
help="Target folder to copy rendered contents of code to (used only if --copy-build is set).",
|
|
254
255
|
)
|
|
255
256
|
parser.add_argument(
|
|
256
257
|
"--copy-conformance-tests",
|
|
257
258
|
action="store_true",
|
|
258
259
|
default=False,
|
|
259
|
-
help="If set, copy the conformance tests folder to `--conformance-tests-dest`
|
|
260
|
+
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
261
|
)
|
|
261
262
|
parser.add_argument(
|
|
262
263
|
"--conformance-tests-dest",
|
|
263
264
|
type=non_empty_string,
|
|
264
265
|
default=DEFAULT_CONFORMANCE_TESTS_DEST,
|
|
265
|
-
help="Target folder to copy conformance tests
|
|
266
|
+
help="Target folder to copy conformance tests of code to (used only if --copy-conformance-tests is set).",
|
|
266
267
|
)
|
|
267
268
|
|
|
268
269
|
parser.add_argument(
|
|
@@ -301,6 +302,9 @@ def parse_arguments():
|
|
|
301
302
|
if not args.log_to_file and args.log_file_name != DEFAULT_LOG_FILE_NAME:
|
|
302
303
|
parser.error("--log-file-name cannot be used when --log-to-file is False.")
|
|
303
304
|
|
|
305
|
+
if args.full_plain and args.dry_run:
|
|
306
|
+
parser.error("--full-plain and --dry-run are mutually exclusive")
|
|
307
|
+
|
|
304
308
|
script_arg_names = [UNIT_TESTS_SCRIPT_NAME, CONFORMANCE_TESTS_SCRIPT_NAME]
|
|
305
309
|
for script_name in script_arg_names:
|
|
306
310
|
args = process_test_script_path(script_name, args)
|
|
@@ -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"
|
|
@@ -169,14 +169,10 @@ class Plain2CodeTUI(App):
|
|
|
169
169
|
with Vertical(id=TUIComponents.DASHBOARD_VIEW.value):
|
|
170
170
|
with VerticalScroll():
|
|
171
171
|
yield Static(
|
|
172
|
-
f"[#FFFFFF]*codeplain[/#FFFFFF] [#888888](v{self.state_machine_version})[/#888888]
|
|
172
|
+
f"[#FFFFFF]*codeplain[/#FFFFFF] [#888888](v{self.state_machine_version})[/#888888]",
|
|
173
173
|
id="codeplain-header",
|
|
174
174
|
classes="codeplain-header",
|
|
175
175
|
)
|
|
176
|
-
yield Static(
|
|
177
|
-
"[#FFFFFF]Rendering in progress...[/#FFFFFF]",
|
|
178
|
-
id=TUIComponents.RENDER_STATUS_WIDGET.value,
|
|
179
|
-
)
|
|
180
176
|
yield FRIDProgress(
|
|
181
177
|
id=TUIComponents.FRID_PROGRESS.value,
|
|
182
178
|
unittests_script=self.unittests_script,
|
|
@@ -190,6 +186,10 @@ class Plain2CodeTUI(App):
|
|
|
190
186
|
show_conformance_test=self.conformance_tests_script is not None,
|
|
191
187
|
show_testing_env=self.prepare_environment_script is not None,
|
|
192
188
|
)
|
|
189
|
+
yield Static(
|
|
190
|
+
"[#FFFFFF]Rendering in progress...[/#FFFFFF]",
|
|
191
|
+
id=TUIComponents.RENDER_STATUS_WIDGET.value,
|
|
192
|
+
)
|
|
193
193
|
with Vertical(id=TUIComponents.LOG_VIEW.value):
|
|
194
194
|
yield LogLevelFilter(id=TUIComponents.LOG_FILTER.value)
|
|
195
195
|
yield Static("", classes="filter-spacer")
|
|
@@ -272,9 +272,9 @@ class Plain2CodeTUI(App):
|
|
|
272
272
|
|
|
273
273
|
self._state_completion_handler.handle(segments, snapshot, previous_state_segments)
|
|
274
274
|
|
|
275
|
-
def on_render_completed(self,
|
|
275
|
+
def on_render_completed(self, event: RenderCompleted):
|
|
276
276
|
"""Handle successful render completion."""
|
|
277
|
-
self._render_success_handler.handle()
|
|
277
|
+
self._render_success_handler.handle(event.module_name, event.build_folder)
|
|
278
278
|
|
|
279
279
|
def on_render_failed(self, event: RenderFailed):
|
|
280
280
|
"""Handle render failure."""
|