codeplain 0.3.9__tar.gz → 0.3.10__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/.github/dependabot.yml +28 -0
- codeplain-0.3.10/.github/workflows/e2e.yml +91 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/.github/workflows/lint-and-test.yml +19 -17
- codeplain-0.3.10/.github/workflows/lint-powershell.yml +124 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/.github/workflows/nofity-slack-on-main-merge.yml +3 -3
- codeplain-0.3.10/.github/workflows/publish-dev-to-pypi.yml +147 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/.github/workflows/publish-install-script.yml +1 -1
- {codeplain-0.3.9 → codeplain-0.3.10}/.github/workflows/publish-to-pypi.yml +60 -5
- {codeplain-0.3.9 → codeplain-0.3.10}/CLAUDE.md +4 -4
- codeplain-0.3.10/CONTRIBUTING.md +137 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/PKG-INFO +36 -8
- {codeplain-0.3.9 → codeplain-0.3.10}/README.md +31 -3
- {codeplain-0.3.9 → codeplain-0.3.10}/codeplain_REST_api.py +6 -14
- {codeplain-0.3.9 → codeplain-0.3.10}/concept_utils.py +6 -0
- codeplain-0.3.10/conformance_fix_journal.py +207 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/docs/plain2code_cli.md +3 -3
- {codeplain-0.3.9 → codeplain-0.3.10}/install/bash/install.sh +41 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/install/powershell/examples.ps1 +11 -5
- {codeplain-0.3.9 → codeplain-0.3.10}/install/powershell/install.ps1 +131 -19
- codeplain-0.3.10/install/powershell/walkthrough.ps1 +174 -0
- codeplain-0.3.10/memory_management.py +52 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/module_renderer.py +6 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/partial_rendering.py +35 -4
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code.py +46 -3
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_arguments.py +7 -4
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_console.py +3 -1
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_exceptions.py +8 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_logger.py +37 -15
- {codeplain-0.3.9 → codeplain-0.3.10}/plain_file.py +18 -1
- {codeplain-0.3.9 → codeplain-0.3.10}/plain_modules.py +197 -7
- {codeplain-0.3.9 → codeplain-0.3.10}/pyproject.toml +3 -3
- codeplain-0.3.10/render_machine/actions/distill_conformance_test_memory.py +56 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/fix_conformance_test.py +58 -29
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/prepare_repositories.py +13 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/run_conformance_tests.py +5 -11
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/conformance_tests.py +40 -3
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/implementation_code_helpers.py +5 -1
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/render_context.py +13 -1
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/render_types.py +0 -4
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/state_machine_config.py +10 -1
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/states.py +1 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/requirements.txt +3 -3
- {codeplain-0.3.9 → codeplain-0.3.10}/system_config.py +35 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_cli_output.py +13 -0
- codeplain-0.3.10/tests/test_conformance_fix_journal.py +259 -0
- codeplain-0.3.10/tests/test_distill_conformance_test_memory.py +145 -0
- codeplain-0.3.10/tests/test_dry_run_link_validation.py +60 -0
- codeplain-0.3.10/tests/test_headless_logging.py +177 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_plain_modules.py +267 -1
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_plainfileparser.py +41 -4
- codeplain-0.3.10/tests/test_prepare_repositories_layout.py +315 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_system_config.py +37 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/plain_module_render_choice_tui.py +25 -8
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/state_handlers.py +7 -1
- codeplain-0.3.9/.github/dependabot.yml +0 -11
- codeplain-0.3.9/.github/workflows/e2e.yml +0 -62
- codeplain-0.3.9/install/powershell/walkthrough.ps1 +0 -161
- codeplain-0.3.9/memory_management.py +0 -132
- codeplain-0.3.9/tests/test_prepare_repositories_layout.py +0 -119
- {codeplain-0.3.9 → codeplain-0.3.10}/.claude/settings.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/.flake8 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/.gitignore +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/.vscode/launch.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/.vscode/settings.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/LICENSE +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/change_detection.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/cli_output/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/cli_output/status.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/config/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/config/system_config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/diff_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/docs/generate_cli.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/event_bus.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/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}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/examples/run.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/file_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/git_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/install/bash/examples.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/metadata_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_cli.md +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_events.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_nodes.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_read_config.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_state.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_telemetry.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain2code_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/plain_spec.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/pytest.ini +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/code_renderer.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/render_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/render_machine/triggers.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/resources/plain_example.png +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/conftest.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/simple.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/e2e/test_hello_world_python.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/e2e/test_hello_world_python_windows.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_arg_provenance.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_console_log_styles.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_folder_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_imports.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_plain2code.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_requires.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_telemetry.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/__init__.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/components.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/models.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/spinner.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/styles.css +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/tui/widget_helpers.py +0 -0
- {codeplain-0.3.9 → codeplain-0.3.10}/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"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# .github/workflows/e2e.yml
|
|
2
|
+
name: E2E
|
|
3
|
+
|
|
4
|
+
on:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: '0 5 * * 1-5' # weekday nights to catch API drift
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
e2e-linux:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
timeout-minutes: 15
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
15
|
+
|
|
16
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
17
|
+
with:
|
|
18
|
+
python-version: '3.12'
|
|
19
|
+
|
|
20
|
+
- run: pip install pytest
|
|
21
|
+
|
|
22
|
+
- name: Set up Docker Buildx
|
|
23
|
+
uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # v3
|
|
24
|
+
|
|
25
|
+
- name: Build E2E image (cached)
|
|
26
|
+
uses: docker/build-push-action@ca052bb54ab0790a636c9b5f226502c73d547a25 # v5
|
|
27
|
+
with:
|
|
28
|
+
context: .
|
|
29
|
+
file: tests/e2e/Dockerfile
|
|
30
|
+
tags: codeplain-e2e:latest
|
|
31
|
+
load: true
|
|
32
|
+
cache-from: type=gha
|
|
33
|
+
cache-to: type=gha,mode=max
|
|
34
|
+
|
|
35
|
+
- name: Run E2E tests
|
|
36
|
+
env:
|
|
37
|
+
CODEPLAIN_API_KEY: ${{ secrets.CODEPLAIN_API_KEY }}
|
|
38
|
+
run: pytest tests/e2e/ -v --tb=short
|
|
39
|
+
|
|
40
|
+
- name: Upload generated outputs on failure
|
|
41
|
+
if: failure()
|
|
42
|
+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
43
|
+
with:
|
|
44
|
+
name: e2e-outputs-linux
|
|
45
|
+
path: /tmp/pytest-of-runner/**/container_work*/**
|
|
46
|
+
|
|
47
|
+
e2e-windows:
|
|
48
|
+
runs-on: windows-latest
|
|
49
|
+
timeout-minutes: 15
|
|
50
|
+
steps:
|
|
51
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
52
|
+
|
|
53
|
+
- uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
|
|
54
|
+
with:
|
|
55
|
+
python-version: '3.12'
|
|
56
|
+
|
|
57
|
+
- run: pip install pytest
|
|
58
|
+
|
|
59
|
+
- name: Run E2E tests
|
|
60
|
+
env:
|
|
61
|
+
CODEPLAIN_API_KEY: ${{ secrets.CODEPLAIN_API_KEY }}
|
|
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@dcb1066f776dd043e64d0e8ba94ca15cc7e1875d # v4.0.0
|
|
85
|
+
with:
|
|
86
|
+
webhook: ${{ env.SLACK_WEBHOOK_URL }}
|
|
87
|
+
webhook-type: incoming-webhook
|
|
88
|
+
payload: |
|
|
89
|
+
{
|
|
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)) }}
|
|
91
|
+
}
|
|
@@ -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
|
|
@@ -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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
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@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
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 }
|
|
@@ -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 }}
|
|
@@ -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>.\"}"
|
|
@@ -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,20 +81,33 @@ 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 != '' }}
|
|
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 != '' }}
|
|
@@ -102,3 +115,45 @@ jobs:
|
|
|
102
115
|
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
103
116
|
-H 'Content-type: application/json' \
|
|
104
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>.\"}"
|
|
@@ -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:**
|