codeplain 0.3.11.dev9__tar.gz → 0.3.11.dev16__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.3.11.dev9 → codeplain-0.3.11.dev16}/.flake8 +2 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/PKG-INFO +2 -2
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/cli_output/status.py +13 -8
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/codeplain_REST_api.py +5 -0
- codeplain-0.3.11.dev16/git_preflight.py +41 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain_file.py +34 -9
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain_modules.py +6 -6
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/pyproject.toml +1 -1
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/fix_conformance_test.py +11 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/fix_unit_tests.py +25 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/render_types.py +5 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/requirements.txt +1 -1
- codeplain-0.3.11.dev16/tests/data/plainfileparser/cyclic_definitions.plain +9 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_defaults_exported.plain +13 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_imported_exported.plain +12 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_inherited_reexported.plain +15 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_malformed.plain +13 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_missing_definition.plain +14 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_missing_definition_example.plain +13 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_multiple_per_bullet.plain +14 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_multiple_per_bullet_undefined.plain +13 -0
- codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_no_definitions.plain +10 -0
- codeplain-0.3.11.dev9/tests/data/plainfileparser/exported_concepts_missing_example.plain → codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_not_declared_example.plain +1 -1
- codeplain-0.3.11.dev16/tests/data/plainfileparser/requires_without_definitions_example.plain +10 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_cli_output.py +3 -2
- codeplain-0.3.11.dev16/tests/test_fix_unit_tests_conformance_context.py +230 -0
- codeplain-0.3.11.dev16/tests/test_git_preflight.py +98 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_plainfileparser.py +39 -18
- codeplain-0.3.11.dev16/tests/test_tui_components.py +88 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/components.py +13 -9
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/widget_helpers.py +11 -4
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.claude/settings.json +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/dependabot.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/workflows/e2e.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/workflows/lint-powershell.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/workflows/publish-dev-to-pypi.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.github/workflows/publish-to-pypi.yml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.gitignore +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.vscode/launch.json +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/.vscode/settings.json +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/CLAUDE.md +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/CONTRIBUTING.md +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/LICENSE +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/README.md +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/change_detection.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/cli_output/__init__.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/concept_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/config/__init__.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/config/system_config.yaml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/conformance_fix_journal.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/diff_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/docs/generate_cli.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/docs/plain2code_cli.md +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/event_bus.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/examples/run.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/file_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/git_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/install/bash/examples.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/install/bash/install.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/install/powershell/examples.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/install/powershell/install.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/install/powershell/walkthrough.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/memory_management.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/metadata_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/module_renderer.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/partial_rendering.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/path_resolution.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_arguments.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_cli.md +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_console.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_events.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_exceptions.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_logger.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_nodes.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_read_config.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_state.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_telemetry.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain2code_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/plain_spec.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/pytest.ini +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/__init__.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/prepare_repositories.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/run_conformance_tests.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/code_renderer.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/implementation_code_helpers.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/render_context.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/render_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/states.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/triggers.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/resources/plain_example.png +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/system_config.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/__init__.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/conftest.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- /codeplain-0.3.11.dev9/tests/data/plainfileparser/exported_concepts_missing.plain → /codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_not_declared.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/simple.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/e2e/test_hello_world_python.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/e2e/test_hello_world_python_windows.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_arg_provenance.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_conformance_fix_journal.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_console_log_styles.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_dry_run_link_validation.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_folder_path_resolution.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_headless_logging.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_imports.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_plain2code.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_plain_modules.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_prepare_repositories_layout.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_requires.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_system_config.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_telemetry.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/__init__.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/models.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/plain_module_render_choice_tui.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/spinner.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/state_handlers.py +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/tui/styles.css +0 -0
- {codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/usage_summary.py +0 -0
|
@@ -20,6 +20,8 @@ exclude =
|
|
|
20
20
|
per-file-ignores =
|
|
21
21
|
__init__.py: F401
|
|
22
22
|
tests/*: U100
|
|
23
|
+
# require_git() runs between imports in plain_modules.py, so the imports below it trip E402
|
|
24
|
+
plain_modules.py: E402
|
|
23
25
|
max-complexity = 15
|
|
24
26
|
enable-extensions = U100
|
|
25
27
|
# Plugin-specific configuration
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: codeplain
|
|
3
|
-
Version: 0.3.11.
|
|
3
|
+
Version: 0.3.11.dev16
|
|
4
4
|
Summary: Transform plain language specifications into working code
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Classifier: Environment :: Console
|
|
@@ -16,7 +16,7 @@ Requires-Dist: python-liquid2==0.4.0
|
|
|
16
16
|
Requires-Dist: pyyaml==6.0.3
|
|
17
17
|
Requires-Dist: requests==2.34.2
|
|
18
18
|
Requires-Dist: rich==15.0.0
|
|
19
|
-
Requires-Dist: sentry-sdk==2.
|
|
19
|
+
Requires-Dist: sentry-sdk==2.68.1
|
|
20
20
|
Requires-Dist: textual>=7.5.0
|
|
21
21
|
Requires-Dist: tiktoken==0.14.0
|
|
22
22
|
Requires-Dist: transitions==0.9.3
|
|
@@ -6,6 +6,8 @@ from typing import Optional
|
|
|
6
6
|
import codeplain_REST_api as codeplain_api
|
|
7
7
|
from plain2code_console import console
|
|
8
8
|
|
|
9
|
+
PLANS_URL = "https://platform.codeplain.ai/plans"
|
|
10
|
+
|
|
9
11
|
|
|
10
12
|
def _create_progress_bar(remaining: int, total: int, width: int = 30) -> str:
|
|
11
13
|
"""Create a Unicode progress bar."""
|
|
@@ -42,12 +44,12 @@ def _display_credit_line(plan_credits: dict) -> None:
|
|
|
42
44
|
bar = _create_progress_bar(remaining, total, width=30)
|
|
43
45
|
|
|
44
46
|
# Format plan type label
|
|
45
|
-
plan_label = "Free
|
|
47
|
+
plan_label = "Free credits" if plan_type == "free" else plan_type.upper() + " plan"
|
|
46
48
|
|
|
47
49
|
if is_expired:
|
|
48
|
-
console.print(f" {plan_label:
|
|
50
|
+
console.print(f" {plan_label:12} {bar} expired {formatted_date}")
|
|
49
51
|
else:
|
|
50
|
-
console.print(f" {plan_label:
|
|
52
|
+
console.print(f" {plan_label:12} {bar} {remaining:2} of {total} remaining expires {formatted_date}")
|
|
51
53
|
|
|
52
54
|
|
|
53
55
|
def _display_bucket_credit_line(bucket: dict, label: str) -> None:
|
|
@@ -71,9 +73,9 @@ def _display_bucket_credit_line(bucket: dict, label: str) -> None:
|
|
|
71
73
|
bar = _create_progress_bar(remaining, total, width=30)
|
|
72
74
|
|
|
73
75
|
if is_expired:
|
|
74
|
-
console.print(f" {label:
|
|
76
|
+
console.print(f" {label:12} {bar} expired {formatted_date}")
|
|
75
77
|
else:
|
|
76
|
-
console.print(f" {label:
|
|
78
|
+
console.print(f" {label:12} {bar} {remaining:2} of {total} remaining expires {formatted_date}")
|
|
77
79
|
|
|
78
80
|
|
|
79
81
|
def _display_status_message(plan_credits: Optional[dict], purchased_credits: list, promo_credits: list) -> None:
|
|
@@ -107,7 +109,11 @@ def _display_status_message(plan_credits: Optional[dict], purchased_credits: lis
|
|
|
107
109
|
break
|
|
108
110
|
|
|
109
111
|
if not has_remaining:
|
|
110
|
-
console.print(
|
|
112
|
+
console.print(
|
|
113
|
+
f"\nNo rendering credits remaining. Upgrade to the PRO plan at {PLANS_URL} to continue rendering."
|
|
114
|
+
)
|
|
115
|
+
else:
|
|
116
|
+
console.print(f"\nTo manage your plan navigate to {PLANS_URL}")
|
|
111
117
|
|
|
112
118
|
|
|
113
119
|
def print_status(api_key: str, api_url: str, client_version: str) -> None:
|
|
@@ -148,7 +154,7 @@ def print_status(api_key: str, api_url: str, client_version: str) -> None:
|
|
|
148
154
|
# Display rendering credits section
|
|
149
155
|
console.print("Rendering credits:")
|
|
150
156
|
|
|
151
|
-
# Display plan credits (free
|
|
157
|
+
# Display plan credits (free credits or subscription)
|
|
152
158
|
if plan_credits:
|
|
153
159
|
_display_credit_line(plan_credits)
|
|
154
160
|
|
|
@@ -162,4 +168,3 @@ def print_status(api_key: str, api_url: str, client_version: str) -> None:
|
|
|
162
168
|
|
|
163
169
|
# Display status messages and management link
|
|
164
170
|
_display_status_message(plan_credits, purchased_credits, promo_credits)
|
|
165
|
-
console.print("\nTo manage your plan navigate to https://platform.codeplain.ai/plans")
|
|
@@ -237,6 +237,7 @@ class CodeplainAPI:
|
|
|
237
237
|
required_modules,
|
|
238
238
|
unittests_issue,
|
|
239
239
|
run_state: RunState,
|
|
240
|
+
conformance_tests_fixes: list[dict] | None = None,
|
|
240
241
|
):
|
|
241
242
|
endpoint_url = f"{self.api_url}/fix_unittests_issue"
|
|
242
243
|
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
|
|
@@ -251,6 +252,10 @@ class CodeplainAPI:
|
|
|
251
252
|
"unittests_issue": unittests_issue,
|
|
252
253
|
"unittest_batch_id": run_state.unittest_batch_id,
|
|
253
254
|
}
|
|
255
|
+
# Implementation code changes made by the conformance tests fixer right before this unit tests run;
|
|
256
|
+
# only sent when unit tests are processed inside the conformance tests phase.
|
|
257
|
+
if conformance_tests_fixes is not None:
|
|
258
|
+
payload["conformance_tests_fixes"] = conformance_tests_fixes
|
|
254
259
|
|
|
255
260
|
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
256
261
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""Verify a working git is available before GitPython is imported.
|
|
2
|
+
|
|
3
|
+
GitPython probes for the git executable on import and raises from module scope
|
|
4
|
+
if it is missing or broken, so the CLI would crash with a traceback before
|
|
5
|
+
main() could explain it.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import shutil
|
|
9
|
+
import subprocess
|
|
10
|
+
import sys
|
|
11
|
+
|
|
12
|
+
from plain2code_console import console
|
|
13
|
+
|
|
14
|
+
GIT_MISSING_MESSAGE = "git is not installed. Please install git and try again."
|
|
15
|
+
GIT_BROKEN_MESSAGE = "git is installed but not working. Please repair your git installation and try again."
|
|
16
|
+
MACOS_BROKEN_GIT_HINT = (
|
|
17
|
+
"This usually means the Command Line Tools are missing; install them with 'xcode-select --install'."
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def git_runs(git_path):
|
|
22
|
+
"""Whether `git version` succeeds. A git on PATH can still be unusable: on
|
|
23
|
+
macOS without the Command Line Tools /usr/bin/git is a stub that exits with
|
|
24
|
+
an xcrun error, and GIT_PYTHON_REFRESH=quiet does not suppress that."""
|
|
25
|
+
try:
|
|
26
|
+
return subprocess.run([git_path, "version"], capture_output=True, timeout=10).returncode == 0
|
|
27
|
+
except (OSError, subprocess.SubprocessError):
|
|
28
|
+
return False
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def require_git():
|
|
32
|
+
"""Exit with a clean message unless a working git is available."""
|
|
33
|
+
git_path = shutil.which("git")
|
|
34
|
+
if git_path is None:
|
|
35
|
+
console.error(f"{GIT_MISSING_MESSAGE}\n")
|
|
36
|
+
sys.exit(1)
|
|
37
|
+
|
|
38
|
+
if not git_runs(git_path):
|
|
39
|
+
hint = f"\n{MACOS_BROKEN_GIT_HINT}" if sys.platform == "darwin" else ""
|
|
40
|
+
console.error(f"{GIT_BROKEN_MESSAGE}{hint}\n")
|
|
41
|
+
sys.exit(1)
|
|
@@ -615,15 +615,45 @@ def parse_plain_source( # noqa: C901
|
|
|
615
615
|
f"Plain syntax error: Syntax error at line {nested_acceptance_test_heading.line_number}: {plain_spec.ACCEPTANCE_TEST_HEADING} heading should be nested under specific functional spec."
|
|
616
616
|
)
|
|
617
617
|
|
|
618
|
+
defined_concepts = set[str]()
|
|
618
619
|
if plain_source[plain_spec.DEFINITIONS] is not None:
|
|
619
620
|
with PlainRenderer() as renderer:
|
|
620
621
|
for token in plain_source[plain_spec.DEFINITIONS].children:
|
|
621
622
|
rendered_token = renderer.render(token)
|
|
622
623
|
new_concepts, _ = concept_utils.extract_concepts_from_definition(rendered_token)
|
|
624
|
+
defined_concepts.update(new_concepts)
|
|
623
625
|
for concept in new_concepts:
|
|
624
626
|
if concept in required_concepts:
|
|
625
627
|
required_concepts.remove(concept)
|
|
626
628
|
|
|
629
|
+
if EXPORTED_CONCEPTS_DIRECTIVE in plain_source_obj.metadata:
|
|
630
|
+
module_name = modules_trace[-1] if modules_trace else None
|
|
631
|
+
subject = f"Module '{module_name}'" if module_name else "Module"
|
|
632
|
+
|
|
633
|
+
for entry in plain_source_obj.metadata[EXPORTED_CONCEPTS_DIRECTIVE]:
|
|
634
|
+
exported_concepts, errors = concept_utils.extract_concepts_from_definition(entry)
|
|
635
|
+
if errors:
|
|
636
|
+
raise PlainSyntaxError(
|
|
637
|
+
f"Plain syntax error: {subject} exports an invalid concept (`{entry}`). "
|
|
638
|
+
f"Expected a concept token, e.g. :ConceptName:."
|
|
639
|
+
)
|
|
640
|
+
|
|
641
|
+
for exported_concept in exported_concepts:
|
|
642
|
+
if exported_concept in concept_utils.DEFAULT_CONCEPTS:
|
|
643
|
+
raise PlainSyntaxError(
|
|
644
|
+
f"Plain syntax error: {subject} cannot export default concept {exported_concept}. "
|
|
645
|
+
f"Only user-defined concepts can be exported."
|
|
646
|
+
)
|
|
647
|
+
|
|
648
|
+
if exported_concept not in defined_concepts:
|
|
649
|
+
message = f"Plain syntax error: {subject} exports undefined concept {exported_concept}."
|
|
650
|
+
if REQUIRES_DIRECTIVE in plain_source_obj.metadata:
|
|
651
|
+
message += (
|
|
652
|
+
" An exported concept must be defined in this module's definitions or in an "
|
|
653
|
+
"imported module; a concept inherited through requires cannot be re-exported."
|
|
654
|
+
)
|
|
655
|
+
raise PlainSyntaxError(message)
|
|
656
|
+
|
|
627
657
|
required_modules = []
|
|
628
658
|
if REQUIRES_DIRECTIVE in plain_source_obj.metadata:
|
|
629
659
|
required_modules = plain_source_obj.metadata[REQUIRES_DIRECTIVE]
|
|
@@ -710,15 +740,7 @@ def process_required_modules(
|
|
|
710
740
|
if EXPORTED_CONCEPTS_DIRECTIVE in plain_file_parse_result.plain_source_obj.metadata:
|
|
711
741
|
exported_concepts = list[str]()
|
|
712
742
|
for concept in plain_file_parse_result.plain_source_obj.metadata[EXPORTED_CONCEPTS_DIRECTIVE]:
|
|
713
|
-
|
|
714
|
-
raise PlainSyntaxError(
|
|
715
|
-
f"Plain syntax error: Default concept cannot be exported: {concept}. Only user-defined concepts can be exported."
|
|
716
|
-
)
|
|
717
|
-
|
|
718
|
-
if isinstance(concept, str):
|
|
719
|
-
exported_concepts.extend(concept_utils.extract_concepts_from_definition(concept)[0])
|
|
720
|
-
else:
|
|
721
|
-
raise PlainSyntaxError(f"Plain syntax error: Invalid exported concept: {concept}.")
|
|
743
|
+
exported_concepts.extend(concept_utils.extract_concepts_from_definition(concept)[0])
|
|
722
744
|
|
|
723
745
|
with PlainRenderer() as renderer:
|
|
724
746
|
for exported_concept in exported_concepts:
|
|
@@ -737,6 +759,9 @@ def process_exported_definitions(plain_source: dict, exported_definitions: list[
|
|
|
737
759
|
if len(exported_definitions) == 0:
|
|
738
760
|
return
|
|
739
761
|
|
|
762
|
+
if plain_source[plain_spec.DEFINITIONS] is None:
|
|
763
|
+
plain_source[plain_spec.DEFINITIONS] = mistletoe.Document("")
|
|
764
|
+
|
|
740
765
|
with PlainRenderer() as renderer:
|
|
741
766
|
for exported_definition in exported_definitions:
|
|
742
767
|
add_defintion = True
|
|
@@ -6,18 +6,18 @@ import tempfile
|
|
|
6
6
|
import zipfile
|
|
7
7
|
from functools import cached_property
|
|
8
8
|
|
|
9
|
+
from git_preflight import require_git
|
|
9
10
|
from plain2code_exceptions import (
|
|
10
|
-
GitNotInstalledError,
|
|
11
11
|
InvalidModuleArchiveError,
|
|
12
12
|
MissingPreviousFunctionalitiesError,
|
|
13
13
|
ModuleDoesNotExistError,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
# Must run before GitPython is imported, which raises on a missing or broken git.
|
|
17
|
+
require_git()
|
|
18
|
+
|
|
19
|
+
from git import Repo
|
|
20
|
+
from git.exc import NoSuchPathError
|
|
21
21
|
|
|
22
22
|
import file_utils
|
|
23
23
|
import git_utils
|
{codeplain-0.3.11.dev9 → codeplain-0.3.11.dev16}/render_machine/actions/fix_conformance_test.py
RENAMED
|
@@ -189,6 +189,17 @@ class FixConformanceTest(BaseAction):
|
|
|
189
189
|
ctx.test_that_triggered_code_change = (ctx.current_testing_module_name, ctx.current_testing_frid)
|
|
190
190
|
ctx.execution_phase = TestExecutionPhase.RETRYING_AFTER_CODE_CHANGE
|
|
191
191
|
|
|
192
|
+
# Remember the change so that the unit tests fixer (which runs next) preserves it instead of
|
|
193
|
+
# reverting it - see FixUnitTests.
|
|
194
|
+
summary = fix_attempt_summary if isinstance(fix_attempt_summary, dict) else {}
|
|
195
|
+
ctx.implementation_code_fixes.append(
|
|
196
|
+
{
|
|
197
|
+
"hypothesis": summary.get("hypothesis"),
|
|
198
|
+
"approach": summary.get("approach"),
|
|
199
|
+
"code_diff": code_diff_files_content,
|
|
200
|
+
}
|
|
201
|
+
)
|
|
202
|
+
|
|
192
203
|
journal.record_fix(
|
|
193
204
|
ctx.current_testing_module_name,
|
|
194
205
|
ctx.current_testing_frid,
|
|
@@ -32,6 +32,13 @@ class FixUnitTests(BaseAction):
|
|
|
32
32
|
|
|
33
33
|
render_utils.print_inputs(render_context, existing_files_content, "Files sent as input to unit tests fixing:")
|
|
34
34
|
|
|
35
|
+
conformance_tests_fixes = self._get_conformance_tests_fixes(render_context)
|
|
36
|
+
if conformance_tests_fixes:
|
|
37
|
+
console.info(
|
|
38
|
+
f"Unit tests are fixed while preserving {len(conformance_tests_fixes)} implementation code change(s) "
|
|
39
|
+
"made to fix the conformance tests."
|
|
40
|
+
)
|
|
41
|
+
|
|
35
42
|
response_files = render_context.codeplain_api.fix_unittests_issue(
|
|
36
43
|
render_context.frid_context.frid,
|
|
37
44
|
render_context.plain_source_tree,
|
|
@@ -41,6 +48,7 @@ class FixUnitTests(BaseAction):
|
|
|
41
48
|
render_context.get_required_modules_functionalities(),
|
|
42
49
|
previous_unittests_issue,
|
|
43
50
|
run_state=render_context.run_state,
|
|
51
|
+
conformance_tests_fixes=conformance_tests_fixes,
|
|
44
52
|
)
|
|
45
53
|
|
|
46
54
|
_, changed_files = file_utils.update_build_folder_with_rendered_files(
|
|
@@ -52,3 +60,20 @@ class FixUnitTests(BaseAction):
|
|
|
52
60
|
console.print_files("Files fixed:", render_context.build_folder, response_files, style=console.OUTPUT_STYLE)
|
|
53
61
|
|
|
54
62
|
return self.SUCCESSFUL_OUTCOME, None
|
|
63
|
+
|
|
64
|
+
@staticmethod
|
|
65
|
+
def _get_conformance_tests_fixes(render_context: RenderContext) -> list[dict] | None:
|
|
66
|
+
"""Implementation code changes the conformance tests fixer made before these unit tests were run.
|
|
67
|
+
|
|
68
|
+
Only present when unit tests are processed inside the conformance tests phase - the implementation
|
|
69
|
+
and refactoring unit test passes have no conformance tests running context.
|
|
70
|
+
"""
|
|
71
|
+
conformance_tests_running_context = getattr(render_context, "conformance_tests_running_context", None)
|
|
72
|
+
if conformance_tests_running_context is None:
|
|
73
|
+
return None
|
|
74
|
+
|
|
75
|
+
implementation_code_fixes = getattr(conformance_tests_running_context, "implementation_code_fixes", None)
|
|
76
|
+
if not implementation_code_fixes:
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
return list(implementation_code_fixes)
|
|
@@ -91,6 +91,11 @@ class ConformanceTestsRunningContext:
|
|
|
91
91
|
|
|
92
92
|
self.current_testing_frid_high_level_implementation_plan: Optional[str] = None
|
|
93
93
|
|
|
94
|
+
# Implementation code changes made by the conformance tests fixer during this conformance phase, in
|
|
95
|
+
# order. Each entry is {"hypothesis": str | None, "approach": str | None, "code_diff": {file: diff}}.
|
|
96
|
+
# Handed to the unit tests fixer so it adjusts the unit tests instead of reverting these changes.
|
|
97
|
+
self.implementation_code_fixes: list[dict] = []
|
|
98
|
+
|
|
94
99
|
def get_conformance_tests_json(self, module_name: str) -> dict:
|
|
95
100
|
return self._conformance_tests_json[module_name]
|
|
96
101
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
exported_concepts:
|
|
3
|
+
- :UnitTests:
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
***definitions***
|
|
7
|
+
- :NewConcept: is a new concept.
|
|
8
|
+
|
|
9
|
+
***implementation reqs***
|
|
10
|
+
- The :NewConcept: must be implemented.
|
|
11
|
+
|
|
12
|
+
***functional specs***
|
|
13
|
+
- Implement a wrapper for the :NewConcept: concept.
|
codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_inherited_reexported.plain
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
requires:
|
|
3
|
+
- exported_concepts
|
|
4
|
+
exported_concepts:
|
|
5
|
+
- :Concept:
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
***definitions***
|
|
9
|
+
- :DependantConcept: depends on the :Concept: concept.
|
|
10
|
+
|
|
11
|
+
***implementation reqs***
|
|
12
|
+
- The :DependantConcept: concept must be implemented.
|
|
13
|
+
|
|
14
|
+
***functional specs***
|
|
15
|
+
- Implement a wrapper for the :DependantConcept: concept.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
exported_concepts:
|
|
3
|
+
- :NewConcept:
|
|
4
|
+
- :Concept:
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
***definitions***
|
|
8
|
+
- :NewConcept: is a new concept.
|
|
9
|
+
|
|
10
|
+
***implementation reqs***
|
|
11
|
+
- The :NewConcept: must be implemented.
|
|
12
|
+
|
|
13
|
+
***functional specs***
|
|
14
|
+
- Implement a wrapper for the :NewConcept: concept.
|
codeplain-0.3.11.dev16/tests/data/plainfileparser/exported_concepts_missing_definition_example.plain
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
requires:
|
|
3
|
+
- exported_concepts_missing_definition
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
***definitions***
|
|
7
|
+
- :AnotherConcept: is a new concept.
|
|
8
|
+
|
|
9
|
+
***implementation reqs***
|
|
10
|
+
- :AnotherConcept: must be implemented.
|
|
11
|
+
|
|
12
|
+
***functional specs***
|
|
13
|
+
- Implement a wrapper for the :AnotherConcept: concept.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
---
|
|
2
|
+
exported_concepts:
|
|
3
|
+
- :NewConcept:, :OtherConcept:
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
***definitions***
|
|
7
|
+
- :NewConcept: is a new concept.
|
|
8
|
+
- :OtherConcept: is another concept.
|
|
9
|
+
|
|
10
|
+
***implementation reqs***
|
|
11
|
+
- The :NewConcept: and :OtherConcept: concepts must be implemented.
|
|
12
|
+
|
|
13
|
+
***functional specs***
|
|
14
|
+
- Implement a wrapper for the :NewConcept: and :OtherConcept: concepts.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
exported_concepts:
|
|
3
|
+
- :NewConcept:, :OtherConcept:
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
***definitions***
|
|
7
|
+
- :NewConcept: is a new concept.
|
|
8
|
+
|
|
9
|
+
***implementation reqs***
|
|
10
|
+
- The :NewConcept: concept must be implemented.
|
|
11
|
+
|
|
12
|
+
***functional specs***
|
|
13
|
+
- Implement a wrapper for the :NewConcept: concept.
|
|
@@ -67,7 +67,7 @@ class TestDisplayCreditLine:
|
|
|
67
67
|
|
|
68
68
|
@patch("cli_output.status.console")
|
|
69
69
|
def test_display_active_free_trial(self, mock_console):
|
|
70
|
-
"""Test displaying active free
|
|
70
|
+
"""Test displaying active free credits."""
|
|
71
71
|
plan_credits = {
|
|
72
72
|
"type": "free",
|
|
73
73
|
"total": 50,
|
|
@@ -78,7 +78,7 @@ class TestDisplayCreditLine:
|
|
|
78
78
|
|
|
79
79
|
mock_console.print.assert_called_once()
|
|
80
80
|
call_args = mock_console.print.call_args[0][0]
|
|
81
|
-
assert "Free
|
|
81
|
+
assert "Free credits" in call_args
|
|
82
82
|
assert "4 of 50 remaining" in call_args
|
|
83
83
|
assert "expires Dec 1, 2028" in call_args
|
|
84
84
|
|
|
@@ -259,6 +259,7 @@ class TestDisplayStatusMessage:
|
|
|
259
259
|
mock_console.print.assert_called_once()
|
|
260
260
|
call_args = mock_console.print.call_args[0][0]
|
|
261
261
|
assert "No rendering credits remaining" in call_args
|
|
262
|
+
assert "https://platform.codeplain.ai/plans" in call_args
|
|
262
263
|
|
|
263
264
|
@patch("cli_output.status.console")
|
|
264
265
|
def test_expired_plan_credits(self, mock_console):
|