wexample-wex-addon-dev-python 12.1.0__tar.gz → 13.0.0__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.
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/PKG-INFO +10 -10
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/README.md +5 -5
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/pyproject.toml +5 -5
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/rename.py +44 -53
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/file/python_pyproject_toml_file.py +11 -11
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/python_addon_manager.py +1 -1
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/abstract_python_path_rename_handler.py +104 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/abstract_python_rename_handler.py +89 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/abstract_python_symbol_rename_handler.py +183 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/applier.py +87 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/python_class_rename_handler.py +19 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/python_common.py +426 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/python_constant_rename_handler.py +37 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/python_function_rename_handler.py +21 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/python_module_rename_handler.py +74 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/python_package_rename_handler.py +125 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/rename_plan.py +84 -0
- wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/refactor/symbol_kind.py +34 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/commands/service/setup.py +2 -2
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/workdir/python_package_workdir.py +8 -8
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/workdir/python_workdir.py +6 -6
- {wexample_wex_addon_dev_python-12.1.0/tests/helpers → wexample_wex_addon_dev_python-13.0.0/tests/helper}/test_pdm.py +5 -5
- wexample_wex_addon_dev_python-13.0.0/tests/integration/refactor/test_python_class_rename_handler.py +121 -0
- wexample_wex_addon_dev_python-13.0.0/tests/integration/refactor/test_python_constant_rename_handler.py +68 -0
- wexample_wex_addon_dev_python-13.0.0/tests/integration/refactor/test_python_function_rename_handler.py +80 -0
- wexample_wex_addon_dev_python-13.0.0/tests/integration/refactor/test_python_module_rename_handler.py +59 -0
- wexample_wex_addon_dev_python-13.0.0/tests/integration/refactor/test_python_package_rename_handler.py +122 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/__init__.py +0 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/helper/__init__.py +0 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/__init__.py +0 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_abstract_python_path_rename_handler.py +17 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_abstract_python_rename_handler.py +44 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_abstract_python_symbol_rename_handler.py +92 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_applier.py +74 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_python_class_rename_handler.py +39 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_python_common.py +182 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_python_constant_rename_handler.py +75 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_python_function_rename_handler.py +37 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_python_module_rename_handler.py +77 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_python_package_rename_handler.py +60 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_rename_plan.py +65 -0
- wexample_wex_addon_dev_python-13.0.0/tests/unit/refactor/test_symbol_kind.py +17 -0
- wexample_wex_addon_dev_python-12.1.0/src/wexample_wex_addon_dev_python/refactor/applier.py +0 -46
- wexample_wex_addon_dev_python-12.1.0/src/wexample_wex_addon_dev_python/refactor/python_package_rename_handler.py +0 -261
- wexample_wex_addon_dev_python-12.1.0/src/wexample_wex_addon_dev_python/refactor/rename_plan.py +0 -43
- wexample_wex_addon_dev_python-12.1.0/src/wexample_wex_addon_dev_python/refactor/symbol_kind.py +0 -19
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/mypy.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/pylint.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/check/pyright.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/check.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/format/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/format/black.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/format/isort.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/code/format.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/examples/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/examples/utils/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/examples/utils/some_example_type.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/examples/validate.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/commands/release/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/common/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/common/pypi_registry_gateway.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/config_value/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/config_value/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/config_value/python_package_readme_config_value.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/const/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/const/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/const/package.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/const/python.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/const/tags.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/file/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/file/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/file/python_app_iml_file.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0/src/wexample_wex_addon_dev_python/helpers → wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/helper}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0/src/wexample_wex_addon_dev_python/helpers → wexample_wex_addon_dev_python-13.0.0/src/wexample_wex_addon_dev_python/helper}/pdm.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/middleware/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/middleware/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/middleware/each_python_file_middleware.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/py.typed +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/refactor/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/resources/.wex.yml +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/resources/docker/Dockerfile.python-profiling +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/resources/package_publish_gitlab.yml +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/resources/readme_templates/tests.md.j2 +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/selection/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/selection/abstract_python_code_selection.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/selection/python_code_performance_selection.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/app_service.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/commands/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/commands/service/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/commands/service/install.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/docker/.wex.yml +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/docker/docker-compose.yml +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/docker-compose.yml +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/entrypoint.sh +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/images/Dockerfile.base +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/images/Dockerfile.develop +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/samples/docker/images/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/services/python/service.yml +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/workdir/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/workdir/__pycache__/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/workdir/mixin/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/workdir/mixin/with_profiling_python_workdir_mixin.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/src/wexample_wex_addon_dev_python/workdir/python_packages_suite_workdir.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0/tests/helpers → wexample_wex_addon_dev_python-13.0.0/tests/helper}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0/tests/unit → wexample_wex_addon_dev_python-13.0.0/tests/integration}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0/tests/unit/helpers → wexample_wex_addon_dev_python-13.0.0/tests/integration/refactor}/__init__.py +0 -0
- {wexample_wex_addon_dev_python-12.1.0/tests/unit/helpers → wexample_wex_addon_dev_python-13.0.0/tests/unit/helper}/test_pdm.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: wexample-wex-addon-dev-python
|
|
3
|
-
Version:
|
|
3
|
+
Version: 13.0.0
|
|
4
4
|
Summary: Python dev addon for wex
|
|
5
5
|
Author-Email: weeger <contact@wexample.com>
|
|
6
6
|
License: MIT
|
|
@@ -15,10 +15,10 @@ Requires-Dist: griffe>=2.0.2
|
|
|
15
15
|
Requires-Dist: networkx
|
|
16
16
|
Requires-Dist: pylint
|
|
17
17
|
Requires-Dist: pyright
|
|
18
|
-
Requires-Dist: wexample-api>=6.
|
|
19
|
-
Requires-Dist: wexample-filestate-python>=
|
|
20
|
-
Requires-Dist: wexample-wex-addon-ai>=
|
|
21
|
-
Requires-Dist: wexample-wex-addon-app>=
|
|
18
|
+
Requires-Dist: wexample-api>=6.8.0
|
|
19
|
+
Requires-Dist: wexample-filestate-python>=9.0.0
|
|
20
|
+
Requires-Dist: wexample-wex-addon-ai>=12.0.0
|
|
21
|
+
Requires-Dist: wexample-wex-addon-app>=28.0.0
|
|
22
22
|
Provides-Extra: dev
|
|
23
23
|
Requires-Dist: pytest; extra == "dev"
|
|
24
24
|
Requires-Dist: pytest-cov; extra == "dev"
|
|
@@ -26,7 +26,7 @@ Description-Content-Type: text/markdown
|
|
|
26
26
|
|
|
27
27
|
# wex_addon_dev_python
|
|
28
28
|
|
|
29
|
-
Version:
|
|
29
|
+
Version: 13.0.0
|
|
30
30
|
|
|
31
31
|
Python dev addon for wex
|
|
32
32
|
|
|
@@ -112,10 +112,10 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
112
112
|
- networkx:
|
|
113
113
|
- pylint:
|
|
114
114
|
- pyright:
|
|
115
|
-
- wexample-api: >=6.
|
|
116
|
-
- wexample-filestate-python: >=
|
|
117
|
-
- wexample-wex-addon-ai: >=
|
|
118
|
-
- wexample-wex-addon-app: >=
|
|
115
|
+
- wexample-api: >=6.8.0
|
|
116
|
+
- wexample-filestate-python: >=9.0.0
|
|
117
|
+
- wexample-wex-addon-ai: >=12.0.0
|
|
118
|
+
- wexample-wex-addon-app: >=28.0.0
|
|
119
119
|
|
|
120
120
|
## Versioning & Compatibility Policy
|
|
121
121
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# wex_addon_dev_python
|
|
2
2
|
|
|
3
|
-
Version:
|
|
3
|
+
Version: 13.0.0
|
|
4
4
|
|
|
5
5
|
Python dev addon for wex
|
|
6
6
|
|
|
@@ -86,10 +86,10 @@ Visit the [Wexample Suite documentation](https://docs.wexample.com) for the comp
|
|
|
86
86
|
- networkx:
|
|
87
87
|
- pylint:
|
|
88
88
|
- pyright:
|
|
89
|
-
- wexample-api: >=6.
|
|
90
|
-
- wexample-filestate-python: >=
|
|
91
|
-
- wexample-wex-addon-ai: >=
|
|
92
|
-
- wexample-wex-addon-app: >=
|
|
89
|
+
- wexample-api: >=6.8.0
|
|
90
|
+
- wexample-filestate-python: >=9.0.0
|
|
91
|
+
- wexample-wex-addon-ai: >=12.0.0
|
|
92
|
+
- wexample-wex-addon-app: >=28.0.0
|
|
93
93
|
|
|
94
94
|
## Versioning & Compatibility Policy
|
|
95
95
|
|
{wexample_wex_addon_dev_python-12.1.0 → wexample_wex_addon_dev_python-13.0.0}/pyproject.toml
RENAMED
|
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
|
|
|
6
6
|
|
|
7
7
|
[project]
|
|
8
8
|
name = "wexample-wex-addon-dev-python"
|
|
9
|
-
version = "
|
|
9
|
+
version = "13.0.0"
|
|
10
10
|
description = "Python dev addon for wex"
|
|
11
11
|
authors = [
|
|
12
12
|
{ name = "weeger", email = "contact@wexample.com" },
|
|
@@ -24,10 +24,10 @@ dependencies = [
|
|
|
24
24
|
"networkx",
|
|
25
25
|
"pylint",
|
|
26
26
|
"pyright",
|
|
27
|
-
"wexample-api>=6.
|
|
28
|
-
"wexample-filestate-python>=
|
|
29
|
-
"wexample-wex-addon-ai>=
|
|
30
|
-
"wexample-wex-addon-app>=
|
|
27
|
+
"wexample-api>=6.8.0",
|
|
28
|
+
"wexample-filestate-python>=9.0.0",
|
|
29
|
+
"wexample-wex-addon-ai>=12.0.0",
|
|
30
|
+
"wexample-wex-addon-app>=28.0.0",
|
|
31
31
|
]
|
|
32
32
|
|
|
33
33
|
[project.readme]
|
|
@@ -32,8 +32,7 @@ if TYPE_CHECKING:
|
|
|
32
32
|
@option(
|
|
33
33
|
name="kind",
|
|
34
34
|
type=str,
|
|
35
|
-
required=
|
|
36
|
-
default="package",
|
|
35
|
+
required=True,
|
|
37
36
|
description="Symbol kind to rename. Step 1 supports only 'package'.",
|
|
38
37
|
)
|
|
39
38
|
@option(
|
|
@@ -69,6 +68,18 @@ def python__code__rename(
|
|
|
69
68
|
from wexample_app.response.failure_response import FailureResponse
|
|
70
69
|
from wexample_app.response.table_response import TableResponse
|
|
71
70
|
|
|
71
|
+
from wexample_wex_addon_dev_python.refactor.python_class_rename_handler import (
|
|
72
|
+
PythonClassRenameHandler,
|
|
73
|
+
)
|
|
74
|
+
from wexample_wex_addon_dev_python.refactor.python_constant_rename_handler import (
|
|
75
|
+
PythonConstantRenameHandler,
|
|
76
|
+
)
|
|
77
|
+
from wexample_wex_addon_dev_python.refactor.python_function_rename_handler import (
|
|
78
|
+
PythonFunctionRenameHandler,
|
|
79
|
+
)
|
|
80
|
+
from wexample_wex_addon_dev_python.refactor.python_module_rename_handler import (
|
|
81
|
+
PythonModuleRenameHandler,
|
|
82
|
+
)
|
|
72
83
|
from wexample_wex_addon_dev_python.refactor.python_package_rename_handler import (
|
|
73
84
|
PythonPackageRenameHandler,
|
|
74
85
|
)
|
|
@@ -85,42 +96,53 @@ def python__code__rename(
|
|
|
85
96
|
),
|
|
86
97
|
)
|
|
87
98
|
|
|
88
|
-
|
|
99
|
+
handler_class = {
|
|
100
|
+
SymbolKind.PACKAGE: PythonPackageRenameHandler,
|
|
101
|
+
SymbolKind.MODULE: PythonModuleRenameHandler,
|
|
102
|
+
SymbolKind.CLASS: PythonClassRenameHandler,
|
|
103
|
+
SymbolKind.FUNCTION: PythonFunctionRenameHandler,
|
|
104
|
+
SymbolKind.CONSTANT: PythonConstantRenameHandler,
|
|
105
|
+
}.get(kind_enum)
|
|
106
|
+
if handler_class is None:
|
|
89
107
|
return FailureResponse(
|
|
90
108
|
kernel=context.kernel,
|
|
91
|
-
message=
|
|
92
|
-
f"--kind {kind_enum.value} not implemented yet "
|
|
93
|
-
"(step 1 covers 'package' only)."
|
|
94
|
-
),
|
|
109
|
+
message=f"--kind {kind_enum.value} not implemented yet.",
|
|
95
110
|
)
|
|
96
111
|
|
|
97
|
-
scope_roots
|
|
112
|
+
scope_roots = app_workdir.get_code_scope_paths(context.kernel)
|
|
98
113
|
|
|
99
|
-
handler =
|
|
114
|
+
handler = handler_class(
|
|
100
115
|
scope_roots=scope_roots,
|
|
101
116
|
source=source,
|
|
102
117
|
target=target,
|
|
103
118
|
dry_run=dry_run,
|
|
104
119
|
)
|
|
120
|
+
|
|
121
|
+
spinner = context.io.spinner(
|
|
122
|
+
label=f"Scanning {len(scope_roots)} root(s) for '{source}' ({kind_enum.value})…"
|
|
123
|
+
)
|
|
105
124
|
try:
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
125
|
+
try:
|
|
126
|
+
report = handler.run()
|
|
127
|
+
except FileNotFoundError as e:
|
|
128
|
+
return FailureResponse(kernel=context.kernel, message=str(e))
|
|
129
|
+
except ValueError as e:
|
|
130
|
+
# Ambiguous match (multiple matches) or invalid dotted name.
|
|
131
|
+
return FailureResponse(kernel=context.kernel, message=str(e))
|
|
132
|
+
except RuntimeError as e:
|
|
133
|
+
# Preflight failure (permissions, target exists). Plan was thrown
|
|
134
|
+
# away, no file has been written — surface as a clean failure.
|
|
135
|
+
return FailureResponse(kernel=context.kernel, message=str(e))
|
|
136
|
+
finally:
|
|
137
|
+
spinner.stop()
|
|
116
138
|
|
|
117
139
|
mode = "APPLIED" if not dry_run else "DRY-RUN"
|
|
118
140
|
context.io.log(
|
|
119
|
-
f"[{mode}] {report.
|
|
141
|
+
f"[{mode}] {report.source_path} → {report.target_path}"
|
|
120
142
|
)
|
|
121
143
|
context.io.log(
|
|
122
|
-
f"[{mode}] scope={
|
|
123
|
-
f"changed={len(report.files_changed)}"
|
|
144
|
+
f"[{mode}] scope={len(scope_roots)} root(s) "
|
|
145
|
+
f"scanned={report.files_scanned} changed={len(report.files_changed)}"
|
|
124
146
|
)
|
|
125
147
|
|
|
126
148
|
# Display paths relative to the matched scope root they live under, so the
|
|
@@ -133,37 +155,6 @@ def python__code__rename(
|
|
|
133
155
|
)
|
|
134
156
|
|
|
135
157
|
|
|
136
|
-
def _resolve_scope_roots(kernel, app_workdir):
|
|
137
|
-
"""Return (scope_roots, info_string).
|
|
138
|
-
|
|
139
|
-
Looks up a containing suite via `find_suite_workdir_path()`; if found,
|
|
140
|
-
materialises the suite workdir and returns the path of every ordered
|
|
141
|
-
sibling package PLUS any consumer paths declared in the suite config
|
|
142
|
-
(resolved by `get_consumers_paths()`). Otherwise falls back to the
|
|
143
|
-
current workdir alone.
|
|
144
|
-
"""
|
|
145
|
-
from wexample_wex_addon_app.app_addon_manager import AppAddonManager
|
|
146
|
-
|
|
147
|
-
suite_path = app_workdir.find_suite_workdir_path()
|
|
148
|
-
if not suite_path:
|
|
149
|
-
return [app_workdir.get_path()], f"workdir={app_workdir.get_path()}"
|
|
150
|
-
|
|
151
|
-
suite_workdir = AppAddonManager.from_kernel(kernel).create_app_workdir(
|
|
152
|
-
path=suite_path
|
|
153
|
-
)
|
|
154
|
-
packages = suite_workdir.get_ordered_packages()
|
|
155
|
-
if not packages:
|
|
156
|
-
return [app_workdir.get_path()], f"workdir={app_workdir.get_path()}"
|
|
157
|
-
|
|
158
|
-
roots = [p.get_path() for p in packages]
|
|
159
|
-
consumers = suite_workdir.get_consumers_paths()
|
|
160
|
-
roots.extend(consumers)
|
|
161
|
-
return (
|
|
162
|
-
roots,
|
|
163
|
-
f"suite={suite_path} (packages={len(packages)}, consumers={len(consumers)})",
|
|
164
|
-
)
|
|
165
|
-
|
|
166
|
-
|
|
167
158
|
def _shortest_rel(path, roots):
|
|
168
159
|
"""Return `path` relative to the longest matching root, else absolute."""
|
|
169
160
|
best = None
|
|
@@ -24,7 +24,7 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
24
24
|
) -> bool:
|
|
25
25
|
from packaging.requirements import Requirement
|
|
26
26
|
from packaging.utils import canonicalize_name
|
|
27
|
-
from wexample_filestate_python.
|
|
27
|
+
from wexample_filestate_python.helper.toml import toml_sort_string_array
|
|
28
28
|
|
|
29
29
|
new_name = canonicalize_name(spec.name)
|
|
30
30
|
|
|
@@ -118,7 +118,7 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
118
118
|
|
|
119
119
|
def optional_group_array(self, group: str):
|
|
120
120
|
"""Ensure and return project.optional-dependencies[group] as multi-line array."""
|
|
121
|
-
from wexample_filestate_python.
|
|
121
|
+
from wexample_filestate_python.helper.toml import (
|
|
122
122
|
toml_ensure_array,
|
|
123
123
|
toml_ensure_table,
|
|
124
124
|
)
|
|
@@ -162,7 +162,7 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
162
162
|
|
|
163
163
|
def _dependencies_array(self):
|
|
164
164
|
"""Ensure and return project.dependencies as a multi-line TOML array."""
|
|
165
|
-
from wexample_filestate_python.
|
|
165
|
+
from wexample_filestate_python.helper.toml import toml_ensure_array
|
|
166
166
|
|
|
167
167
|
project = self._project_table()
|
|
168
168
|
deps, _ = toml_ensure_array(project, "dependencies")
|
|
@@ -187,7 +187,7 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
187
187
|
if not import_name:
|
|
188
188
|
return
|
|
189
189
|
|
|
190
|
-
from wexample_filestate_python.
|
|
190
|
+
from wexample_filestate_python.helper.toml import toml_ensure_table
|
|
191
191
|
|
|
192
192
|
tool_tbl, _ = toml_ensure_table(content, ["tool"])
|
|
193
193
|
pdm_tbl, _ = toml_ensure_table(tool_tbl, ["pdm"])
|
|
@@ -207,7 +207,7 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
207
207
|
def _enforce_project_metadata(
|
|
208
208
|
self, content: dict, project_name: str | None, project_version: str | None
|
|
209
209
|
) -> None:
|
|
210
|
-
from wexample_filestate_python.
|
|
210
|
+
from wexample_filestate_python.helper.toml import toml_ensure_table
|
|
211
211
|
|
|
212
212
|
project_tbl, _ = toml_ensure_table(content, ["project"])
|
|
213
213
|
if project_name:
|
|
@@ -267,7 +267,7 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
267
267
|
if not import_name:
|
|
268
268
|
return
|
|
269
269
|
|
|
270
|
-
from wexample_filestate_python.
|
|
270
|
+
from wexample_filestate_python.helper.toml import toml_ensure_table
|
|
271
271
|
|
|
272
272
|
tool_tbl, _ = toml_ensure_table(content, ["tool"])
|
|
273
273
|
|
|
@@ -298,8 +298,8 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
298
298
|
]
|
|
299
299
|
|
|
300
300
|
def _ensure_dev_dependencies(self, content: dict) -> None:
|
|
301
|
-
from wexample_filestate_python.
|
|
302
|
-
from wexample_filestate_python.
|
|
301
|
+
from wexample_filestate_python.helper.package import package_normalize_name
|
|
302
|
+
from wexample_filestate_python.helper.toml import (
|
|
303
303
|
toml_get_string_value,
|
|
304
304
|
toml_sort_string_array,
|
|
305
305
|
)
|
|
@@ -325,8 +325,8 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
325
325
|
)
|
|
326
326
|
|
|
327
327
|
def _normalize_dependencies(self, content: dict) -> None:
|
|
328
|
-
from wexample_filestate_python.
|
|
329
|
-
from wexample_filestate_python.
|
|
328
|
+
from wexample_filestate_python.helper.package import package_normalize_name
|
|
329
|
+
from wexample_filestate_python.helper.toml import (
|
|
330
330
|
toml_get_string_value,
|
|
331
331
|
toml_sort_string_array,
|
|
332
332
|
)
|
|
@@ -385,7 +385,7 @@ class PythonPyprojectTomlFile(AppDependenciesConfigFileMixin, TomlFile):
|
|
|
385
385
|
|
|
386
386
|
def _project_table(self):
|
|
387
387
|
"""Ensure and return the [project] table."""
|
|
388
|
-
from wexample_filestate_python.
|
|
388
|
+
from wexample_filestate_python.helper.toml import toml_ensure_table
|
|
389
389
|
|
|
390
390
|
doc = self.read_parsed()
|
|
391
391
|
project, _ = toml_ensure_table(doc, ["project"])
|
|
@@ -14,7 +14,7 @@ if TYPE_CHECKING:
|
|
|
14
14
|
|
|
15
15
|
class PythonAddonManager(SelectionContributingAddonMixin, AbstractAddonManager):
|
|
16
16
|
def get_local_configurable_keys(self) -> list[dict]:
|
|
17
|
-
from wexample_wex_addon_dev_python.
|
|
17
|
+
from wexample_wex_addon_dev_python.helper.pdm import (
|
|
18
18
|
apply_pdm_bin_dir,
|
|
19
19
|
detect_pdm_bin_dir,
|
|
20
20
|
)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from wexample_helpers.classes.abstract_method import abstract_method
|
|
6
|
+
from wexample_helpers.classes.private_field import private_field
|
|
7
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
8
|
+
|
|
9
|
+
from wexample_wex_addon_dev_python.refactor.abstract_python_rename_handler import (
|
|
10
|
+
AbstractPythonRenameHandler,
|
|
11
|
+
)
|
|
12
|
+
from wexample_wex_addon_dev_python.refactor.python_common import (
|
|
13
|
+
RenameReport,
|
|
14
|
+
iter_python_files,
|
|
15
|
+
rewrite_imports,
|
|
16
|
+
)
|
|
17
|
+
from wexample_wex_addon_dev_python.refactor.rename_plan import RenamePlan
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@base_class
|
|
21
|
+
class AbstractPythonPathRenameHandler(AbstractPythonRenameHandler):
|
|
22
|
+
"""Common shell for renames that boil down to moving one filesystem entry
|
|
23
|
+
(a package directory, a single .py file…) and rewriting every dotted
|
|
24
|
+
import statement that targets it.
|
|
25
|
+
|
|
26
|
+
Subclasses only customise *what* to locate on disk and *how* the new path
|
|
27
|
+
is derived. The plan, the report, and the per-file rewrite loop live here.
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
_resolved_source_path: Path | None = private_field(
|
|
31
|
+
default=None,
|
|
32
|
+
description="Source path located by `_find_source_path` during "
|
|
33
|
+
"compute_plan; used to build the report when `path_renames` is empty "
|
|
34
|
+
"(e.g. merge mode).",
|
|
35
|
+
)
|
|
36
|
+
_resolved_target_path: Path | None = private_field(
|
|
37
|
+
default=None,
|
|
38
|
+
description="Target path derived from the source during compute_plan; "
|
|
39
|
+
"used by the report alongside `_resolved_source_path`.",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
def compute_plan(self) -> RenamePlan:
|
|
43
|
+
plan = RenamePlan()
|
|
44
|
+
source_path = self._find_source_path()
|
|
45
|
+
target_path = self._derive_target_path(source_path)
|
|
46
|
+
self._resolved_source_path = source_path
|
|
47
|
+
self._resolved_target_path = target_path
|
|
48
|
+
self._plan_path_move(plan, source_path, target_path)
|
|
49
|
+
self._plan_target_parent_creation(plan, target_path)
|
|
50
|
+
|
|
51
|
+
for py_file in iter_python_files(self.scope_roots):
|
|
52
|
+
plan.files_scanned += 1
|
|
53
|
+
new_source = rewrite_imports(
|
|
54
|
+
py_file, self._source_parts, self._target_parts
|
|
55
|
+
)
|
|
56
|
+
if new_source is not None:
|
|
57
|
+
plan.rewrites[py_file] = new_source
|
|
58
|
+
|
|
59
|
+
return plan
|
|
60
|
+
|
|
61
|
+
def _build_report(self, plan: RenamePlan) -> RenameReport:
|
|
62
|
+
return RenameReport(
|
|
63
|
+
files_changed=list(plan.rewrites.keys()),
|
|
64
|
+
files_scanned=plan.files_scanned,
|
|
65
|
+
source_path=self._resolved_source_path,
|
|
66
|
+
target_path=self._resolved_target_path,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
@abstract_method
|
|
70
|
+
def _derive_target_path(self, source_path: Path) -> Path:
|
|
71
|
+
"""Return where `source_path` should be moved to on disk."""
|
|
72
|
+
|
|
73
|
+
@abstract_method
|
|
74
|
+
def _find_source_path(self) -> Path:
|
|
75
|
+
"""Locate the unique filesystem entry that matches `source`."""
|
|
76
|
+
|
|
77
|
+
def _plan_path_move(
|
|
78
|
+
self, plan: RenamePlan, source_path: Path, target_path: Path
|
|
79
|
+
) -> None:
|
|
80
|
+
"""Default move: one atomic path rename. Subclasses may override to
|
|
81
|
+
merge into an existing target (`PythonPackageRenameHandler`)."""
|
|
82
|
+
plan.path_renames.append((source_path, target_path))
|
|
83
|
+
|
|
84
|
+
def _plan_target_parent_creation(
|
|
85
|
+
self, plan: RenamePlan, target_path: Path
|
|
86
|
+
) -> None:
|
|
87
|
+
"""Walk up from `target_path.parent` and queue every missing ancestor
|
|
88
|
+
directory plus an empty `__init__.py` so the move can land inside a
|
|
89
|
+
valid Python package even when the user renames across parents."""
|
|
90
|
+
parent = target_path.parent
|
|
91
|
+
missing: list[Path] = []
|
|
92
|
+
while not parent.exists():
|
|
93
|
+
missing.append(parent)
|
|
94
|
+
up = parent.parent
|
|
95
|
+
if up == parent:
|
|
96
|
+
raise RuntimeError(
|
|
97
|
+
f"Cannot find any existing ancestor for {target_path}"
|
|
98
|
+
)
|
|
99
|
+
parent = up
|
|
100
|
+
|
|
101
|
+
# Outermost-first so each `mkdir` finds its own parent in place.
|
|
102
|
+
for directory in reversed(missing):
|
|
103
|
+
plan.directories_to_create.append(directory)
|
|
104
|
+
plan.rewrites[directory / "__init__.py"] = ""
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from wexample_helpers.classes.abstract_method import abstract_method
|
|
6
|
+
from wexample_helpers.classes.base_class import BaseClass
|
|
7
|
+
from wexample_helpers.classes.field import public_field
|
|
8
|
+
from wexample_helpers.classes.private_field import private_field
|
|
9
|
+
from wexample_helpers.decorator.base_class import base_class
|
|
10
|
+
|
|
11
|
+
from wexample_wex_addon_dev_python.refactor.applier import (
|
|
12
|
+
NaiveRenameApplier,
|
|
13
|
+
RenameApplier,
|
|
14
|
+
)
|
|
15
|
+
from wexample_wex_addon_dev_python.refactor.python_common import RenameReport
|
|
16
|
+
from wexample_wex_addon_dev_python.refactor.rename_plan import RenamePlan
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@base_class
|
|
20
|
+
class AbstractPythonRenameHandler(BaseClass):
|
|
21
|
+
"""Top-level shell for any Python rename, regardless of what gets renamed
|
|
22
|
+
(a package directory, a single module file, a class/function/constant
|
|
23
|
+
inside a module, …).
|
|
24
|
+
|
|
25
|
+
Subclasses decide what the plan looks like (`compute_plan`) and how the
|
|
26
|
+
report describes the operation (`_build_report`). Everything else — field
|
|
27
|
+
layout, init validation, three-phase orchestration — lives here so every
|
|
28
|
+
flavour of rename stays strictly consistent.
|
|
29
|
+
"""
|
|
30
|
+
dry_run: bool = public_field(
|
|
31
|
+
default=True,
|
|
32
|
+
description="When True, return the plan/report without touching the "
|
|
33
|
+
"filesystem.",
|
|
34
|
+
)
|
|
35
|
+
scope_roots: list[Path] = public_field(
|
|
36
|
+
description="Roots scanned for both source location and rewrites.",
|
|
37
|
+
)
|
|
38
|
+
source: str = public_field(
|
|
39
|
+
description="Dotted source name (e.g. 'mylib.helpers.Color').",
|
|
40
|
+
)
|
|
41
|
+
target: str = public_field(
|
|
42
|
+
description="Dotted target name (e.g. 'mylib.helpers.Tone').",
|
|
43
|
+
)
|
|
44
|
+
_source_parts: tuple[str, ...] = private_field(
|
|
45
|
+
factory=tuple,
|
|
46
|
+
description="Cached `source.split('.')`; set in __attrs_post_init__.",
|
|
47
|
+
)
|
|
48
|
+
_target_parts: tuple[str, ...] = private_field(
|
|
49
|
+
factory=tuple,
|
|
50
|
+
description="Cached `target.split('.')`; set in __attrs_post_init__.",
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
def __attrs_post_init__(self) -> None:
|
|
54
|
+
self._execute_super_attrs_post_init_if_exists()
|
|
55
|
+
if not self.scope_roots:
|
|
56
|
+
raise ValueError("scope_roots must contain at least one path")
|
|
57
|
+
self._source_parts = tuple(self.source.split("."))
|
|
58
|
+
self._target_parts = tuple(self.target.split("."))
|
|
59
|
+
if not all(self._source_parts) or not all(self._target_parts):
|
|
60
|
+
raise ValueError(
|
|
61
|
+
"source and target must be dotted names without empty parts"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
@abstract_method
|
|
65
|
+
def compute_plan(self) -> RenamePlan:
|
|
66
|
+
"""Phase 1: scan and build the plan. No write yet."""
|
|
67
|
+
|
|
68
|
+
def run(
|
|
69
|
+
self,
|
|
70
|
+
applier: RenameApplier | None = None,
|
|
71
|
+
) -> RenameReport:
|
|
72
|
+
"""Compute plan → preflight → apply (or stop after compute in dry-run)."""
|
|
73
|
+
plan = self.compute_plan()
|
|
74
|
+
report = self._build_report(plan)
|
|
75
|
+
|
|
76
|
+
if self.dry_run:
|
|
77
|
+
return report
|
|
78
|
+
|
|
79
|
+
problems = plan.preflight()
|
|
80
|
+
if problems:
|
|
81
|
+
joined = "\n - ".join(problems)
|
|
82
|
+
raise RuntimeError(f"Plan preflight failed:\n - {joined}")
|
|
83
|
+
|
|
84
|
+
(applier or NaiveRenameApplier()).apply(plan)
|
|
85
|
+
return report
|
|
86
|
+
|
|
87
|
+
@abstract_method
|
|
88
|
+
def _build_report(self, plan: RenamePlan) -> RenameReport:
|
|
89
|
+
"""Compose the user-facing report once the plan is built."""
|