codeplain 0.3.10.dev5__tar.gz → 0.3.11.dev7__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.dev5 → codeplain-0.3.11.dev7}/PKG-INFO +1 -1
- codeplain-0.3.11.dev7/install/bash/examples.sh +175 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/install/bash/install.sh +4 -2
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/install/powershell/examples.ps1 +65 -3
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/install/powershell/install.ps1 +9 -2
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_console.py +5 -4
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_console_log_styles.py +61 -5
- codeplain-0.3.10.dev5/install/bash/examples.sh +0 -97
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.claude/settings.json +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.flake8 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/dependabot.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/e2e.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/lint-and-test.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/lint-powershell.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/nofity-slack-on-main-merge.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/publish-dev-to-pypi.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/publish-install-script.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/publish-to-pypi.yml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.gitignore +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.vscode/launch.json +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.vscode/settings.json +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/CLAUDE.md +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/CONTRIBUTING.md +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/LICENSE +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/README.md +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/change_detection.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/cli_output/__init__.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/cli_output/dry_run.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/cli_output/render_summary.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/cli_output/status.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/codeplain_REST_api.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/concept_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/config/__init__.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/config/system_config.yaml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/conformance_fix_journal.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/diff_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/docs/generate_cli.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/docs/plain2code_cli.md +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/docs/starting_a_plain_project_from_scratch.md +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/event_bus.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_golang/config.yaml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_golang/harness_tests/hello_world_test.go +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_golang/hello_world_golang.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_golang/run.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_python/config.yaml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_python/harness_tests/hello_world_display/test_hello_world.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_python/hello_world_python.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_python/run.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/config.yaml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/e2e/hello_world.cy.ts +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress/support/e2e.ts +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/harness_tests/hello_world_display/cypress.config.ts +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/harness_tests/hello_world_display/package.json +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/harness_tests/hello_world_display/tsconfig.json +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/hello_world_react.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/run.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/run.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/file_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/git_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/install/bash/walkthrough.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/install/powershell/walkthrough.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/memory_management.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/metadata_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/module_renderer.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/partial_rendering.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/path_resolution.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_arguments.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_cli.md +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_events.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_exceptions.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_logger.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_nodes.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_read_config.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_state.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_telemetry.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain2code_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain_file.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain_modules.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/plain_spec.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/pyproject.toml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/pytest.ini +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/__init__.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/analyze_specification_ambiguity.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/base_action.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/commit_conformance_tests_changes.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/commit_implementation_code_changes.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/create_dist.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/exit_with_error.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/finish_functional_requirement.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/fix_conformance_test.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/fix_unit_tests.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/prepare_repositories.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/prepare_testing_environment.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/refactor_code.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/render_conformance_tests.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/render_functional_requirement.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/run_conformance_tests.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/run_unit_tests.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/actions/summarize_conformance_tests.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/code_renderer.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/conformance_tests.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/implementation_code_helpers.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/render_context.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/render_types.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/render_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/state_machine_config.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/states.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/render_machine/triggers.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/requirements.txt +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/resources/codeplain_overview.png +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/resources/plain_example.png +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/standard_template_library/golang-console-app-template.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/standard_template_library/python-console-app-template.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/standard_template_library/typescript-react-app-boilerplate.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/standard_template_library/typescript-react-app-template.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/system_config.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_conformance_tests_cypress.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_conformance_tests_cypress.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_conformance_tests_golang.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_conformance_tests_golang.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_conformance_tests_python.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_conformance_tests_python.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_flutter.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_flutter.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_golang.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_golang.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_python.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_python.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_react.ps1 +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/test_scripts/run_unittests_react.sh +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/__init__.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/conftest.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/acceptance_tests_warning/main_requiring_acceptance_tests.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/acceptance_tests_warning/required_with_acceptance_tests.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/circular_imports_1.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/circular_imports_2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/circular_imports_main.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/diamond_import_1.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/diamond_import_2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/diamond_import_common.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/diamond_imports_main.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/import_with_functionalities.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/imports_module_with_functionalities.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/imports/non_existent_import.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/partial_rendering/pr_code_var.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/partial_rendering/pr_implement.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/partial_rendering/pr_leaf.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/partial_rendering/pr_middle.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/partial_rendering/pr_root.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/partial_rendering/pr_solo.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/add_new_task_modal_specification.yaml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/duplicate_specification_heading.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/empty_functional_specs_section.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/invalid_specification_order.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/missing_non_functional_requirements.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/no_functional_specs_section.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/plain_source_with_absolute_link.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/plain_source_with_url_link.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/task_list_ui_specification.yaml +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/task_manager_with_reference_links.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfile/without_non_functional_requirement.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_acceptance_tests.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_acceptance_tests_nondefined.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_defined_nondefined.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_defined_nondefined_2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_definition.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_noconcepts.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_nonconcept.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_nondefined.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_redefinition.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_several_concepts.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/concept_validation_valid.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_base.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_example.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_missing.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_missing_example.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_nested.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_nested_example.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_transitive_example.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_transitive_l1.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/exported_concepts_transitive_l2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/plain_file_parser_with_comments.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/plain_file_with_comments_indented.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/regular_plain_source.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_defs.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_example.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_l1.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_l2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_missing.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_module.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_partial.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/required_concepts_partial_duplicate.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/topological_sort.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/plainfileparser/topological_sort_not_referenced.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/circular_requires_main.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/circular_requires_sub.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/diamond_requires_1.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/diamond_requires_2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/diamond_requires_common.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/diamond_requires_main.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/independent_requires_1.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/independent_requires_2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/independent_requires_main.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/non_existent_require.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/normal_requires_1.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/normal_requires_2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/normal_requires_common.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/requires/normal_requires_main.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/sample_base64_image.txt +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/simple.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/templates/block_level_include.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/templates/code_variables.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/templates/header.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/templates/implement.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/templates/implement_2.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/templates/template_include.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/data/templates/test_hardest_problem.plain +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/e2e/Dockerfile +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/e2e/conftest.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/e2e/test_hello_world_python.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/e2e/test_hello_world_python_windows.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_arg_provenance.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_change_detection.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_cli_output.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_conformance_fix_journal.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_distill_conformance_test_memory.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_dry_run_link_validation.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_file_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_folder_path_resolution.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_git_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_headless_logging.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_imports.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_log_file_name_resolution.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_logging_config_path_resolution.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_partial_rendering.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_path_resolution.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_plain2code.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_plain2code_state.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_plain2code_utils.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_plain_modules.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_plainfile.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_plainfileparser.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_plainspec.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_prepare_repositories_layout.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_requires.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_resolve_config_file.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_script_path_resolution.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_system_config.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_telemetry.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_tui_usage.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tests/test_usage_summary.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/__init__.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/components.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/models.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/plain2code_tui.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/plain_module_render_choice_tui.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/spinner.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/state_handlers.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/styles.css +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/tui/widget_helpers.py +0 -0
- {codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/usage_summary.py +0 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -euo pipefail
|
|
4
|
+
|
|
5
|
+
# Brand Colors (use exported colors if available, otherwise define them)
|
|
6
|
+
YELLOW="${YELLOW:-\033[38;2;224;255;110m}"
|
|
7
|
+
GREEN="${GREEN:-\033[38;2;121;252;150m}"
|
|
8
|
+
WHITE="${WHITE:-\033[38;2;255;255;255m}"
|
|
9
|
+
RED="${RED:-\033[38;2;239;68;68m}"
|
|
10
|
+
GRAY="${GRAY:-\033[38;2;128;128;128m}"
|
|
11
|
+
BOLD="${BOLD:-\033[1m}"
|
|
12
|
+
NC="${NC:-\033[0m}"
|
|
13
|
+
|
|
14
|
+
# Examples configuration
|
|
15
|
+
EXAMPLES_FOLDER_NAME="plainlang-examples"
|
|
16
|
+
EXAMPLES_DOWNLOAD_URL="https://codeplain.ai/examples/unix"
|
|
17
|
+
|
|
18
|
+
# Prompt the user, reading from the terminal when there is one. Falling back to
|
|
19
|
+
# stdin keeps the script usable in non-interactive environments instead of
|
|
20
|
+
# dying on an unreadable /dev/tty.
|
|
21
|
+
prompt_user() {
|
|
22
|
+
local prompt="$1"
|
|
23
|
+
local varname="$2"
|
|
24
|
+
|
|
25
|
+
# Test that /dev/tty can actually be opened: it exists but fails to open
|
|
26
|
+
# when the process has no controlling terminal.
|
|
27
|
+
if { : < /dev/tty; } 2>/dev/null; then
|
|
28
|
+
read -r -p "$prompt" "$varname" < /dev/tty || true
|
|
29
|
+
else
|
|
30
|
+
read -r -p "$prompt" "$varname" || true
|
|
31
|
+
fi
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Make the user acknowledge that the examples were not installed. The
|
|
35
|
+
# installation continues either way, but the failure must not scroll past
|
|
36
|
+
# unseen - the installer clears the screen in its next step.
|
|
37
|
+
confirm_continue_after_failure() {
|
|
38
|
+
echo ""
|
|
39
|
+
echo -e " ${YELLOW}The examples were not installed.${NC} ${GRAY}The installation will continue.${NC}"
|
|
40
|
+
echo ""
|
|
41
|
+
prompt_user "$(printf '%b' " Continue? Press ${WHITE}[Enter]${NC} to acknowledge: ")" _ACKNOWLEDGED
|
|
42
|
+
echo ""
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Tell the user how to get unzip on their system, then let the installer move on.
|
|
46
|
+
report_missing_unzip_tool() {
|
|
47
|
+
echo -e " ${RED}✗ Cannot extract the examples: no 'unzip' command found.${NC}"
|
|
48
|
+
echo ""
|
|
49
|
+
echo -e " ${GRAY}Install unzip and re-run the installer to get the examples:${NC}"
|
|
50
|
+
echo ""
|
|
51
|
+
case "$OSTYPE" in
|
|
52
|
+
darwin*)
|
|
53
|
+
echo -e " ${WHITE}${BOLD}brew install unzip${NC}"
|
|
54
|
+
;;
|
|
55
|
+
*)
|
|
56
|
+
echo -e " ${WHITE}${BOLD}apt-get install unzip${NC} ${GRAY}(Debian/Ubuntu)${NC}"
|
|
57
|
+
echo -e " ${WHITE}${BOLD}dnf install unzip${NC} ${GRAY}(Fedora/RHEL)${NC}"
|
|
58
|
+
echo -e " ${WHITE}${BOLD}apk add unzip${NC} ${GRAY}(Alpine)${NC}"
|
|
59
|
+
;;
|
|
60
|
+
esac
|
|
61
|
+
echo ""
|
|
62
|
+
echo -e " ${GRAY}The examples are also available at:${NC}"
|
|
63
|
+
echo -e " ${WHITE}https://github.com/Codeplain-ai/plainlang-examples${NC}"
|
|
64
|
+
echo ""
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
# Checked before anything is downloaded, so a missing unzip is reported up
|
|
68
|
+
# front instead of leaving the user with an installer that just stops.
|
|
69
|
+
if ! command -v unzip &> /dev/null; then
|
|
70
|
+
report_missing_unzip_tool
|
|
71
|
+
confirm_continue_after_failure
|
|
72
|
+
exit 0
|
|
73
|
+
fi
|
|
74
|
+
|
|
75
|
+
# Show current directory and ask for extraction path
|
|
76
|
+
CURRENT_DIR=$(pwd)
|
|
77
|
+
echo -e " Current folder: ${WHITE}${CURRENT_DIR}${NC}"
|
|
78
|
+
echo ""
|
|
79
|
+
echo -e " Extract examples here, or enter a different path:"
|
|
80
|
+
echo ""
|
|
81
|
+
prompt_user " [Enter for current, or type path]: " EXTRACT_PATH
|
|
82
|
+
echo ""
|
|
83
|
+
|
|
84
|
+
# Use current directory if empty
|
|
85
|
+
if [ -z "${EXTRACT_PATH:-}" ]; then
|
|
86
|
+
EXTRACT_PATH="$CURRENT_DIR"
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
# Expand ~ to home directory
|
|
90
|
+
EXTRACT_PATH="${EXTRACT_PATH/#\~/$HOME}"
|
|
91
|
+
|
|
92
|
+
SKIP_DOWNLOAD=false
|
|
93
|
+
|
|
94
|
+
# Check if directory exists, create if not
|
|
95
|
+
if [ ! -d "$EXTRACT_PATH" ]; then
|
|
96
|
+
echo -e " ${GRAY}Creating directory...${NC}"
|
|
97
|
+
if ! mkdir -p "$EXTRACT_PATH" 2>/dev/null; then
|
|
98
|
+
echo -e " ${RED}✗ Failed to create directory: ${EXTRACT_PATH}${NC}"
|
|
99
|
+
confirm_continue_after_failure
|
|
100
|
+
SKIP_DOWNLOAD=true
|
|
101
|
+
fi
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
EXAMPLES_INSTALLED=false
|
|
105
|
+
|
|
106
|
+
if [ "$SKIP_DOWNLOAD" = false ]; then
|
|
107
|
+
echo -e " ${GRAY}Downloading examples...${NC}"
|
|
108
|
+
|
|
109
|
+
# Download the zip file
|
|
110
|
+
TEMP_ZIP=$(mktemp)
|
|
111
|
+
DOWNLOAD_OK=false
|
|
112
|
+
DOWNLOAD_ERROR="Could not download ${EXAMPLES_DOWNLOAD_URL}"
|
|
113
|
+
if curl -L -s -o "$TEMP_ZIP" "$EXAMPLES_DOWNLOAD_URL" && [ -s "$TEMP_ZIP" ]; then
|
|
114
|
+
DOWNLOAD_OK=true
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# A server error page is a successful download of the wrong thing, so check
|
|
118
|
+
# for the zip magic bytes rather than handing unzip an HTML page.
|
|
119
|
+
if [ "$DOWNLOAD_OK" = true ] && [ "$(head -c 2 "$TEMP_ZIP")" != "PK" ]; then
|
|
120
|
+
DOWNLOAD_OK=false
|
|
121
|
+
DOWNLOAD_ERROR="The downloaded file is not a zip archive."
|
|
122
|
+
fi
|
|
123
|
+
|
|
124
|
+
if [ "$DOWNLOAD_OK" = true ]; then
|
|
125
|
+
echo -e " ${GRAY}Extracting to ${EXTRACT_PATH}...${NC}"
|
|
126
|
+
|
|
127
|
+
# Extract the zip file (contents are at the zip root, so extract into the target folder)
|
|
128
|
+
EXTRACTED_DIR="${EXTRACT_PATH}/${EXAMPLES_FOLDER_NAME}"
|
|
129
|
+
rm -rf "$EXTRACTED_DIR" 2>/dev/null || true # Remove existing if present
|
|
130
|
+
|
|
131
|
+
# Keep the extractor's own error output: it is the only clue about why
|
|
132
|
+
# extraction failed (corrupt download, no disk space, no permissions).
|
|
133
|
+
if EXTRACT_OUTPUT=$(unzip -q -o "$TEMP_ZIP" -d "$EXTRACTED_DIR" 2>&1); then
|
|
134
|
+
# Remove the .gitignore file from the root of the extracted directory
|
|
135
|
+
if [ -f "${EXTRACTED_DIR}/.gitignore" ]; then
|
|
136
|
+
rm -f "${EXTRACTED_DIR}/.gitignore"
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
clear || true
|
|
140
|
+
echo ""
|
|
141
|
+
echo -e " ${GREEN}✓ Examples downloaded successfully!${NC}"
|
|
142
|
+
echo ""
|
|
143
|
+
echo -e " ${GRAY}Examples are in: ${EXTRACTED_DIR}${NC}"
|
|
144
|
+
echo ""
|
|
145
|
+
echo -e " ${WHITE}${BOLD}Try the hello, world example:${NC}"
|
|
146
|
+
echo ""
|
|
147
|
+
echo -e " ${GRAY}Example folder:${NC} ${WHITE}cd ${EXTRACTED_DIR}/hello-world/python${NC}"
|
|
148
|
+
echo ""
|
|
149
|
+
echo -e " ${GRAY}Render the example:${NC} ${WHITE}codeplain hello-world-python.plain${NC}"
|
|
150
|
+
echo ""
|
|
151
|
+
echo -e " ${GRAY}See hello-world/python/README.md for details.${NC}"
|
|
152
|
+
echo ""
|
|
153
|
+
EXAMPLES_INSTALLED=true
|
|
154
|
+
else
|
|
155
|
+
echo -e " ${RED}✗ Failed to extract examples.${NC}"
|
|
156
|
+
if [ -n "$EXTRACT_OUTPUT" ]; then
|
|
157
|
+
echo -e " ${GRAY}$(echo "$EXTRACT_OUTPUT" | tail -n 3)${NC}"
|
|
158
|
+
fi
|
|
159
|
+
fi
|
|
160
|
+
|
|
161
|
+
# Clean up temp file
|
|
162
|
+
rm -f "$TEMP_ZIP"
|
|
163
|
+
else
|
|
164
|
+
echo -e " ${RED}✗ Failed to download examples.${NC}"
|
|
165
|
+
echo -e " ${GRAY}${DOWNLOAD_ERROR}${NC}"
|
|
166
|
+
rm -f "$TEMP_ZIP"
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
if [ "$EXAMPLES_INSTALLED" = true ]; then
|
|
170
|
+
echo ""
|
|
171
|
+
prompt_user "$(printf '%b' " Press ${WHITE}[Enter]${NC} to continue...")" _CONTINUE
|
|
172
|
+
else
|
|
173
|
+
confirm_continue_after_failure
|
|
174
|
+
fi
|
|
175
|
+
fi
|
|
@@ -425,9 +425,11 @@ else
|
|
|
425
425
|
echo ""
|
|
426
426
|
fi
|
|
427
427
|
|
|
428
|
-
# Run examples download if user agrees
|
|
428
|
+
# Run examples download if user agrees. The examples are a nice-to-have, so a
|
|
429
|
+
# failure there must never abort the installation (set -e would otherwise take
|
|
430
|
+
# the whole installer down without printing anything).
|
|
429
431
|
if [[ ! "${DOWNLOAD_EXAMPLES:-}" =~ ^[Nn]$ ]]; then
|
|
430
|
-
run_script "examples.sh"
|
|
432
|
+
run_script "examples.sh" || echo -e "${GRAY}Example download did not complete. Continuing with the installation.${NC}"
|
|
431
433
|
fi
|
|
432
434
|
|
|
433
435
|
# Final verification: make sure the installed codeplain can actually run and
|
|
@@ -19,6 +19,39 @@ $CROSS = [char]0x2717
|
|
|
19
19
|
$EXAMPLES_FOLDER_NAME = "plainlang-examples"
|
|
20
20
|
$EXAMPLES_DOWNLOAD_URL = "https://codeplain.ai/examples/windows"
|
|
21
21
|
|
|
22
|
+
# Make the user acknowledge that the examples were not installed. The
|
|
23
|
+
# installation continues either way, but the failure must not scroll past
|
|
24
|
+
# unseen - the installer clears the screen in its next step.
|
|
25
|
+
function Confirm-ContinueAfterFailure {
|
|
26
|
+
Write-Host ""
|
|
27
|
+
Write-Host " ${YELLOW}The examples were not installed.${NC} ${GRAY}The installation will continue.${NC}"
|
|
28
|
+
Write-Host ""
|
|
29
|
+
Read-Host " Continue? Press ${WHITE}[Enter]${NC} to acknowledge"
|
|
30
|
+
Write-Host ""
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
# Expand-Archive lives in the Microsoft.PowerShell.Archive module, shipped with
|
|
34
|
+
# PowerShell 5.0 and later. Checked before anything is downloaded, so a machine
|
|
35
|
+
# without it is told what to do instead of just seeing an extraction failure.
|
|
36
|
+
function Show-MissingArchiveCmdletMessage {
|
|
37
|
+
Write-Host " ${RED}${CROSS} Cannot extract the examples: Expand-Archive is not available.${NC}"
|
|
38
|
+
Write-Host ""
|
|
39
|
+
Write-Host " ${GRAY}Expand-Archive requires PowerShell 5.0 or later. Install a newer${NC}"
|
|
40
|
+
Write-Host " ${GRAY}PowerShell and re-run the installer to get the examples:${NC}"
|
|
41
|
+
Write-Host ""
|
|
42
|
+
Write-Host " ${WHITE}${BOLD}https://aka.ms/powershell${NC}"
|
|
43
|
+
Write-Host ""
|
|
44
|
+
Write-Host " ${GRAY}The examples are also available at:${NC}"
|
|
45
|
+
Write-Host " ${WHITE}https://github.com/Codeplain-ai/plainlang-examples${NC}"
|
|
46
|
+
Write-Host ""
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (-not (Get-Command Expand-Archive -ErrorAction SilentlyContinue)) {
|
|
50
|
+
Show-MissingArchiveCmdletMessage
|
|
51
|
+
Confirm-ContinueAfterFailure
|
|
52
|
+
exit 0
|
|
53
|
+
}
|
|
54
|
+
|
|
22
55
|
# Show current directory and ask for extraction path
|
|
23
56
|
$CURRENT_DIR = Get-Location
|
|
24
57
|
Write-Host " Current folder: ${WHITE}${CURRENT_DIR}${NC}"
|
|
@@ -47,11 +80,13 @@ if (-not (Test-Path $EXTRACT_PATH -PathType Container)) {
|
|
|
47
80
|
New-Item -ItemType Directory -Path $EXTRACT_PATH -Force | Out-Null
|
|
48
81
|
} catch {
|
|
49
82
|
Write-Host " ${RED}${CROSS} Failed to create directory: ${EXTRACT_PATH}${NC}"
|
|
50
|
-
|
|
83
|
+
Confirm-ContinueAfterFailure
|
|
51
84
|
$SKIP_DOWNLOAD = $true
|
|
52
85
|
}
|
|
53
86
|
}
|
|
54
87
|
|
|
88
|
+
$EXAMPLES_INSTALLED = $false
|
|
89
|
+
|
|
55
90
|
if (-not $SKIP_DOWNLOAD) {
|
|
56
91
|
Write-Host " ${GRAY}Downloading examples...${NC}"
|
|
57
92
|
|
|
@@ -60,7 +95,26 @@ if (-not $SKIP_DOWNLOAD) {
|
|
|
60
95
|
try {
|
|
61
96
|
Invoke-WebRequest -Uri $EXAMPLES_DOWNLOAD_URL -OutFile $TEMP_ZIP -UseBasicParsing
|
|
62
97
|
|
|
98
|
+
# Check for the zip magic bytes rather than handing Expand-Archive a
|
|
99
|
+
# server error page. Read via a stream: 'Get-Content -Encoding Byte' is
|
|
100
|
+
# Windows PowerShell 5.1 only, '-AsByteStream' is PowerShell 6+ only.
|
|
101
|
+
$IS_ZIP = $false
|
|
63
102
|
if (Test-Path $TEMP_ZIP) {
|
|
103
|
+
$HEADER = New-Object byte[] 2
|
|
104
|
+
$STREAM = [System.IO.File]::OpenRead($TEMP_ZIP)
|
|
105
|
+
try {
|
|
106
|
+
$BYTES_READ = $STREAM.Read($HEADER, 0, 2)
|
|
107
|
+
} finally {
|
|
108
|
+
$STREAM.Close()
|
|
109
|
+
}
|
|
110
|
+
$IS_ZIP = ($BYTES_READ -eq 2 -and $HEADER[0] -eq 0x50 -and $HEADER[1] -eq 0x4B)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (-not $IS_ZIP -and (Test-Path $TEMP_ZIP)) {
|
|
114
|
+
Write-Host " ${RED}${CROSS} Failed to download examples.${NC}"
|
|
115
|
+
Write-Host " ${GRAY}The downloaded file is not a zip archive.${NC}"
|
|
116
|
+
Remove-Item -Path $TEMP_ZIP -Force -ErrorAction SilentlyContinue
|
|
117
|
+
} elseif ($IS_ZIP) {
|
|
64
118
|
Write-Host " ${GRAY}Extracting to ${EXTRACT_PATH}...${NC}"
|
|
65
119
|
|
|
66
120
|
try {
|
|
@@ -91,8 +145,12 @@ if (-not $SKIP_DOWNLOAD) {
|
|
|
91
145
|
Write-Host ""
|
|
92
146
|
Write-Host " ${GRAY}See hello-world/python/README.md for details.${NC}"
|
|
93
147
|
Write-Host ""
|
|
148
|
+
$EXAMPLES_INSTALLED = $true
|
|
94
149
|
} catch {
|
|
150
|
+
# Keep the cmdlet's own message: it is the only clue about why
|
|
151
|
+
# extraction failed (corrupt download, no space, no permissions).
|
|
95
152
|
Write-Host " ${RED}${CROSS} Failed to extract examples.${NC}"
|
|
153
|
+
Write-Host " ${GRAY}$($_.Exception.Message)${NC}"
|
|
96
154
|
}
|
|
97
155
|
|
|
98
156
|
Remove-Item -Path $TEMP_ZIP -Force -ErrorAction SilentlyContinue
|
|
@@ -104,6 +162,10 @@ if (-not $SKIP_DOWNLOAD) {
|
|
|
104
162
|
Remove-Item -Path $TEMP_ZIP -Force -ErrorAction SilentlyContinue
|
|
105
163
|
}
|
|
106
164
|
|
|
107
|
-
|
|
108
|
-
|
|
165
|
+
if ($EXAMPLES_INSTALLED) {
|
|
166
|
+
Write-Host ""
|
|
167
|
+
Read-Host " Press ${WHITE}[Enter]${NC} to continue..."
|
|
168
|
+
} else {
|
|
169
|
+
Confirm-ContinueAfterFailure
|
|
170
|
+
}
|
|
109
171
|
}
|
|
@@ -526,9 +526,16 @@ if ($nonInteractive) {
|
|
|
526
526
|
Write-Host ""
|
|
527
527
|
}
|
|
528
528
|
|
|
529
|
-
# Run examples download if user agrees
|
|
529
|
+
# Run examples download if user agrees. The examples are a nice-to-have, so a
|
|
530
|
+
# failure there must never abort the installation: examples.ps1 runs in this
|
|
531
|
+
# runspace via the call operator, so a terminating error inside it would
|
|
532
|
+
# otherwise propagate here and take the whole installer down.
|
|
530
533
|
if ($downloadExamples -notmatch '^[Nn]$') {
|
|
531
|
-
|
|
534
|
+
try {
|
|
535
|
+
Invoke-SubScript "examples.ps1"
|
|
536
|
+
} catch {
|
|
537
|
+
Write-Host "${GRAY}Example download did not complete. Continuing with the installation.${NC}"
|
|
538
|
+
}
|
|
532
539
|
}
|
|
533
540
|
|
|
534
541
|
# Final verification: make sure the installed codeplain can actually run and
|
|
@@ -27,7 +27,7 @@ class Plain2CodeConsole(Console):
|
|
|
27
27
|
DEBUG_STYLE = Style(color="purple")
|
|
28
28
|
|
|
29
29
|
def __init__(self):
|
|
30
|
-
super().__init__()
|
|
30
|
+
super().__init__(emoji=False)
|
|
31
31
|
try:
|
|
32
32
|
import tiktoken
|
|
33
33
|
|
|
@@ -66,9 +66,10 @@ class Plain2CodeConsole(Console):
|
|
|
66
66
|
"""
|
|
67
67
|
logger.log(level, " ".join(map(str, args)), extra={"log_color": color})
|
|
68
68
|
style = base_style + Style(color=color) if color else base_style
|
|
69
|
-
#
|
|
70
|
-
# in interpolated content (error texts, file names)
|
|
71
|
-
#
|
|
69
|
+
# Messages must render exactly as logged and not pick its own styling:
|
|
70
|
+
# -- no Rich markup (via square brackets) in interpolated content (error texts, file names)
|
|
71
|
+
# -- no repr highlighter restyling brackets and numbers inside them.
|
|
72
|
+
# -- no emoji substitution, but it's set False in __init__, otherwise it won't reach renderables like Trees
|
|
72
73
|
kwargs.setdefault("markup", False)
|
|
73
74
|
kwargs.setdefault("highlight", False)
|
|
74
75
|
super().print(*args, **kwargs, style=style)
|
|
@@ -70,14 +70,70 @@ class TestConsoleColorParam:
|
|
|
70
70
|
|
|
71
71
|
assert handler.records[0].log_color is None
|
|
72
72
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
73
|
+
|
|
74
|
+
class TestTerminalTextRendersVerbatim:
|
|
75
|
+
"""
|
|
76
|
+
Message text must reach the terminal unchanged, and must not influence its own
|
|
77
|
+
styling. Colors are still applied but they are chosen by the call, never parsed
|
|
78
|
+
out of the text:
|
|
79
|
+
- Rich markup tags must not be interpreted
|
|
80
|
+
- the repr highlighter must not restyle brackets and numbers
|
|
81
|
+
- emoji shortcodes must not be substituted by glyphs
|
|
82
|
+
"""
|
|
83
|
+
|
|
84
|
+
def test_markup_closing_tag_prints_verbatim(self):
|
|
85
|
+
console = Plain2CodeConsole()
|
|
76
86
|
with console.capture() as capture:
|
|
77
|
-
console.
|
|
78
|
-
|
|
87
|
+
console.error("Error: [/closing] tag")
|
|
88
|
+
# markup=True raises MarkupError on an unmatched closing tag
|
|
79
89
|
assert "[/closing]" in capture.get()
|
|
80
90
|
|
|
91
|
+
def test_markup_style_tag_prints_verbatim(self):
|
|
92
|
+
console = Plain2CodeConsole()
|
|
93
|
+
with console.capture() as capture:
|
|
94
|
+
console.error("Error: [bold]important text")
|
|
95
|
+
# markup=True silently consumes the tag and styles the rest
|
|
96
|
+
assert "[bold]" in capture.get()
|
|
97
|
+
|
|
98
|
+
def test_bracketed_number_prints_verbatim(self, monkeypatch):
|
|
99
|
+
# Rich emits no ANSI unless it believes it is writing to a colored terminal
|
|
100
|
+
# (FORCE_COLOR alone is not enough: TERM=dumb still resolves to no colors)
|
|
101
|
+
monkeypatch.setenv("FORCE_COLOR", "1")
|
|
102
|
+
monkeypatch.setenv("TERM", "xterm-256color")
|
|
103
|
+
console = Plain2CodeConsole()
|
|
104
|
+
assert console.color_system is not None # should fail test immediately if no colors
|
|
105
|
+
|
|
106
|
+
with console.capture() as capture:
|
|
107
|
+
console.error("Error: [Errno 8] failed")
|
|
108
|
+
# highlight=True breaks this up with colour codes
|
|
109
|
+
assert "[Errno 8]" in capture.get()
|
|
110
|
+
|
|
111
|
+
def test_concept_name_matching_emoji_prints_verbatim(self):
|
|
112
|
+
console = Plain2CodeConsole()
|
|
113
|
+
with console.capture() as capture:
|
|
114
|
+
console.error("Syntax error: Invalid concept: :Package:")
|
|
115
|
+
assert ":Package:" in capture.get()
|
|
116
|
+
assert "📦" not in capture.get()
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
class TestPrintHelpersDoNotSubstituteEmoji:
|
|
120
|
+
"""
|
|
121
|
+
Same rule as TestTerminalTextRendersVerbatim, for the two helpers that bypass _log_and_print.
|
|
122
|
+
Only emoji is covered here, markup and highlighting still apply to them.
|
|
123
|
+
"""
|
|
124
|
+
|
|
125
|
+
def test_print_list_does_not_substitute_emoji(self):
|
|
126
|
+
console = Plain2CodeConsole()
|
|
127
|
+
with console.capture() as capture:
|
|
128
|
+
console.print_list(["The :Package: is a concept"])
|
|
129
|
+
assert ":Package:" in capture.get()
|
|
130
|
+
|
|
131
|
+
def test_print_files_does_not_substitute_emoji_in_tree_labels(self):
|
|
132
|
+
console = Plain2CodeConsole()
|
|
133
|
+
with console.capture() as capture:
|
|
134
|
+
console.print_files("Files added:", "build", {":Package:.py": "x"})
|
|
135
|
+
assert ":Package:" in capture.get()
|
|
136
|
+
|
|
81
137
|
|
|
82
138
|
class TestLoggingHandlerForwardsColor:
|
|
83
139
|
"""LoggingHandler must forward the log_color record attribute into LogMessageEmitted."""
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
set -euo pipefail
|
|
4
|
-
|
|
5
|
-
# Brand Colors (use exported colors if available, otherwise define them)
|
|
6
|
-
YELLOW="${YELLOW:-\033[38;2;224;255;110m}"
|
|
7
|
-
GREEN="${GREEN:-\033[38;2;121;252;150m}"
|
|
8
|
-
WHITE="${WHITE:-\033[38;2;255;255;255m}"
|
|
9
|
-
RED="${RED:-\033[38;2;239;68;68m}"
|
|
10
|
-
GRAY="${GRAY:-\033[38;2;128;128;128m}"
|
|
11
|
-
BOLD="${BOLD:-\033[1m}"
|
|
12
|
-
NC="${NC:-\033[0m}"
|
|
13
|
-
|
|
14
|
-
# Examples configuration
|
|
15
|
-
EXAMPLES_FOLDER_NAME="plainlang-examples"
|
|
16
|
-
EXAMPLES_DOWNLOAD_URL="https://codeplain.ai/examples/unix"
|
|
17
|
-
|
|
18
|
-
# Show current directory and ask for extraction path
|
|
19
|
-
CURRENT_DIR=$(pwd)
|
|
20
|
-
echo -e " Current folder: ${WHITE}${CURRENT_DIR}${NC}"
|
|
21
|
-
echo ""
|
|
22
|
-
echo -e " Extract examples here, or enter a different path:"
|
|
23
|
-
echo ""
|
|
24
|
-
read -r -p " [Enter for current, or type path]: " EXTRACT_PATH < /dev/tty
|
|
25
|
-
echo ""
|
|
26
|
-
|
|
27
|
-
# Use current directory if empty
|
|
28
|
-
if [ -z "${EXTRACT_PATH:-}" ]; then
|
|
29
|
-
EXTRACT_PATH="$CURRENT_DIR"
|
|
30
|
-
fi
|
|
31
|
-
|
|
32
|
-
# Expand ~ to home directory
|
|
33
|
-
EXTRACT_PATH="${EXTRACT_PATH/#\~/$HOME}"
|
|
34
|
-
|
|
35
|
-
SKIP_DOWNLOAD=false
|
|
36
|
-
|
|
37
|
-
# Check if directory exists, create if not
|
|
38
|
-
if [ ! -d "$EXTRACT_PATH" ]; then
|
|
39
|
-
echo -e " ${GRAY}Creating directory...${NC}"
|
|
40
|
-
mkdir -p "$EXTRACT_PATH" 2>/dev/null
|
|
41
|
-
if [ $? -ne 0 ]; then
|
|
42
|
-
echo -e " ${RED}✗ Failed to create directory: ${EXTRACT_PATH}${NC}"
|
|
43
|
-
echo -e " ${GRAY}Skipping example download.${NC}"
|
|
44
|
-
SKIP_DOWNLOAD=true
|
|
45
|
-
fi
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
if [ "$SKIP_DOWNLOAD" = false ]; then
|
|
49
|
-
echo -e " ${GRAY}Downloading examples...${NC}"
|
|
50
|
-
|
|
51
|
-
# Download the zip file
|
|
52
|
-
TEMP_ZIP=$(mktemp)
|
|
53
|
-
curl -L -s -o "$TEMP_ZIP" "$EXAMPLES_DOWNLOAD_URL"
|
|
54
|
-
|
|
55
|
-
if [ $? -eq 0 ] && [ -s "$TEMP_ZIP" ]; then
|
|
56
|
-
echo -e " ${GRAY}Extracting to ${EXTRACT_PATH}...${NC}"
|
|
57
|
-
|
|
58
|
-
# Extract the zip file (contents are at the zip root, so extract into the target folder)
|
|
59
|
-
EXTRACTED_DIR="${EXTRACT_PATH}/${EXAMPLES_FOLDER_NAME}"
|
|
60
|
-
rm -rf "$EXTRACTED_DIR" 2>/dev/null # Remove existing if present
|
|
61
|
-
unzip -q -o "$TEMP_ZIP" -d "$EXTRACTED_DIR" 2>/dev/null
|
|
62
|
-
|
|
63
|
-
if [ $? -eq 0 ]; then
|
|
64
|
-
# Remove the .gitignore file from the root of the extracted directory
|
|
65
|
-
if [ -f "${EXTRACTED_DIR}/.gitignore" ]; then
|
|
66
|
-
rm -f "${EXTRACTED_DIR}/.gitignore"
|
|
67
|
-
fi
|
|
68
|
-
|
|
69
|
-
clear
|
|
70
|
-
echo ""
|
|
71
|
-
echo -e " ${GREEN}✓ Examples downloaded successfully!${NC}"
|
|
72
|
-
echo ""
|
|
73
|
-
echo -e " ${GRAY}Examples are in: ${EXTRACTED_DIR}${NC}"
|
|
74
|
-
echo ""
|
|
75
|
-
echo -e " ${WHITE}${BOLD}Try the hello, world example:${NC}"
|
|
76
|
-
echo ""
|
|
77
|
-
echo -e " ${GRAY}Example folder:${NC} ${WHITE}cd ${EXTRACTED_DIR}/hello-world/python${NC}"
|
|
78
|
-
echo ""
|
|
79
|
-
echo -e " ${GRAY}Render the example:${NC} ${WHITE}codeplain hello-world-python.plain${NC}"
|
|
80
|
-
echo ""
|
|
81
|
-
echo -e " ${GRAY}See hello-world/python/README.md for details.${NC}"
|
|
82
|
-
echo ""
|
|
83
|
-
else
|
|
84
|
-
echo -e " ${RED}✗ Failed to extract examples.${NC}"
|
|
85
|
-
fi
|
|
86
|
-
|
|
87
|
-
# Clean up temp file
|
|
88
|
-
rm -f "$TEMP_ZIP"
|
|
89
|
-
else
|
|
90
|
-
echo -e " ${RED}✗ Failed to download examples.${NC}"
|
|
91
|
-
rm -f "$TEMP_ZIP"
|
|
92
|
-
fi
|
|
93
|
-
|
|
94
|
-
echo ""
|
|
95
|
-
PROMPT=$(printf '%b' " Press ${WHITE}[Enter]${NC} to continue...")
|
|
96
|
-
read -r -p "$PROMPT" < /dev/tty
|
|
97
|
-
fi
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/nofity-slack-on-main-merge.yml
RENAMED
|
File without changes
|
|
File without changes
|
{codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/.github/workflows/publish-install-script.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/docs/starting_a_plain_project_from_scratch.md
RENAMED
|
File without changes
|
|
File without changes
|
{codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_golang/config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_python/config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{codeplain-0.3.10.dev5 → codeplain-0.3.11.dev7}/examples/example_hello_world_react/config.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|