codeplain 0.3.9__tar.gz → 0.3.10.dev2__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.9 → codeplain-0.3.10.dev2}/.github/workflows/e2e.yml +28 -1
- codeplain-0.3.10.dev2/.github/workflows/lint-powershell.yml +124 -0
- codeplain-0.3.10.dev2/.github/workflows/publish-dev-to-pypi.yml +147 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.github/workflows/publish-to-pypi.yml +14 -1
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/CLAUDE.md +4 -4
- codeplain-0.3.10.dev2/CONTRIBUTING.md +137 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/PKG-INFO +36 -8
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/README.md +31 -3
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/concept_utils.py +6 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/docs/plain2code_cli.md +3 -3
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/install/bash/install.sh +41 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/install/powershell/examples.ps1 +11 -5
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/install/powershell/install.ps1 +131 -19
- codeplain-0.3.10.dev2/install/powershell/walkthrough.ps1 +174 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/module_renderer.py +6 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/partial_rendering.py +35 -4
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code.py +31 -3
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_arguments.py +7 -4
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_console.py +3 -1
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_exceptions.py +8 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_logger.py +37 -15
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain_file.py +18 -1
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain_modules.py +197 -7
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/pyproject.toml +3 -3
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/prepare_repositories.py +5 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/conformance_tests.py +40 -3
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/implementation_code_helpers.py +5 -1
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/render_context.py +13 -1
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/requirements.txt +3 -3
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/system_config.py +35 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_cli_output.py +13 -0
- codeplain-0.3.10.dev2/tests/test_headless_logging.py +177 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_plain_modules.py +267 -1
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_plainfileparser.py +41 -4
- codeplain-0.3.10.dev2/tests/test_prepare_repositories_layout.py +277 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_system_config.py +37 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/plain_module_render_choice_tui.py +25 -8
- codeplain-0.3.9/install/powershell/walkthrough.ps1 +0 -161
- codeplain-0.3.9/tests/test_prepare_repositories_layout.py +0 -119
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.claude/settings.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.flake8 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.github/dependabot.yml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.gitignore +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.vscode/launch.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/.vscode/settings.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/LICENSE +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/change_detection.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/cli_output/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/cli_output/status.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/codeplain_REST_api.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/config/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/config/system_config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/diff_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/docs/generate_cli.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/event_bus.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/examples/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/file_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/git_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/install/bash/examples.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/memory_management.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/metadata_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_cli.md +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_events.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_nodes.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_read_config.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_state.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_telemetry.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain2code_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/plain_spec.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/pytest.ini +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/fix_conformance_test.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/run_conformance_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/code_renderer.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/render_types.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/render_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/states.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/render_machine/triggers.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/resources/plain_example.png +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/conftest.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/simple.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/e2e/test_hello_world_python.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/e2e/test_hello_world_python_windows.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_arg_provenance.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_console_log_styles.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_folder_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_imports.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_plain2code.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_requires.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_telemetry.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/components.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/models.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/spinner.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/state_handlers.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/styles.css +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/tui/widget_helpers.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10.dev2}/usage_summary.py +0 -0
|
@@ -59,4 +59,31 @@ jobs:
|
|
|
59
59
|
- name: Run E2E tests
|
|
60
60
|
env:
|
|
61
61
|
CODEPLAIN_API_KEY: ${{ secrets.CODEPLAIN_API_KEY }}
|
|
62
|
-
run: pytest tests/e2e/ -v --tb=short
|
|
62
|
+
run: pytest tests/e2e/ -v --tb=short
|
|
63
|
+
|
|
64
|
+
notify-on-failure:
|
|
65
|
+
name: Notify Slack on failure
|
|
66
|
+
needs: [e2e-linux, e2e-windows]
|
|
67
|
+
if: failure()
|
|
68
|
+
runs-on: ubuntu-latest
|
|
69
|
+
env:
|
|
70
|
+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_E2E_WEBHOOK_URL }}
|
|
71
|
+
steps:
|
|
72
|
+
- name: Determine failed platforms
|
|
73
|
+
id: platforms
|
|
74
|
+
run: |
|
|
75
|
+
failed=""
|
|
76
|
+
[ "${{ needs.e2e-linux.result }}" = "failure" ] && failed="Linux"
|
|
77
|
+
if [ "${{ needs.e2e-windows.result }}" = "failure" ]; then
|
|
78
|
+
[ -n "$failed" ] && failed="$failed and Windows" || failed="Windows"
|
|
79
|
+
fi
|
|
80
|
+
echo "failed=$failed" >> "$GITHUB_OUTPUT"
|
|
81
|
+
|
|
82
|
+
- name: Send failure notification to Slack
|
|
83
|
+
if: ${{ env.SLACK_WEBHOOK_URL != '' }}
|
|
84
|
+
uses: slackapi/slack-github-action@v1.24.0
|
|
85
|
+
with:
|
|
86
|
+
payload: |
|
|
87
|
+
{
|
|
88
|
+
"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)) }}
|
|
89
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
name: PowerShell Install Scripts
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
paths:
|
|
6
|
+
- 'install/powershell/*.ps1'
|
|
7
|
+
- '.github/workflows/lint-powershell.yml'
|
|
8
|
+
pull_request:
|
|
9
|
+
paths:
|
|
10
|
+
- 'install/powershell/*.ps1'
|
|
11
|
+
- '.github/workflows/lint-powershell.yml'
|
|
12
|
+
workflow_dispatch:
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
parse-windows-powershell-51:
|
|
16
|
+
name: Parse under Windows PowerShell 5.1
|
|
17
|
+
runs-on: windows-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@v4
|
|
20
|
+
|
|
21
|
+
# The install scripts are fetched over HTTP and executed on stock Windows,
|
|
22
|
+
# where powershell.exe (5.1) is the default shell. 5.1 reads BOM-less files
|
|
23
|
+
# as ANSI (CP1252), so a non-ASCII glyph such as U+2713 decodes into a smart
|
|
24
|
+
# quote that silently terminates the enclosing string. The resulting parse
|
|
25
|
+
# errors point at unrelated lines far below the real cause, so parse every
|
|
26
|
+
# script with 5.1 explicitly rather than relying on PowerShell 7.
|
|
27
|
+
- name: Parse each script with 5.1
|
|
28
|
+
shell: powershell
|
|
29
|
+
run: |
|
|
30
|
+
$ErrorActionPreference = 'Stop'
|
|
31
|
+
Write-Host "PowerShell $($PSVersionTable.PSVersion) / ANSI codepage $([System.Text.Encoding]::Default.WebName)"
|
|
32
|
+
|
|
33
|
+
$failed = $false
|
|
34
|
+
Get-ChildItem 'install/powershell' -Filter *.ps1 | Sort-Object Name | ForEach-Object {
|
|
35
|
+
$errors = $null
|
|
36
|
+
[System.Management.Automation.Language.Parser]::ParseFile(
|
|
37
|
+
$_.FullName, [ref]$null, [ref]$errors) | Out-Null
|
|
38
|
+
|
|
39
|
+
if ($errors -and $errors.Count -gt 0) {
|
|
40
|
+
$failed = $true
|
|
41
|
+
Write-Host "FAIL $($_.Name): $($errors.Count) parse error(s)"
|
|
42
|
+
$errors | Sort-Object { $_.Extent.StartLineNumber } | ForEach-Object {
|
|
43
|
+
Write-Host " L$($_.Extent.StartLineNumber): $($_.Message)"
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
Write-Host "OK $($_.Name)"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if ($failed) { exit 1 }
|
|
51
|
+
|
|
52
|
+
# A BOM would fix file-based parsing but break `irm ... | iex`: PowerShell 5.1
|
|
53
|
+
# decodes an HTTP text/* body with no charset as ISO-8859-1, turning the BOM
|
|
54
|
+
# into literal "i>>?" text and failing with
|
|
55
|
+
# "The term 'i>>?$ErrorActionPreference' is not recognized".
|
|
56
|
+
# Keeping the sources pure ASCII is what makes both paths safe, so enforce it.
|
|
57
|
+
- name: Require pure ASCII and no BOM
|
|
58
|
+
shell: powershell
|
|
59
|
+
run: |
|
|
60
|
+
$ErrorActionPreference = 'Stop'
|
|
61
|
+
$failed = $false
|
|
62
|
+
|
|
63
|
+
Get-ChildItem 'install/powershell' -Filter *.ps1 | Sort-Object Name | ForEach-Object {
|
|
64
|
+
$fileBad = $false
|
|
65
|
+
$bytes = [System.IO.File]::ReadAllBytes($_.FullName)
|
|
66
|
+
|
|
67
|
+
if ($bytes.Length -ge 3 -and $bytes[0] -eq 0xEF -and $bytes[1] -eq 0xBB -and $bytes[2] -eq 0xBF) {
|
|
68
|
+
$failed = $true
|
|
69
|
+
$fileBad = $true
|
|
70
|
+
Write-Host "FAIL $($_.Name): has a UTF-8 BOM (breaks 'irm | iex'); remove it"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
# Report line/column of any byte outside ASCII so the fix is obvious.
|
|
74
|
+
$text = [System.Text.Encoding]::UTF8.GetString($bytes)
|
|
75
|
+
$lineNo = 0
|
|
76
|
+
foreach ($line in ($text -split "`r?`n")) {
|
|
77
|
+
$lineNo++
|
|
78
|
+
for ($i = 0; $i -lt $line.Length; $i++) {
|
|
79
|
+
if ([int]$line[$i] -gt 127) {
|
|
80
|
+
$failed = $true
|
|
81
|
+
$fileBad = $true
|
|
82
|
+
$cp = "U+{0:X4}" -f [int]$line[$i]
|
|
83
|
+
Write-Host "FAIL $($_.Name) L${lineNo} C$($i + 1): non-ASCII $cp"
|
|
84
|
+
Write-Host " build it from its code point instead, e.g. `$CHECK = [char]0x2713"
|
|
85
|
+
break
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (-not $fileBad) { Write-Host "OK $($_.Name)" }
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if ($failed) { exit 1 }
|
|
94
|
+
|
|
95
|
+
parse-powershell-7:
|
|
96
|
+
name: Parse under PowerShell 7
|
|
97
|
+
runs-on: windows-latest
|
|
98
|
+
steps:
|
|
99
|
+
- uses: actions/checkout@v4
|
|
100
|
+
|
|
101
|
+
- name: Parse each script with 7
|
|
102
|
+
shell: pwsh
|
|
103
|
+
run: |
|
|
104
|
+
$ErrorActionPreference = 'Stop'
|
|
105
|
+
Write-Host "PowerShell $($PSVersionTable.PSVersion)"
|
|
106
|
+
|
|
107
|
+
$failed = $false
|
|
108
|
+
Get-ChildItem 'install/powershell' -Filter *.ps1 | Sort-Object Name | ForEach-Object {
|
|
109
|
+
$errors = $null
|
|
110
|
+
[System.Management.Automation.Language.Parser]::ParseFile(
|
|
111
|
+
$_.FullName, [ref]$null, [ref]$errors) | Out-Null
|
|
112
|
+
|
|
113
|
+
if ($errors -and $errors.Count -gt 0) {
|
|
114
|
+
$failed = $true
|
|
115
|
+
Write-Host "FAIL $($_.Name): $($errors.Count) parse error(s)"
|
|
116
|
+
$errors | Sort-Object { $_.Extent.StartLineNumber } | ForEach-Object {
|
|
117
|
+
Write-Host " L$($_.Extent.StartLineNumber): $($_.Message)"
|
|
118
|
+
}
|
|
119
|
+
} else {
|
|
120
|
+
Write-Host "OK $($_.Name)"
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if ($failed) { exit 1 }
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
name: Publish dev build to PyPI
|
|
2
|
+
|
|
3
|
+
# Every merge to main publishes a PEP 440 dev release (e.g. 0.3.10.dev7) to
|
|
4
|
+
# PyPI, so the latest main is always installable from the real index with real
|
|
5
|
+
# dependency resolution. Dev releases are pre-releases: pip and uv skip them
|
|
6
|
+
# unless asked, so ordinary installs keep getting the latest stable.
|
|
7
|
+
#
|
|
8
|
+
# Tagged releases (including rc/beta/alpha) are handled by publish-to-pypi.yml.
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
branches: [main]
|
|
12
|
+
# Ad-hoc runs, e.g. re-publishing after a PyPI outage.
|
|
13
|
+
workflow_dispatch:
|
|
14
|
+
|
|
15
|
+
# Least privilege by default: jobs get no GITHUB_TOKEN scopes unless they
|
|
16
|
+
# opt in below.
|
|
17
|
+
permissions: {}
|
|
18
|
+
|
|
19
|
+
# Serialize publishes so versions land in merge order. Queued runs are not
|
|
20
|
+
# cancelled — each merge should still get its own dev build.
|
|
21
|
+
concurrency:
|
|
22
|
+
group: publish-dev-to-pypi
|
|
23
|
+
cancel-in-progress: false
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
build:
|
|
27
|
+
name: Build dev distribution
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
permissions:
|
|
30
|
+
contents: read
|
|
31
|
+
outputs:
|
|
32
|
+
should-publish: ${{ steps.version.outputs.should-publish }}
|
|
33
|
+
version: ${{ steps.version.outputs.version }}
|
|
34
|
+
|
|
35
|
+
steps:
|
|
36
|
+
- uses: actions/checkout@v4
|
|
37
|
+
with:
|
|
38
|
+
# hatch-vcs derives the version from git tags, so we need full history.
|
|
39
|
+
fetch-depth: 0
|
|
40
|
+
|
|
41
|
+
- name: Install uv
|
|
42
|
+
# uv provisions its own Python (honoring requires-python), so no
|
|
43
|
+
# separate actions/setup-python step is needed.
|
|
44
|
+
run: |
|
|
45
|
+
curl -LsSf https://astral.sh/uv/install.sh | sh
|
|
46
|
+
echo "$HOME/.local/bin" >> $GITHUB_PATH
|
|
47
|
+
|
|
48
|
+
- name: Compute dev version
|
|
49
|
+
id: version
|
|
50
|
+
# Between releases hatch-vcs produces something like
|
|
51
|
+
# "0.3.10.dev16+gb710c2982". The "+g..." local version segment is valid
|
|
52
|
+
# PEP 440 but is rejected by PyPI on upload, so it has to go. We keep
|
|
53
|
+
# setuptools-scm's own next-version guess (0.3.10 — the patch bump
|
|
54
|
+
# after the latest tag) rather than re-deriving it here, and use the
|
|
55
|
+
# run number as the dev counter: it is strictly increasing, so each
|
|
56
|
+
# merge sorts after the last and re-runs never collide.
|
|
57
|
+
run: |
|
|
58
|
+
RAW=$(uvx --from setuptools-scm python -c \
|
|
59
|
+
"from setuptools_scm import get_version; print(get_version())")
|
|
60
|
+
echo "setuptools-scm reports: $RAW"
|
|
61
|
+
|
|
62
|
+
# On a commit that IS a release tag, setuptools-scm returns a clean
|
|
63
|
+
# version with no .dev component (e.g. "0.3.9" or "0.4.0rc1").
|
|
64
|
+
# Appending ".dev<run>" to that yields 0.3.9.dev42, which sorts BELOW
|
|
65
|
+
# the released 0.3.9 — newer code would look older. A tagged commit
|
|
66
|
+
# is a real release and is published by publish-to-pypi.yml, so there
|
|
67
|
+
# is no dev build to make here.
|
|
68
|
+
case "$RAW" in
|
|
69
|
+
*.dev*) ;;
|
|
70
|
+
*)
|
|
71
|
+
echo "::notice::$RAW is a tagged release; skipping dev build."
|
|
72
|
+
echo "should-publish=false" >> $GITHUB_OUTPUT
|
|
73
|
+
exit 0
|
|
74
|
+
;;
|
|
75
|
+
esac
|
|
76
|
+
|
|
77
|
+
BASE=${RAW%%+*}
|
|
78
|
+
BASE=${BASE%%.dev*}
|
|
79
|
+
VERSION="${BASE}.dev${GITHUB_RUN_NUMBER}"
|
|
80
|
+
echo "Derived version: $RAW -> $VERSION"
|
|
81
|
+
echo "SETUPTOOLS_SCM_PRETEND_VERSION=$VERSION" >> $GITHUB_ENV
|
|
82
|
+
echo "should-publish=true" >> $GITHUB_OUTPUT
|
|
83
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
84
|
+
|
|
85
|
+
- name: Build package
|
|
86
|
+
if: steps.version.outputs.should-publish == 'true'
|
|
87
|
+
# hatch-vcs reads SETUPTOOLS_SCM_PRETEND_VERSION in place of the tag.
|
|
88
|
+
run: |
|
|
89
|
+
uv build
|
|
90
|
+
echo "Built distributions:"
|
|
91
|
+
ls -l dist/
|
|
92
|
+
|
|
93
|
+
- name: Store the distribution packages
|
|
94
|
+
if: steps.version.outputs.should-publish == 'true'
|
|
95
|
+
uses: actions/upload-artifact@v4
|
|
96
|
+
with:
|
|
97
|
+
name: dev-package-distributions
|
|
98
|
+
path: dist/
|
|
99
|
+
|
|
100
|
+
publish-dev:
|
|
101
|
+
name: Publish dev build to PyPI
|
|
102
|
+
needs: build
|
|
103
|
+
if: needs.build.outputs.should-publish == 'true'
|
|
104
|
+
runs-on: ubuntu-latest
|
|
105
|
+
environment:
|
|
106
|
+
name: pypi
|
|
107
|
+
url: https://pypi.org/p/codeplain
|
|
108
|
+
permissions:
|
|
109
|
+
# Mint a short-lived OIDC token so PyPI Trusted Publishing can
|
|
110
|
+
# authenticate this run — no long-lived API token needed.
|
|
111
|
+
id-token: write
|
|
112
|
+
|
|
113
|
+
env:
|
|
114
|
+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
115
|
+
|
|
116
|
+
steps:
|
|
117
|
+
- name: Download distribution packages
|
|
118
|
+
uses: actions/download-artifact@v4
|
|
119
|
+
with:
|
|
120
|
+
name: dev-package-distributions
|
|
121
|
+
path: dist/
|
|
122
|
+
|
|
123
|
+
- name: Publish to PyPI
|
|
124
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
125
|
+
with:
|
|
126
|
+
# PyPI uploads are immutable, so a re-run of an already-published
|
|
127
|
+
# version should be a no-op, not a red build.
|
|
128
|
+
skip-existing: true
|
|
129
|
+
|
|
130
|
+
- name: Notify Slack (success)
|
|
131
|
+
if: ${{ success() && env.SLACK_WEBHOOK_URL != '' }}
|
|
132
|
+
env:
|
|
133
|
+
VERSION: ${{ needs.build.outputs.version }}
|
|
134
|
+
run: |
|
|
135
|
+
# Spell out the --pre install: a plain "pip install codeplain" will
|
|
136
|
+
# NOT pick this up, which otherwise reads as a broken publish.
|
|
137
|
+
TEXT="*Codeplain Client*: dev build \`$VERSION\` published to PyPI :test_tube:. Normal installs are unaffected — try it with \`pip install --pre codeplain==$VERSION\`. Pre-release builds talk to \`api.test.codeplain.ai\` by default."
|
|
138
|
+
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
139
|
+
-H 'Content-type: application/json' \
|
|
140
|
+
--data "$(jq -n --arg t "$TEXT" '{text:$t}')"
|
|
141
|
+
|
|
142
|
+
- name: Notify Slack (failure)
|
|
143
|
+
if: ${{ failure() && env.SLACK_WEBHOOK_URL != '' }}
|
|
144
|
+
run: |
|
|
145
|
+
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
146
|
+
-H 'Content-type: application/json' \
|
|
147
|
+
--data "{\"text\":\"*Codeplain Client*: Publishing dev build to PyPI FAILED :x: (commit \`${{ github.sha }}\`). See <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|the run log>.\"}"
|
|
@@ -91,10 +91,23 @@ jobs:
|
|
|
91
91
|
|
|
92
92
|
- name: Notify Slack (success)
|
|
93
93
|
if: ${{ success() && env.SLACK_WEBHOOK_URL != '' }}
|
|
94
|
+
env:
|
|
95
|
+
# GitHub marks the release itself as a pre-release; the tag
|
|
96
|
+
# (v0.4.0rc1) carries the same intent for PEP 440.
|
|
97
|
+
IS_PRERELEASE: ${{ github.event.release.prerelease }}
|
|
98
|
+
TAG: ${{ github.ref_name }}
|
|
94
99
|
run: |
|
|
100
|
+
VERSION="${TAG#v}"
|
|
101
|
+
if [ "$IS_PRERELEASE" = "true" ]; then
|
|
102
|
+
# pip and uv skip pre-releases by default, so "--upgrade" would
|
|
103
|
+
# NOT pick this up. Tell people the command that actually works.
|
|
104
|
+
TEXT="*Codeplain Client*: pre-release \`$TAG\` published to PyPI :test_tube:. Normal installs are unaffected — try it with \`pip install --pre codeplain==$VERSION\`."
|
|
105
|
+
else
|
|
106
|
+
TEXT="*Codeplain Client*: \`$TAG\` published to PyPI :white_check_mark:. Install with \`pip install --upgrade codeplain\`."
|
|
107
|
+
fi
|
|
95
108
|
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
96
109
|
-H 'Content-type: application/json' \
|
|
97
|
-
--data "
|
|
110
|
+
--data "$(jq -n --arg t "$TEXT" '{text:$t}')"
|
|
98
111
|
|
|
99
112
|
- name: Notify Slack (failure)
|
|
100
113
|
if: ${{ failure() && env.SLACK_WEBHOOK_URL != '' }}
|
|
@@ -14,14 +14,14 @@ The codebase serves two audiences:
|
|
|
14
14
|
- **End users**: developers who write `***plain` specs and run `plain2code.py` to generate code
|
|
15
15
|
- **Internal devs**: maintaining the renderer itself (this codebase)
|
|
16
16
|
|
|
17
|
-
### Related Repository:
|
|
17
|
+
### Related Repository: codeplain-api
|
|
18
18
|
|
|
19
|
-
This repository has a sibling repository **`
|
|
19
|
+
This repository has a sibling repository **`codeplain-api`** which contains the backend API service that this client communicates with. The two repositories are typically cloned as siblings:
|
|
20
20
|
|
|
21
21
|
```
|
|
22
22
|
parent-directory/
|
|
23
|
-
├── codeplain/
|
|
24
|
-
└──
|
|
23
|
+
├── codeplain/ # This repository (client)
|
|
24
|
+
└── codeplain-api/ # Backend API service
|
|
25
25
|
```
|
|
26
26
|
|
|
27
27
|
**When to work across both repositories:**
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
# Contributing to Codeplain
|
|
2
|
+
|
|
3
|
+
Thanks for contributing to Codeplain.
|
|
4
|
+
|
|
5
|
+
## Before You Start
|
|
6
|
+
|
|
7
|
+
Check existing issues and pull requests before starting work.
|
|
8
|
+
|
|
9
|
+
Keep each contribution focused on one issue or a closely related set of changes.
|
|
10
|
+
|
|
11
|
+
## Contribution Workflow
|
|
12
|
+
|
|
13
|
+
1. Fork the Codeplain repository.
|
|
14
|
+
2. Make your changes on a branch in your fork.
|
|
15
|
+
3. Commit and push the changes to your fork.
|
|
16
|
+
4. Open a pull request against the Codeplain `main` branch.
|
|
17
|
+
|
|
18
|
+
## Configure Codeplain
|
|
19
|
+
|
|
20
|
+
Use your own Codeplain API key for local development and testing.
|
|
21
|
+
|
|
22
|
+
Never commit API keys, credentials, or other secrets.
|
|
23
|
+
|
|
24
|
+
## Test with a Plain Example
|
|
25
|
+
|
|
26
|
+
When relevant, test your change with an existing example from the `plainlang-examples` repository.
|
|
27
|
+
|
|
28
|
+
This provides a real `.plain` project for verifying the change in an actual Codeplain workflow.
|
|
29
|
+
|
|
30
|
+
## Run Tests
|
|
31
|
+
|
|
32
|
+
Run the tests relevant to your change before opening a pull request.
|
|
33
|
+
|
|
34
|
+
For changes that affect the CLI, rendering, or test execution, also test the change by running the relevant Codeplain command from the terminal.
|
|
35
|
+
|
|
36
|
+
Check that:
|
|
37
|
+
|
|
38
|
+
* the command returns the expected exit code,
|
|
39
|
+
* errors are clear and do not expose unintended tracebacks,
|
|
40
|
+
* existing Codeplain behavior still works.
|
|
41
|
+
|
|
42
|
+
For platform-specific changes, test the relevant `.sh` or `.ps1` workflow.
|
|
43
|
+
|
|
44
|
+
## Keep the Change Clean
|
|
45
|
+
|
|
46
|
+
Before submitting:
|
|
47
|
+
|
|
48
|
+
* remove temporary files and debugging output,
|
|
49
|
+
* avoid unrelated changes,
|
|
50
|
+
* add or update tests where needed,
|
|
51
|
+
* update documentation when behavior changes,
|
|
52
|
+
* verify that no secrets are included.
|
|
53
|
+
|
|
54
|
+
Review your changes with:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
git status
|
|
58
|
+
git diff
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Pull Request
|
|
62
|
+
|
|
63
|
+
Include:
|
|
64
|
+
|
|
65
|
+
* what changed,
|
|
66
|
+
* why it changed,
|
|
67
|
+
* the related issue, when applicable,
|
|
68
|
+
* how the change was tested,
|
|
69
|
+
* the `plainlang-examples` example used, when relevant.
|
|
70
|
+
|
|
71
|
+
## Pre-Releases
|
|
72
|
+
|
|
73
|
+
Everything below happens on real PyPI — there is no separate test index.
|
|
74
|
+
Pre-releases are invisible to ordinary installs: pip and uv skip them during
|
|
75
|
+
resolution, so `pip install codeplain` and `pip install --upgrade codeplain`
|
|
76
|
+
always serve the latest *stable* release.
|
|
77
|
+
|
|
78
|
+
### Dev builds (automatic)
|
|
79
|
+
|
|
80
|
+
Every merge to `main` publishes a dev release such as `0.3.10.dev7`, so the tip
|
|
81
|
+
of main is always installable from the real index:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
pip install --pre codeplain==0.3.10.dev7
|
|
85
|
+
uv tool install --prerelease allow codeplain
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Versions are `<next-patch>.dev<run-number>`, so they sort after the last
|
|
89
|
+
release and before the next one. See `.github/workflows/publish-dev-to-pypi.yml`.
|
|
90
|
+
If that workflow is ever dispatched against a commit that is itself a release
|
|
91
|
+
tag, it skips rather than publishing a dev build that would sort below the
|
|
92
|
+
release.
|
|
93
|
+
|
|
94
|
+
### Release candidates (manual)
|
|
95
|
+
|
|
96
|
+
To get a specific build in front of people before it becomes the default
|
|
97
|
+
install, cut a PEP 440 pre-release.
|
|
98
|
+
|
|
99
|
+
Tag and publish a GitHub release as usual, but with a pre-release version and
|
|
100
|
+
the release marked "pre-release":
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
v0.4.0a1 alpha
|
|
104
|
+
v0.4.0b1 beta
|
|
105
|
+
v0.4.0rc1 release candidate
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`publish-to-pypi.yml` handles these with no special casing: hatch-vcs reads the
|
|
109
|
+
version straight off the tag (`v0.4.0rc1` -> `0.4.0rc1`).
|
|
110
|
+
|
|
111
|
+
Opt in the same way:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
pip install --pre codeplain==0.4.0rc1
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Which API a build talks to
|
|
118
|
+
|
|
119
|
+
Pre-release builds default to the **test** API, so an unreleased client is
|
|
120
|
+
exercised against the unreleased backend:
|
|
121
|
+
|
|
122
|
+
| build | default API |
|
|
123
|
+
| --- | --- |
|
|
124
|
+
| stable release (`0.3.9`) | `https://api.codeplain.ai` |
|
|
125
|
+
| dev build (`0.3.10.dev7`) | `https://api.test.codeplain.ai` |
|
|
126
|
+
| alpha/beta/rc (`0.4.0rc1`) | `https://api.test.codeplain.ai` |
|
|
127
|
+
|
|
128
|
+
`--api` always overrides this. Resolution lives in
|
|
129
|
+
`system_config._resolve_default_api_url`, keyed off the version baked into the
|
|
130
|
+
package at build time — so nothing needs configuring at install time.
|
|
131
|
+
|
|
132
|
+
A source checkout reports the nearest git tag as its version, so it is treated
|
|
133
|
+
as stable and keeps pointing at production; use `--api` to aim it elsewhere.
|
|
134
|
+
|
|
135
|
+
Because every build above goes to real PyPI, dependency resolution and the
|
|
136
|
+
install path are exactly what an end user gets — the main reason this is
|
|
137
|
+
preferred over publishing to TestPyPI.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: codeplain
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.10.dev2
|
|
4
4
|
Summary: Transform plain language specifications into working code
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Classifier: Environment :: Console
|
|
@@ -8,15 +8,15 @@ Classifier: Intended Audience :: Developers
|
|
|
8
8
|
Classifier: Operating System :: OS Independent
|
|
9
9
|
Classifier: Topic :: Software Development :: Code Generators
|
|
10
10
|
Requires-Python: ==3.11.*
|
|
11
|
-
Requires-Dist: gitpython==3.1.
|
|
12
|
-
Requires-Dist: mistletoe==1.
|
|
11
|
+
Requires-Dist: gitpython==3.1.55
|
|
12
|
+
Requires-Dist: mistletoe==1.6.0
|
|
13
13
|
Requires-Dist: networkx==3.6.1
|
|
14
14
|
Requires-Dist: python-frontmatter==1.3.0
|
|
15
15
|
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.66.
|
|
19
|
+
Requires-Dist: sentry-sdk==2.66.1
|
|
20
20
|
Requires-Dist: textual>=7.5.0
|
|
21
21
|
Requires-Dist: tiktoken==0.13.0
|
|
22
22
|
Requires-Dist: transitions==0.9.3
|
|
@@ -52,6 +52,7 @@ macOS and Linux:
|
|
|
52
52
|
|
|
53
53
|
```bash
|
|
54
54
|
curl -fsSL https://codeplain.ai/install.sh | bash
|
|
55
|
+
# re-run to update to the latest version
|
|
55
56
|
```
|
|
56
57
|
|
|
57
58
|
Windows PowerShell:
|
|
@@ -74,12 +75,39 @@ export CODEPLAIN_API_KEY="your_actual_api_key_here"
|
|
|
74
75
|
|
|
75
76
|
You describe what you want in plain English, an agent helps you write a spec in \*\*\*plain language, and \*codeplain renders the actual code. This is what [plain-forge](https://github.com/Codeplain-ai/plain-forge) sets up: a toolkit of skills, rules, and docs that plugs into your AI coding agent of choice — Claude Code, Codex, ForgeCode, OpenCode, or any other agent that reads from a standard skills directory — and turns a conversation into a complete `.plain` spec, then keeps maintaining it across the lifetime of the project.
|
|
76
77
|
|
|
77
|
-
If you didn't install it during step 1, run it any time:
|
|
78
|
+
If you didn't install it during step 1, run it any time using your favorite Node package runner:
|
|
78
79
|
|
|
79
80
|
```bash
|
|
80
81
|
npx plain-forge install
|
|
81
82
|
```
|
|
82
83
|
|
|
84
|
+
The same command works with any other runner — pick whichever matches your toolchain:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
# npm (bundled with Node.js)
|
|
88
|
+
npx plain-forge install
|
|
89
|
+
|
|
90
|
+
# pnpm
|
|
91
|
+
pnpm dlx plain-forge install
|
|
92
|
+
|
|
93
|
+
# Bun
|
|
94
|
+
bunx plain-forge install
|
|
95
|
+
|
|
96
|
+
# Yarn (Berry, v2+)
|
|
97
|
+
yarn dlx plain-forge install
|
|
98
|
+
|
|
99
|
+
# Deno (npm: specifier, needs permissions to write the skills directory)
|
|
100
|
+
deno run -A npm:plain-forge install
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Every runner downloads `plain-forge` on demand and runs it without adding it to your project's dependencies. The package exposes a `plain-forge` binary, so no runner needs an extra `--package` flag.
|
|
104
|
+
|
|
105
|
+
`install` fails if plain-forge is already installed at the target — to refresh an existing installation to the latest skills, rules, and docs, use `update` instead (swap in your runner of choice):
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
npx plain-forge update
|
|
109
|
+
```
|
|
110
|
+
|
|
83
111
|
### 3. Convert specs into tested and validated code
|
|
84
112
|
|
|
85
113
|
\*codeplain extends coding agents with agentic skills for working at the specification layer, and with tools that convert specifications into tested and validated implementation code.
|
|
@@ -101,9 +129,9 @@ You can immediately test the system with a simple "Hello World" example:
|
|
|
101
129
|
|
|
102
130
|
_Note: Rendering will take a few minutes to complete._
|
|
103
131
|
|
|
104
|
-
- The system will generate a Python application in the `
|
|
132
|
+
- The system will generate a Python application in the `dist` directory. You can run it with:
|
|
105
133
|
```bash
|
|
106
|
-
cd
|
|
134
|
+
cd dist
|
|
107
135
|
python hello_world.py
|
|
108
136
|
```
|
|
109
137
|
|
|
@@ -22,6 +22,7 @@ macOS and Linux:
|
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
24
|
curl -fsSL https://codeplain.ai/install.sh | bash
|
|
25
|
+
# re-run to update to the latest version
|
|
25
26
|
```
|
|
26
27
|
|
|
27
28
|
Windows PowerShell:
|
|
@@ -44,12 +45,39 @@ export CODEPLAIN_API_KEY="your_actual_api_key_here"
|
|
|
44
45
|
|
|
45
46
|
You describe what you want in plain English, an agent helps you write a spec in \*\*\*plain language, and \*codeplain renders the actual code. This is what [plain-forge](https://github.com/Codeplain-ai/plain-forge) sets up: a toolkit of skills, rules, and docs that plugs into your AI coding agent of choice — Claude Code, Codex, ForgeCode, OpenCode, or any other agent that reads from a standard skills directory — and turns a conversation into a complete `.plain` spec, then keeps maintaining it across the lifetime of the project.
|
|
46
47
|
|
|
47
|
-
If you didn't install it during step 1, run it any time:
|
|
48
|
+
If you didn't install it during step 1, run it any time using your favorite Node package runner:
|
|
48
49
|
|
|
49
50
|
```bash
|
|
50
51
|
npx plain-forge install
|
|
51
52
|
```
|
|
52
53
|
|
|
54
|
+
The same command works with any other runner — pick whichever matches your toolchain:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# npm (bundled with Node.js)
|
|
58
|
+
npx plain-forge install
|
|
59
|
+
|
|
60
|
+
# pnpm
|
|
61
|
+
pnpm dlx plain-forge install
|
|
62
|
+
|
|
63
|
+
# Bun
|
|
64
|
+
bunx plain-forge install
|
|
65
|
+
|
|
66
|
+
# Yarn (Berry, v2+)
|
|
67
|
+
yarn dlx plain-forge install
|
|
68
|
+
|
|
69
|
+
# Deno (npm: specifier, needs permissions to write the skills directory)
|
|
70
|
+
deno run -A npm:plain-forge install
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Every runner downloads `plain-forge` on demand and runs it without adding it to your project's dependencies. The package exposes a `plain-forge` binary, so no runner needs an extra `--package` flag.
|
|
74
|
+
|
|
75
|
+
`install` fails if plain-forge is already installed at the target — to refresh an existing installation to the latest skills, rules, and docs, use `update` instead (swap in your runner of choice):
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
npx plain-forge update
|
|
79
|
+
```
|
|
80
|
+
|
|
53
81
|
### 3. Convert specs into tested and validated code
|
|
54
82
|
|
|
55
83
|
\*codeplain extends coding agents with agentic skills for working at the specification layer, and with tools that convert specifications into tested and validated implementation code.
|
|
@@ -71,9 +99,9 @@ You can immediately test the system with a simple "Hello World" example:
|
|
|
71
99
|
|
|
72
100
|
_Note: Rendering will take a few minutes to complete._
|
|
73
101
|
|
|
74
|
-
- The system will generate a Python application in the `
|
|
102
|
+
- The system will generate a Python application in the `dist` directory. You can run it with:
|
|
75
103
|
```bash
|
|
76
|
-
cd
|
|
104
|
+
cd dist
|
|
77
105
|
python hello_world.py
|
|
78
106
|
```
|
|
79
107
|
|
|
@@ -12,8 +12,14 @@ from plain2code_exceptions import PlainSyntaxError
|
|
|
12
12
|
DEFAULT_CONCEPTS = {
|
|
13
13
|
":ConformanceTests:",
|
|
14
14
|
":UnitTests:",
|
|
15
|
+
":AcceptanceTest:",
|
|
15
16
|
":AcceptanceTests:",
|
|
16
17
|
":Implementation:",
|
|
18
|
+
":plainDefinitions:",
|
|
19
|
+
":plainImplementationReqs:",
|
|
20
|
+
":plainFunctionality:",
|
|
21
|
+
":plainTestReqs:",
|
|
22
|
+
":plainImplementationCode:",
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
|
|
@@ -118,9 +118,9 @@ options:
|
|
|
118
118
|
If set, render the state machine graph.
|
|
119
119
|
--logging-config-path LOGGING_CONFIG_PATH
|
|
120
120
|
Path to the logging configuration file.
|
|
121
|
-
--headless Run in headless mode: no TUI
|
|
122
|
-
|
|
123
|
-
|
|
121
|
+
--headless Run in headless mode: no TUI. Progress is written to
|
|
122
|
+
the log file and streamed to stdout as it happens; the
|
|
123
|
+
specification text itself stays in the log file only.
|
|
124
124
|
--status Display account status including user information, API
|
|
125
125
|
key label, and rendering credits. Does not render any
|
|
126
126
|
code.
|