codeplain 0.3.8__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.8 → 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.8 → 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.8 → codeplain-0.3.10}/.github/workflows/publish-install-script.yml +18 -1
- codeplain-0.3.10/.github/workflows/publish-to-pypi.yml +159 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/CLAUDE.md +10 -6
- codeplain-0.3.10/CONTRIBUTING.md +137 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/PKG-INFO +36 -8
- {codeplain-0.3.8 → codeplain-0.3.10}/README.md +31 -3
- {codeplain-0.3.8 → codeplain-0.3.10}/codeplain_REST_api.py +6 -14
- {codeplain-0.3.8 → codeplain-0.3.10}/concept_utils.py +6 -0
- codeplain-0.3.10/conformance_fix_journal.py +207 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/docs/plain2code_cli.md +25 -23
- {codeplain-0.3.8 → codeplain-0.3.10}/docs/starting_a_plain_project_from_scratch.md +8 -2
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_golang/run.sh +2 -2
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_python/run.sh +2 -2
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_react/run.sh +1 -1
- {codeplain-0.3.8 → codeplain-0.3.10}/git_utils.py +0 -10
- {codeplain-0.3.8 → codeplain-0.3.10}/install/bash/install.sh +41 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/install/powershell/examples.ps1 +11 -5
- {codeplain-0.3.8 → 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.10/metadata_utils.py +46 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/module_renderer.py +9 -6
- {codeplain-0.3.8 → codeplain-0.3.10}/partial_rendering.py +35 -4
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code.py +52 -4
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_arguments.py +13 -19
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_cli.md +17 -19
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_console.py +3 -1
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_exceptions.py +8 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_logger.py +37 -15
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_telemetry.py +17 -11
- {codeplain-0.3.8 → codeplain-0.3.10}/plain_file.py +18 -1
- {codeplain-0.3.8 → codeplain-0.3.10}/plain_modules.py +264 -42
- {codeplain-0.3.8 → 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.8 → codeplain-0.3.10}/render_machine/actions/fix_conformance_test.py +58 -29
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/prepare_repositories.py +16 -10
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/run_conformance_tests.py +5 -11
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/conformance_tests.py +48 -9
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/implementation_code_helpers.py +5 -1
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/render_context.py +14 -4
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/render_types.py +0 -4
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/render_utils.py +1 -2
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/state_machine_config.py +10 -1
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/states.py +1 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/requirements.txt +3 -3
- codeplain-0.3.10/system_config.py +148 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/e2e/test_hello_world_python.py +1 -1
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/e2e/test_hello_world_python_windows.py +1 -1
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_arg_provenance.py +3 -3
- {codeplain-0.3.8 → 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.8 → codeplain-0.3.10}/tests/test_folder_path_resolution.py +12 -13
- codeplain-0.3.10/tests/test_headless_logging.py +177 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_plain2code.py +1 -2
- codeplain-0.3.10/tests/test_plain_modules.py +794 -0
- {codeplain-0.3.8 → 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.10/tests/test_system_config.py +95 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_telemetry.py +31 -10
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/plain_module_render_choice_tui.py +25 -8
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/state_handlers.py +7 -1
- codeplain-0.3.8/.github/dependabot.yml +0 -11
- codeplain-0.3.8/.github/workflows/e2e.yml +0 -62
- codeplain-0.3.8/.github/workflows/publish-to-pypi.yml +0 -70
- codeplain-0.3.8/install/powershell/walkthrough.ps1 +0 -161
- codeplain-0.3.8/memory_management.py +0 -133
- codeplain-0.3.8/system_config.py +0 -68
- codeplain-0.3.8/tests/test_plain_modules.py +0 -343
- {codeplain-0.3.8 → codeplain-0.3.10}/.claude/settings.json +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/.flake8 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/.gitignore +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/.vscode/launch.json +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/.vscode/settings.json +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/LICENSE +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/change_detection.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/cli_output/__init__.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/cli_output/status.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/config/__init__.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/config/system_config.yaml +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/diff_utils.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/docs/generate_cli.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/event_bus.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.8 → 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.8 → codeplain-0.3.10}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/examples/run.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/file_utils.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/install/bash/examples.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/path_resolution.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_events.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_nodes.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_read_config.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_state.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/plain2code_utils.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/plain_spec.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/pytest.ini +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/__init__.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/code_renderer.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/render_machine/triggers.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/resources/plain_example.png +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/__init__.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/conftest.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/simple.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_console_log_styles.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_imports.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_requires.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/__init__.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/components.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/models.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/spinner.py +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/styles.css +0 -0
- {codeplain-0.3.8 → codeplain-0.3.10}/tui/widget_helpers.py +0 -0
- {codeplain-0.3.8 → 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>.\"}"
|
|
@@ -14,8 +14,11 @@ jobs:
|
|
|
14
14
|
name: Upload to Cloudflare R2
|
|
15
15
|
runs-on: ubuntu-latest
|
|
16
16
|
|
|
17
|
+
env:
|
|
18
|
+
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
|
|
19
|
+
|
|
17
20
|
steps:
|
|
18
|
-
- uses: actions/checkout@
|
|
21
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
19
22
|
|
|
20
23
|
- name: Upload install scripts to R2
|
|
21
24
|
env:
|
|
@@ -54,3 +57,17 @@ jobs:
|
|
|
54
57
|
--content-type "text/plain"
|
|
55
58
|
echo "✓ examples.ps1 uploaded to R2"
|
|
56
59
|
|
|
60
|
+
- name: Notify Slack (success)
|
|
61
|
+
if: ${{ success() && env.SLACK_WEBHOOK_URL != '' }}
|
|
62
|
+
run: |
|
|
63
|
+
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
64
|
+
-H 'Content-type: application/json' \
|
|
65
|
+
--data "{\"text\":\"*Codeplain Client*: Install scripts deployed to R2 :white_check_mark: (\`${GITHUB_SHA:0:7}\`, by *${{ github.actor }}*).\"}"
|
|
66
|
+
|
|
67
|
+
- name: Notify Slack (failure)
|
|
68
|
+
if: ${{ failure() && env.SLACK_WEBHOOK_URL != '' }}
|
|
69
|
+
run: |
|
|
70
|
+
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
71
|
+
-H 'Content-type: application/json' \
|
|
72
|
+
--data "{\"text\":\"*Codeplain Client*: Install script deploy to R2 FAILED :x: (\`${GITHUB_SHA:0:7}\`). Users may be getting a stale installer. See <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|the run log>.\"}"
|
|
73
|
+
|