codeplain 0.3.10.dev2__tar.gz → 0.3.10.dev4__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.10.dev4/.github/dependabot.yml +28 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/e2e.yml +10 -8
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/lint-and-test.yml +19 -17
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/lint-powershell.yml +2 -2
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/nofity-slack-on-main-merge.yml +3 -3
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/publish-install-script.yml +1 -1
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/publish-to-pypi.yml +46 -4
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/PKG-INFO +1 -1
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/codeplain_REST_api.py +6 -14
- codeplain-0.3.10.dev4/conformance_fix_journal.py +207 -0
- codeplain-0.3.10.dev4/memory_management.py +52 -0
- codeplain-0.3.10.dev4/render_machine/actions/distill_conformance_test_memory.py +56 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/fix_conformance_test.py +58 -29
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/prepare_repositories.py +8 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/run_conformance_tests.py +5 -11
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/render_types.py +0 -4
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/state_machine_config.py +10 -1
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/states.py +1 -0
- codeplain-0.3.10.dev4/tests/test_conformance_fix_journal.py +259 -0
- codeplain-0.3.10.dev4/tests/test_distill_conformance_test_memory.py +145 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_prepare_repositories_layout.py +38 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/state_handlers.py +7 -1
- codeplain-0.3.10.dev2/.github/dependabot.yml +0 -11
- codeplain-0.3.10.dev2/memory_management.py +0 -132
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.claude/settings.json +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.flake8 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/publish-dev-to-pypi.yml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.gitignore +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.vscode/launch.json +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.vscode/settings.json +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/CLAUDE.md +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/CONTRIBUTING.md +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/LICENSE +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/README.md +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/change_detection.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/cli_output/__init__.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/cli_output/status.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/concept_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/config/__init__.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/config/system_config.yaml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/diff_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/docs/generate_cli.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/docs/plain2code_cli.md +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/event_bus.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/examples/run.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/file_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/git_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/install/bash/examples.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/install/bash/install.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/install/powershell/examples.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/install/powershell/install.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/install/powershell/walkthrough.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/metadata_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/module_renderer.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/partial_rendering.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/path_resolution.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_arguments.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_cli.md +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_console.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_events.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_exceptions.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_logger.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_nodes.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_read_config.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_state.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_telemetry.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain2code_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain_file.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain_modules.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/plain_spec.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/pyproject.toml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/pytest.ini +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/__init__.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/code_renderer.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/implementation_code_helpers.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/render_context.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/render_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/render_machine/triggers.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/requirements.txt +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/resources/plain_example.png +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/system_config.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/__init__.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/conftest.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/simple.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/e2e/test_hello_world_python.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/e2e/test_hello_world_python_windows.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_arg_provenance.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_cli_output.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_console_log_styles.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_folder_path_resolution.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_headless_logging.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_imports.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_plain2code.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_plain_modules.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_plainfileparser.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_requires.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_system_config.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_telemetry.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/__init__.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/components.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/models.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/plain_module_render_choice_tui.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/spinner.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/styles.css +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/tui/widget_helpers.py +0 -0
- {codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/usage_summary.py +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
version: 2
|
|
2
|
+
updates:
|
|
3
|
+
- package-ecosystem: "pip"
|
|
4
|
+
directory: "/"
|
|
5
|
+
schedule:
|
|
6
|
+
interval: "weekly"
|
|
7
|
+
open-pull-requests-limit: 3
|
|
8
|
+
commit-message:
|
|
9
|
+
prefix: "dependabot"
|
|
10
|
+
labels:
|
|
11
|
+
- "dependencies"
|
|
12
|
+
|
|
13
|
+
# Keeps the SHA-pinned actions in publish-to-pypi.yml patched.
|
|
14
|
+
- package-ecosystem: "github-actions"
|
|
15
|
+
directory: "/"
|
|
16
|
+
schedule:
|
|
17
|
+
interval: "weekly"
|
|
18
|
+
open-pull-requests-limit: 5
|
|
19
|
+
commit-message:
|
|
20
|
+
prefix: "ci"
|
|
21
|
+
labels:
|
|
22
|
+
- "dependencies"
|
|
23
|
+
- "github-actions"
|
|
24
|
+
groups:
|
|
25
|
+
actions-minor-and-patch:
|
|
26
|
+
update-types:
|
|
27
|
+
- "minor"
|
|
28
|
+
- "patch"
|
|
@@ -11,19 +11,19 @@ jobs:
|
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
timeout-minutes: 15
|
|
13
13
|
steps:
|
|
14
|
-
- uses: actions/checkout@
|
|
14
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
15
15
|
|
|
16
|
-
- uses: actions/setup-python@
|
|
16
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
17
17
|
with:
|
|
18
18
|
python-version: '3.12'
|
|
19
19
|
|
|
20
20
|
- run: pip install pytest
|
|
21
21
|
|
|
22
22
|
- name: Set up Docker Buildx
|
|
23
|
-
uses: docker/setup-buildx-action@v3
|
|
23
|
+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
|
24
24
|
|
|
25
25
|
- name: Build E2E image (cached)
|
|
26
|
-
uses: docker/build-push-action@v5
|
|
26
|
+
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
|
|
27
27
|
with:
|
|
28
28
|
context: .
|
|
29
29
|
file: tests/e2e/Dockerfile
|
|
@@ -39,7 +39,7 @@ jobs:
|
|
|
39
39
|
|
|
40
40
|
- name: Upload generated outputs on failure
|
|
41
41
|
if: failure()
|
|
42
|
-
uses: actions/upload-artifact@
|
|
42
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
43
43
|
with:
|
|
44
44
|
name: e2e-outputs-linux
|
|
45
45
|
path: /tmp/pytest-of-runner/**/container_work*/**
|
|
@@ -48,9 +48,9 @@ jobs:
|
|
|
48
48
|
runs-on: windows-latest
|
|
49
49
|
timeout-minutes: 15
|
|
50
50
|
steps:
|
|
51
|
-
- uses: actions/checkout@
|
|
51
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
52
52
|
|
|
53
|
-
- uses: actions/setup-python@
|
|
53
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
54
54
|
with:
|
|
55
55
|
python-version: '3.12'
|
|
56
56
|
|
|
@@ -81,8 +81,10 @@ jobs:
|
|
|
81
81
|
|
|
82
82
|
- name: Send failure notification to Slack
|
|
83
83
|
if: ${{ env.SLACK_WEBHOOK_URL != '' }}
|
|
84
|
-
uses: slackapi/slack-github-action@
|
|
84
|
+
uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0
|
|
85
85
|
with:
|
|
86
|
+
webhook: ${{ env.SLACK_WEBHOOK_URL }}
|
|
87
|
+
webhook-type: incoming-webhook
|
|
86
88
|
payload: |
|
|
87
89
|
{
|
|
88
90
|
"text": ${{ toJSON(format('[Codeplain Client] E2E tests FAILED on {0}. See <{1}/{2}/actions/runs/{3}|the run log>.', steps.platforms.outputs.failed, github.server_url, github.repository, github.run_id)) }}
|
|
@@ -12,13 +12,13 @@ jobs:
|
|
|
12
12
|
name: Black Formatting
|
|
13
13
|
runs-on: ubuntu-latest
|
|
14
14
|
steps:
|
|
15
|
-
- uses: actions/checkout@
|
|
15
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
16
16
|
- name: Set up Python
|
|
17
|
-
uses: actions/setup-python@
|
|
17
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
18
18
|
with:
|
|
19
19
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
20
20
|
- name: Cache pip
|
|
21
|
-
uses: actions/cache@
|
|
21
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
22
22
|
with:
|
|
23
23
|
path: ~/.cache/pip
|
|
24
24
|
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
|
|
@@ -33,13 +33,13 @@ jobs:
|
|
|
33
33
|
name: Import Sorting
|
|
34
34
|
runs-on: ubuntu-latest
|
|
35
35
|
steps:
|
|
36
|
-
- uses: actions/checkout@
|
|
36
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
37
37
|
- name: Set up Python
|
|
38
|
-
uses: actions/setup-python@
|
|
38
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
39
39
|
with:
|
|
40
40
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
41
41
|
- name: Cache pip
|
|
42
|
-
uses: actions/cache@
|
|
42
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
43
43
|
with:
|
|
44
44
|
path: ~/.cache/pip
|
|
45
45
|
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
|
|
@@ -54,13 +54,13 @@ jobs:
|
|
|
54
54
|
name: Flake8 Linting
|
|
55
55
|
runs-on: ubuntu-latest
|
|
56
56
|
steps:
|
|
57
|
-
- uses: actions/checkout@
|
|
57
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
58
58
|
- name: Set up Python
|
|
59
|
-
uses: actions/setup-python@
|
|
59
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
60
60
|
with:
|
|
61
61
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
62
62
|
- name: Cache pip
|
|
63
|
-
uses: actions/cache@
|
|
63
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
64
64
|
with:
|
|
65
65
|
path: ~/.cache/pip
|
|
66
66
|
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
|
|
@@ -75,13 +75,13 @@ jobs:
|
|
|
75
75
|
name: MyPy Type Checking
|
|
76
76
|
runs-on: ubuntu-latest
|
|
77
77
|
steps:
|
|
78
|
-
- uses: actions/checkout@
|
|
78
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
79
79
|
- name: Set up Python
|
|
80
|
-
uses: actions/setup-python@
|
|
80
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
81
81
|
with:
|
|
82
82
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
83
83
|
- name: Cache pip
|
|
84
|
-
uses: actions/cache@
|
|
84
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
85
85
|
with:
|
|
86
86
|
path: ~/.cache/pip
|
|
87
87
|
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
|
|
@@ -96,9 +96,9 @@ jobs:
|
|
|
96
96
|
name: Run Tests
|
|
97
97
|
runs-on: ubuntu-latest
|
|
98
98
|
steps:
|
|
99
|
-
- uses: actions/checkout@
|
|
99
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
100
100
|
- name: Set up Python
|
|
101
|
-
uses: actions/setup-python@
|
|
101
|
+
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
102
102
|
with:
|
|
103
103
|
python-version: ${{ env.PYTHON_VERSION }}
|
|
104
104
|
- name: Configure git for tests
|
|
@@ -107,7 +107,7 @@ jobs:
|
|
|
107
107
|
git config --global user.name "Test Runner"
|
|
108
108
|
git config --global init.defaultBranch main
|
|
109
109
|
- name: Cache pip
|
|
110
|
-
uses: actions/cache@
|
|
110
|
+
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
|
111
111
|
with:
|
|
112
112
|
path: ~/.cache/pip
|
|
113
113
|
key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
|
|
@@ -122,5 +122,7 @@ jobs:
|
|
|
122
122
|
coverage run -m pytest tests/ -v
|
|
123
123
|
coverage xml
|
|
124
124
|
coverage report
|
|
125
|
-
|
|
126
|
-
|
|
125
|
+
# Disabled: v3's Node runtime is gone from the runners. Re-enable with a
|
|
126
|
+
# current major version, which renamed several inputs.
|
|
127
|
+
# - name: Upload coverage reports
|
|
128
|
+
# uses: codecov/codecov-action@v3
|
|
@@ -16,7 +16,7 @@ jobs:
|
|
|
16
16
|
name: Parse under Windows PowerShell 5.1
|
|
17
17
|
runs-on: windows-latest
|
|
18
18
|
steps:
|
|
19
|
-
- uses: actions/checkout@
|
|
19
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
20
20
|
|
|
21
21
|
# The install scripts are fetched over HTTP and executed on stock Windows,
|
|
22
22
|
# where powershell.exe (5.1) is the default shell. 5.1 reads BOM-less files
|
|
@@ -96,7 +96,7 @@ jobs:
|
|
|
96
96
|
name: Parse under PowerShell 7
|
|
97
97
|
runs-on: windows-latest
|
|
98
98
|
steps:
|
|
99
|
-
- uses: actions/checkout@
|
|
99
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
100
100
|
|
|
101
101
|
- name: Parse each script with 7
|
|
102
102
|
shell: pwsh
|
{codeplain-0.3.10.dev2 → codeplain-0.3.10.dev4}/.github/workflows/nofity-slack-on-main-merge.yml
RENAMED
|
@@ -12,11 +12,11 @@ jobs:
|
|
|
12
12
|
if: github.event.pull_request.merged == true
|
|
13
13
|
steps:
|
|
14
14
|
- name: Send notification to Slack
|
|
15
|
-
uses: slackapi/slack-github-action@
|
|
15
|
+
uses: slackapi/slack-github-action@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0
|
|
16
16
|
with:
|
|
17
|
+
webhook: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
18
|
+
webhook-type: incoming-webhook
|
|
17
19
|
payload: |
|
|
18
20
|
{
|
|
19
21
|
"text": ${{ toJSON(format('[Codeplain Client] PR <{0}|#{1}: {2}> was merged to main by `{3}`.', github.event.pull_request.html_url, github.event.pull_request.number, github.event.pull_request.title, github.actor)) }}
|
|
20
22
|
}
|
|
21
|
-
env:
|
|
22
|
-
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
@@ -19,7 +19,7 @@ jobs:
|
|
|
19
19
|
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
20
20
|
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
22
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
23
23
|
with:
|
|
24
24
|
# hatch-vcs derives the version from git tags, so we need full history.
|
|
25
25
|
fetch-depth: 0
|
|
@@ -46,7 +46,7 @@ jobs:
|
|
|
46
46
|
ls -l dist/
|
|
47
47
|
|
|
48
48
|
- name: Store the distribution packages
|
|
49
|
-
uses: actions/upload-artifact@
|
|
49
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
50
50
|
with:
|
|
51
51
|
name: python-package-distributions
|
|
52
52
|
path: dist/
|
|
@@ -81,13 +81,13 @@ jobs:
|
|
|
81
81
|
|
|
82
82
|
steps:
|
|
83
83
|
- name: Download distribution packages
|
|
84
|
-
uses: actions/download-artifact@
|
|
84
|
+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
85
85
|
with:
|
|
86
86
|
name: python-package-distributions
|
|
87
87
|
path: dist/
|
|
88
88
|
|
|
89
89
|
- name: Publish to PyPI
|
|
90
|
-
uses: pypa/gh-action-pypi-publish@release/v1
|
|
90
|
+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
91
91
|
|
|
92
92
|
- name: Notify Slack (success)
|
|
93
93
|
if: ${{ success() && env.SLACK_WEBHOOK_URL != '' }}
|
|
@@ -115,3 +115,45 @@ jobs:
|
|
|
115
115
|
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
116
116
|
-H 'Content-type: application/json' \
|
|
117
117
|
--data "{\"text\":\"*Codeplain Client*: Publishing \`${{ github.ref_name }}\` to PyPI FAILED :x:. See <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|the run log>.\"}"
|
|
118
|
+
|
|
119
|
+
# Release pipelines to be turned on only after the rest of the infrastructure
|
|
120
|
+
# is ready.
|
|
121
|
+
#
|
|
122
|
+
# # Runs only after the package is on PyPI. Kept as its own job so the publish job
|
|
123
|
+
# # keeps its minimal permissions and no checkout.
|
|
124
|
+
# linear-release:
|
|
125
|
+
# name: Record release in Linear
|
|
126
|
+
# needs: publish-to-pypi
|
|
127
|
+
# runs-on: ubuntu-latest
|
|
128
|
+
#
|
|
129
|
+
# permissions:
|
|
130
|
+
# contents: read
|
|
131
|
+
#
|
|
132
|
+
# env:
|
|
133
|
+
# SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
134
|
+
#
|
|
135
|
+
# steps:
|
|
136
|
+
# - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
137
|
+
# with:
|
|
138
|
+
# # The scan needs full history.
|
|
139
|
+
# fetch-depth: 0
|
|
140
|
+
#
|
|
141
|
+
# # Non-fatal: the package is already published.
|
|
142
|
+
# - name: Record release in Linear
|
|
143
|
+
# id: linear
|
|
144
|
+
# continue-on-error: true
|
|
145
|
+
# uses: linear/linear-release-action@0a25abab892a91062ebf42260dbb2ce6277aa205 # v0.16.0
|
|
146
|
+
# with:
|
|
147
|
+
# access_key: ${{ secrets.LINEAR_ACCESS_KEY }}
|
|
148
|
+
# version: ${{ github.ref_name }}
|
|
149
|
+
# # Pin the CLI the action downloads, not just the action.
|
|
150
|
+
# cli_version: v0.16.0
|
|
151
|
+
#
|
|
152
|
+
# # continue-on-error keeps the job green, so this checks the step's own
|
|
153
|
+
# # outcome — `failure()` would never fire.
|
|
154
|
+
# - name: Notify Slack (release not recorded)
|
|
155
|
+
# if: ${{ steps.linear.outcome == 'failure' && env.SLACK_WEBHOOK_URL != '' }}
|
|
156
|
+
# run: |
|
|
157
|
+
# curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
158
|
+
# -H 'Content-type: application/json' \
|
|
159
|
+
# --data "{\"text\":\"*Codeplain Client*: \`${{ github.ref_name }}\` is on PyPI, but recording it in Linear FAILED :warning:. See <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|the run log>.\"}"
|
|
@@ -254,7 +254,7 @@ class CodeplainAPI:
|
|
|
254
254
|
|
|
255
255
|
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
256
256
|
|
|
257
|
-
def
|
|
257
|
+
def distill_conformance_test_memory(
|
|
258
258
|
self,
|
|
259
259
|
frid,
|
|
260
260
|
plain_source_tree,
|
|
@@ -263,15 +263,10 @@ class CodeplainAPI:
|
|
|
263
263
|
memory_files_content,
|
|
264
264
|
module_name,
|
|
265
265
|
required_modules,
|
|
266
|
-
|
|
267
|
-
conformance_tests_files,
|
|
268
|
-
acceptance_tests,
|
|
269
|
-
conformance_tests_issue,
|
|
270
|
-
conformance_tests_folder_name,
|
|
271
|
-
previous_conformance_tests_issue_old,
|
|
266
|
+
fix_journals,
|
|
272
267
|
run_state: RunState,
|
|
273
268
|
):
|
|
274
|
-
endpoint_url = f"{self.api_url}/
|
|
269
|
+
endpoint_url = f"{self.api_url}/distill_conformance_test_memory"
|
|
275
270
|
headers = {"X-API-Key": self.api_key, "Content-Type": "application/json"}
|
|
276
271
|
|
|
277
272
|
payload = {
|
|
@@ -282,12 +277,7 @@ class CodeplainAPI:
|
|
|
282
277
|
"memory_files_content": memory_files_content,
|
|
283
278
|
"module_name": module_name,
|
|
284
279
|
"required_modules": required_modules,
|
|
285
|
-
"
|
|
286
|
-
"conformance_tests_files": conformance_tests_files,
|
|
287
|
-
"acceptance_tests": acceptance_tests,
|
|
288
|
-
"conformance_tests_issue": conformance_tests_issue,
|
|
289
|
-
"conformance_tests_folder_name": conformance_tests_folder_name,
|
|
290
|
-
"previous_conformance_tests_issue": previous_conformance_tests_issue_old,
|
|
280
|
+
"fix_journals": fix_journals,
|
|
291
281
|
}
|
|
292
282
|
|
|
293
283
|
return self.post_request(endpoint_url, headers, payload, run_state)
|
|
@@ -381,6 +371,7 @@ class CodeplainAPI:
|
|
|
381
371
|
conformance_tests_folder_name,
|
|
382
372
|
current_testing_frid_high_level_implementation_plan: Optional[str],
|
|
383
373
|
conflicting_requirements_count: int,
|
|
374
|
+
fix_attempts_journal: list,
|
|
384
375
|
run_state: RunState,
|
|
385
376
|
):
|
|
386
377
|
endpoint_url = f"{self.api_url}/fix_conformance_tests_issue"
|
|
@@ -403,6 +394,7 @@ class CodeplainAPI:
|
|
|
403
394
|
"conformance_tests_folder_name": conformance_tests_folder_name,
|
|
404
395
|
"current_testing_frid_high_level_implementation_plan": current_testing_frid_high_level_implementation_plan,
|
|
405
396
|
"conflicting_requirements_count": conflicting_requirements_count,
|
|
397
|
+
"fix_attempts_journal": fix_attempts_journal,
|
|
406
398
|
}
|
|
407
399
|
|
|
408
400
|
if acceptance_tests is not None:
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"""Deterministic journal of conformance tests fix attempts.
|
|
2
|
+
|
|
3
|
+
While a functionality's conformance tests are failing, every fix attempt is recorded here: the
|
|
4
|
+
issue that triggered it, what the fixer said it tried, which files it changed and whether the tests
|
|
5
|
+
passed afterwards. A digest of the journal is sent back with every fix request so the fixer does
|
|
6
|
+
not repeat attempts that already failed, and once the functionality's conformance tests all pass
|
|
7
|
+
the journal is distilled into durable memories and deleted.
|
|
8
|
+
|
|
9
|
+
Each entry carries the issue in two forms: the raw script output (kept untruncated, on disk only)
|
|
10
|
+
and the prepared form the server built for the fix prompt (trimmed, and summarized or truncated
|
|
11
|
+
when oversized) - the issue exactly the way the fixer saw it. The prepared form is what travels in
|
|
12
|
+
the fix digest and the distillation payload; the raw form exists for humans debugging a render.
|
|
13
|
+
An attempt's outcome text is not stored twice: the output produced after an attempt is the raw
|
|
14
|
+
issue of the next attempt.
|
|
15
|
+
|
|
16
|
+
Journals are keyed by the (module, frid) whose tests are being fixed - during the regression sweep
|
|
17
|
+
that can be a previously implemented functionality, possibly from a required module.
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import hashlib
|
|
21
|
+
import json
|
|
22
|
+
import os
|
|
23
|
+
import shutil
|
|
24
|
+
|
|
25
|
+
from plain2code_console import console
|
|
26
|
+
|
|
27
|
+
CONFORMANCE_TEST_JOURNAL_SUBFOLDER = "conformance_test_journal"
|
|
28
|
+
|
|
29
|
+
# Cap for the issue excerpts included in payloads (the per-attempt issue in the fix digest, and the
|
|
30
|
+
# initial issue in the distillation payload). The server-prepared issue is already bounded (LLM
|
|
31
|
+
# summary or ~10k-char truncation), so this only trims the rare oversized case - it must not
|
|
32
|
+
# routinely cut into summaries the server already sized for a prompt.
|
|
33
|
+
MAX_ISSUE_EXCERPT_CHARS = 8000
|
|
34
|
+
|
|
35
|
+
# The keys of a journal entry that make up the digest sent to the fixer and the distiller.
|
|
36
|
+
DIGEST_KEYS = ["attempt", "hypothesis", "approach", "target", "files_changed", "duplicate_of", "result"]
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def _trim_issue(issue: str | None, max_chars: int) -> str | None:
|
|
40
|
+
if issue is None or len(issue) <= max_chars:
|
|
41
|
+
return issue
|
|
42
|
+
return f"(TRUNCATED - showing the last {max_chars} characters)\n" + issue[-max_chars:]
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def normalized_diff_hash(diff_files: dict[str, str] | None) -> str | None:
|
|
46
|
+
"""Hashes a fix's diff so that essentially identical retries can be detected.
|
|
47
|
+
|
|
48
|
+
Whitespace-only differences are ignored - a fix that reproduces an earlier failed change with
|
|
49
|
+
different formatting is still the same attempt.
|
|
50
|
+
"""
|
|
51
|
+
if not diff_files:
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
normalized_parts = []
|
|
55
|
+
for file_name in sorted(diff_files):
|
|
56
|
+
content_lines = [line.strip() for line in (diff_files[file_name] or "").splitlines() if line.strip()]
|
|
57
|
+
normalized_parts.append(file_name + "\n" + "\n".join(content_lines))
|
|
58
|
+
|
|
59
|
+
return hashlib.sha256("\n".join(normalized_parts).encode("utf-8")).hexdigest()
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
class FixAttemptJournal:
|
|
63
|
+
"""File-backed journal, one JSONL file per (module, frid) whose conformance tests are fixed."""
|
|
64
|
+
|
|
65
|
+
def __init__(self, memory_folder: str):
|
|
66
|
+
self.journal_folder = os.path.join(memory_folder, CONFORMANCE_TEST_JOURNAL_SUBFOLDER)
|
|
67
|
+
|
|
68
|
+
def _journal_path(self, module_name: str, frid: str) -> str:
|
|
69
|
+
return os.path.join(self.journal_folder, f"{module_name}__{frid}.jsonl")
|
|
70
|
+
|
|
71
|
+
def _read_entries(self, module_name: str, frid: str) -> list[dict]:
|
|
72
|
+
journal_path = self._journal_path(module_name, frid)
|
|
73
|
+
if not os.path.exists(journal_path):
|
|
74
|
+
return []
|
|
75
|
+
|
|
76
|
+
entries = []
|
|
77
|
+
with open(journal_path, "r", encoding="utf-8") as journal_file:
|
|
78
|
+
for line in journal_file:
|
|
79
|
+
line = line.strip()
|
|
80
|
+
if not line:
|
|
81
|
+
continue
|
|
82
|
+
try:
|
|
83
|
+
entries.append(json.loads(line))
|
|
84
|
+
except json.JSONDecodeError:
|
|
85
|
+
console.error(f"Skipping malformed journal entry in {journal_path}.")
|
|
86
|
+
|
|
87
|
+
return entries
|
|
88
|
+
|
|
89
|
+
def _write_entries(self, module_name: str, frid: str, entries: list[dict]):
|
|
90
|
+
os.makedirs(self.journal_folder, exist_ok=True)
|
|
91
|
+
with open(self._journal_path(module_name, frid), "w", encoding="utf-8") as journal_file:
|
|
92
|
+
for entry in entries:
|
|
93
|
+
journal_file.write(json.dumps(entry) + "\n")
|
|
94
|
+
|
|
95
|
+
def open_attempt(self, module_name: str, frid: str, attempt_no: int, issue_before: str):
|
|
96
|
+
"""Starts a new journal entry for a fix attempt that is about to be made.
|
|
97
|
+
|
|
98
|
+
The raw issue is stored untruncated - it never travels in a payload, only its prepared form
|
|
99
|
+
(recorded later by record_fix) does.
|
|
100
|
+
"""
|
|
101
|
+
entries = self._read_entries(module_name, frid)
|
|
102
|
+
entries.append({"attempt": attempt_no, "issue_before_raw": issue_before})
|
|
103
|
+
self._write_entries(module_name, frid, entries)
|
|
104
|
+
|
|
105
|
+
def record_fix(
|
|
106
|
+
self,
|
|
107
|
+
module_name: str,
|
|
108
|
+
frid: str,
|
|
109
|
+
fix_attempt_summary: dict | None,
|
|
110
|
+
files_changed: list[str],
|
|
111
|
+
target: str,
|
|
112
|
+
diff_files: dict[str, str] | None,
|
|
113
|
+
prepared_issue: str | None,
|
|
114
|
+
):
|
|
115
|
+
"""Completes the open attempt with what the fix actually did.
|
|
116
|
+
|
|
117
|
+
The prepared issue is the form the server built for the fix prompt - the issue exactly the
|
|
118
|
+
way the fixer saw it. The diff hash marks the attempt as a duplicate when an earlier attempt
|
|
119
|
+
in the same journal produced essentially the same change - the strongest signal that the
|
|
120
|
+
fixer is going in circles.
|
|
121
|
+
"""
|
|
122
|
+
entries = self._read_entries(module_name, frid)
|
|
123
|
+
if not entries:
|
|
124
|
+
console.error("Cannot record a fix - no journal entry is open.")
|
|
125
|
+
return
|
|
126
|
+
|
|
127
|
+
entry = entries[-1]
|
|
128
|
+
if isinstance(fix_attempt_summary, dict):
|
|
129
|
+
entry["hypothesis"] = fix_attempt_summary.get("hypothesis")
|
|
130
|
+
entry["approach"] = fix_attempt_summary.get("approach")
|
|
131
|
+
if prepared_issue:
|
|
132
|
+
entry["issue_before"] = prepared_issue
|
|
133
|
+
entry["files_changed"] = sorted(files_changed)
|
|
134
|
+
entry["target"] = target
|
|
135
|
+
|
|
136
|
+
diff_hash = normalized_diff_hash(diff_files)
|
|
137
|
+
entry["diff_hash"] = diff_hash
|
|
138
|
+
if diff_hash is not None:
|
|
139
|
+
for earlier_entry in entries[:-1]:
|
|
140
|
+
if earlier_entry.get("diff_hash") == diff_hash:
|
|
141
|
+
entry["duplicate_of"] = earlier_entry["attempt"]
|
|
142
|
+
break
|
|
143
|
+
|
|
144
|
+
self._write_entries(module_name, frid, entries)
|
|
145
|
+
|
|
146
|
+
def record_result(self, module_name: str, frid: str, passed: bool):
|
|
147
|
+
"""Records whether the conformance tests passed after the last fix attempt was applied.
|
|
148
|
+
|
|
149
|
+
A failed run's output is not stored here - it becomes the raw issue of the next attempt.
|
|
150
|
+
Does nothing when no attempt is pending: the first test run of a functionality has no fix
|
|
151
|
+
attempt behind it.
|
|
152
|
+
"""
|
|
153
|
+
entries = self._read_entries(module_name, frid)
|
|
154
|
+
if not entries or "result" in entries[-1]:
|
|
155
|
+
return
|
|
156
|
+
|
|
157
|
+
entries[-1]["result"] = "conformance tests passed" if passed else "conformance tests still failed"
|
|
158
|
+
self._write_entries(module_name, frid, entries)
|
|
159
|
+
|
|
160
|
+
def build_digest(self, module_name: str, frid: str) -> list[dict]:
|
|
161
|
+
"""Builds the compact attempt history sent with a fix request.
|
|
162
|
+
|
|
163
|
+
Only attempts whose fix has been recorded are included - the entry just opened for the
|
|
164
|
+
attempt being made (and any dangling entry an interrupted render left behind) carries no
|
|
165
|
+
information for the fixer. Each included attempt carries the prepared issue it addressed,
|
|
166
|
+
so the fixer can see how the issue evolved across attempts. Raw outputs never travel - the
|
|
167
|
+
current issue is sent with the request separately.
|
|
168
|
+
"""
|
|
169
|
+
return [self._digest_entry(entry) for entry in self._read_entries(module_name, frid) if "target" in entry]
|
|
170
|
+
|
|
171
|
+
@staticmethod
|
|
172
|
+
def _digest_entry(entry: dict) -> dict:
|
|
173
|
+
digest_entry = {key: entry[key] for key in DIGEST_KEYS if key in entry}
|
|
174
|
+
if entry.get("issue_before"):
|
|
175
|
+
digest_entry["issue"] = _trim_issue(entry["issue_before"], MAX_ISSUE_EXCERPT_CHARS)
|
|
176
|
+
return digest_entry
|
|
177
|
+
|
|
178
|
+
def collect_all(self) -> list[dict]:
|
|
179
|
+
"""Collects the digests of every journal, keyed by the tested module and frid, for distillation."""
|
|
180
|
+
if not os.path.exists(self.journal_folder):
|
|
181
|
+
return []
|
|
182
|
+
|
|
183
|
+
journals = []
|
|
184
|
+
for file_name in sorted(os.listdir(self.journal_folder)):
|
|
185
|
+
if not file_name.endswith(".jsonl") or "__" not in file_name:
|
|
186
|
+
continue
|
|
187
|
+
module_name, _, frid = file_name[: -len(".jsonl")].rpartition("__")
|
|
188
|
+
entries = [entry for entry in self._read_entries(module_name, frid) if "target" in entry]
|
|
189
|
+
if not entries:
|
|
190
|
+
continue
|
|
191
|
+
initial_issue = entries[0].get("issue_before") or _trim_issue(
|
|
192
|
+
entries[0].get("issue_before_raw"), MAX_ISSUE_EXCERPT_CHARS
|
|
193
|
+
)
|
|
194
|
+
journal = {
|
|
195
|
+
"module": module_name,
|
|
196
|
+
"frid": frid,
|
|
197
|
+
"initial_issue": initial_issue,
|
|
198
|
+
"attempts": [self._digest_entry(entry) for entry in entries],
|
|
199
|
+
}
|
|
200
|
+
journals.append(journal)
|
|
201
|
+
|
|
202
|
+
return journals
|
|
203
|
+
|
|
204
|
+
def clear_all(self):
|
|
205
|
+
"""Deletes every journal. Called after the journals have been distilled into memories."""
|
|
206
|
+
if os.path.exists(self.journal_folder):
|
|
207
|
+
shutil.rmtree(self.journal_folder)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
import file_utils
|
|
4
|
+
from conformance_fix_journal import FixAttemptJournal
|
|
5
|
+
from plain2code_console import console
|
|
6
|
+
|
|
7
|
+
CONFORMANCE_TEST_MEMORY_SUBFOLDER = "conformance_test_memory"
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class MemoryManager:
|
|
11
|
+
"""Manages a module's memory store at <build>/<module>/.memory.
|
|
12
|
+
|
|
13
|
+
The distilled memories are inherited by the next module in the chain (copied over when its
|
|
14
|
+
render starts, like the code repo), so learnings travel across modules.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
@staticmethod
|
|
18
|
+
def fetch_memory_files(memory_folder: str) -> tuple[list[str], dict[str, str]]:
|
|
19
|
+
"""Fetch memory files from memory_folder/conformance_test_memory."""
|
|
20
|
+
memory_path = os.path.join(memory_folder, CONFORMANCE_TEST_MEMORY_SUBFOLDER)
|
|
21
|
+
if not os.path.exists(memory_path):
|
|
22
|
+
return [], {}
|
|
23
|
+
memory_files = file_utils.list_all_text_files(memory_path)
|
|
24
|
+
memory_files_content = file_utils.get_existing_files_content(memory_path, memory_files)
|
|
25
|
+
console.debug(f"Loaded {len(memory_files_content)} memory files.")
|
|
26
|
+
return memory_files, memory_files_content
|
|
27
|
+
|
|
28
|
+
def __init__(self, codeplain_api, memory_folder: str):
|
|
29
|
+
self.codeplain_api = codeplain_api
|
|
30
|
+
self.memory_folder = memory_folder
|
|
31
|
+
self.journal = FixAttemptJournal(memory_folder)
|
|
32
|
+
|
|
33
|
+
def store_memory_files(self, response_files: dict[str, str]):
|
|
34
|
+
"""Stores distilled memory files, applying deletions (None content) to existing memories."""
|
|
35
|
+
memory_path = os.path.join(self.memory_folder, CONFORMANCE_TEST_MEMORY_SUBFOLDER)
|
|
36
|
+
memory_files, _ = MemoryManager.fetch_memory_files(self.memory_folder)
|
|
37
|
+
file_utils.store_response_files(memory_path, response_files, memory_files)
|
|
38
|
+
|
|
39
|
+
@staticmethod
|
|
40
|
+
def inherit_memories(source_memory_folder: str, destination_memory_folder: str):
|
|
41
|
+
"""Copies the distilled memories of a previously rendered module into this module's store.
|
|
42
|
+
|
|
43
|
+
Only the distilled memories travel - fix attempt journals are transient state of one
|
|
44
|
+
module's render. A previous module without memories (e.g. shipped as an archive that
|
|
45
|
+
carries only code) is a no-op.
|
|
46
|
+
"""
|
|
47
|
+
source_path = os.path.join(source_memory_folder, CONFORMANCE_TEST_MEMORY_SUBFOLDER)
|
|
48
|
+
if not os.path.isdir(source_path):
|
|
49
|
+
return
|
|
50
|
+
file_utils.copy_folder_content(
|
|
51
|
+
source_path, os.path.join(destination_memory_folder, CONFORMANCE_TEST_MEMORY_SUBFOLDER)
|
|
52
|
+
)
|