py-wlcli 0.8.0__py3-none-any.whl
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.
- py_wlcli-0.8.0.dist-info/METADATA +139 -0
- py_wlcli-0.8.0.dist-info/RECORD +320 -0
- py_wlcli-0.8.0.dist-info/WHEEL +4 -0
- py_wlcli-0.8.0.dist-info/entry_points.txt +2 -0
- py_wlcli-0.8.0.dist-info/licenses/LICENSE +21 -0
- wl_cli/__init__.py +27 -0
- wl_cli/__main__.py +130 -0
- wl_cli/capabilities.py +79 -0
- wl_cli/cc/__init__.py +5 -0
- wl_cli/cc/checks.py +1019 -0
- wl_cli/cc/cli.py +370 -0
- wl_cli/cc/mutate.py +1350 -0
- wl_cli/cli_click.py +156 -0
- wl_cli/commands/__init__.py +84 -0
- wl_cli/commands/base.py +80 -0
- wl_cli/commands/buildcommands/__init__.py +1 -0
- wl_cli/commands/buildcommands/build.py +71 -0
- wl_cli/commands/buildcommands/build_utils.py +47 -0
- wl_cli/commands/buildcommands/builders/__init__.py +18 -0
- wl_cli/commands/buildcommands/builders/cleanup.py +35 -0
- wl_cli/commands/buildcommands/builders/coordinator.py +122 -0
- wl_cli/commands/buildcommands/builders/environment.py +81 -0
- wl_cli/commands/buildcommands/builders/rust_builder.py +39 -0
- wl_cli/commands/buildcommands/builders/stubs.py +58 -0
- wl_cli/commands/buildcommands/dist.py +326 -0
- wl_cli/commands/buildcommands/test.py +89 -0
- wl_cli/commands/clean/__init__.py +1 -0
- wl_cli/commands/clean/build.py +151 -0
- wl_cli/commands/clean/clean.py +294 -0
- wl_cli/commands/clean/clean_utils.py +77 -0
- wl_cli/commands/clean/core.py +236 -0
- wl_cli/commands/clean/dead_code/__init__.py +0 -0
- wl_cli/commands/clean/dead_code/dead_code_command.py +70 -0
- wl_cli/commands/clean/dead_code/detector.py +161 -0
- wl_cli/commands/clean/dead_code/fixer.py +176 -0
- wl_cli/commands/clean/dead_code/reporter.py +295 -0
- wl_cli/commands/clean/dead_code/utils.py +0 -0
- wl_cli/commands/clean/lfs.py +215 -0
- wl_cli/commands/clean/python.py +81 -0
- wl_cli/commands/clean/rust.py +91 -0
- wl_cli/commands/clean/utils/__init__.py +34 -0
- wl_cli/commands/clean/venv.py +91 -0
- wl_cli/commands/cleanup.py +73 -0
- wl_cli/commands/click_base.py +79 -0
- wl_cli/commands/config/__init__.py +1 -0
- wl_cli/commands/config/config.py +291 -0
- wl_cli/commands/debug/__init__.py +6 -0
- wl_cli/commands/debug/debug.py +309 -0
- wl_cli/commands/debug/debug_cache.py +86 -0
- wl_cli/commands/debug/debug_subagent.py +156 -0
- wl_cli/commands/debug/output_formatter.py +165 -0
- wl_cli/commands/debug/source_hasher.py +92 -0
- wl_cli/commands/format/__init__.py +13 -0
- wl_cli/commands/format/format_cache_adapter.py +125 -0
- wl_cli/commands/format/format_command.py +197 -0
- wl_cli/commands/format/format_coordinator.py +191 -0
- wl_cli/commands/format/format_executor.py +470 -0
- wl_cli/commands/format/format_outcome.py +44 -0
- wl_cli/commands/format/format_path_handler.py +1016 -0
- wl_cli/commands/format/format_progress.py +62 -0
- wl_cli/commands/format/format_reporter.py +31 -0
- wl_cli/commands/format/python_formatter.py +506 -0
- wl_cli/commands/format/rust_formatter.py +106 -0
- wl_cli/commands/gate/__init__.py +1 -0
- wl_cli/commands/gate/gate_command.py +862 -0
- wl_cli/commands/gate/preflight.py +445 -0
- wl_cli/commands/git/__init__.py +1 -0
- wl_cli/commands/git/config.py +169 -0
- wl_cli/commands/git/git_facts.py +60 -0
- wl_cli/commands/git/git_flow.py +86 -0
- wl_cli/commands/git/hook.py +112 -0
- wl_cli/commands/git/policy.py +216 -0
- wl_cli/commands/git/push_update.py +82 -0
- wl_cli/commands/initenv/__init__.py +1 -0
- wl_cli/commands/initenv/common/__init__.py +23 -0
- wl_cli/commands/initenv/common/check_git_bash.py +78 -0
- wl_cli/commands/initenv/common/error_handler.py +68 -0
- wl_cli/commands/initenv/common/exceptions.py +52 -0
- wl_cli/commands/initenv/components/__init__.py +4 -0
- wl_cli/commands/initenv/components/cargo_sync.py +240 -0
- wl_cli/commands/initenv/components/config_manager.py +106 -0
- wl_cli/commands/initenv/components/directory_utils.py +71 -0
- wl_cli/commands/initenv/components/git/__init__.py +9 -0
- wl_cli/commands/initenv/components/git/branch_creator.py +143 -0
- wl_cli/commands/initenv/components/git/git_flow_interface.py +24 -0
- wl_cli/commands/initenv/components/git/git_flow_manager.py +159 -0
- wl_cli/commands/initenv/components/git/git_lfs_manager.py +272 -0
- wl_cli/commands/initenv/components/git/git_utility.py +254 -0
- wl_cli/commands/initenv/components/git/gitignore_manager.py +53 -0
- wl_cli/commands/initenv/components/git_initializer.py +212 -0
- wl_cli/commands/initenv/components/i18n_manager.py +104 -0
- wl_cli/commands/initenv/components/log_manager.py +241 -0
- wl_cli/commands/initenv/components/project_structure/__init__.py +23 -0
- wl_cli/commands/initenv/components/project_structure/config_generator.py +360 -0
- wl_cli/commands/initenv/components/project_structure/directory_creator.py +184 -0
- wl_cli/commands/initenv/components/project_structure/hook_source.py +110 -0
- wl_cli/commands/initenv/components/project_structure/hooks_manager.py +995 -0
- wl_cli/commands/initenv/components/project_structure/readme_handler.py +56 -0
- wl_cli/commands/initenv/components/project_structure/rust_files_handler.py +30 -0
- wl_cli/commands/initenv/components/project_structure/setup_handler.py +103 -0
- wl_cli/commands/initenv/components/project_structure/sop_generator.py +73 -0
- wl_cli/commands/initenv/components/project_structure/template_copier.py +104 -0
- wl_cli/commands/initenv/components/project_structure/template_manager.py +195 -0
- wl_cli/commands/initenv/components/pyproject_generator.py +194 -0
- wl_cli/commands/initenv/components/rust_initializer.py +145 -0
- wl_cli/commands/initenv/components/symlink_cleaner.py +99 -0
- wl_cli/commands/initenv/components/symlink_manager.py +52 -0
- wl_cli/commands/initenv/components/venv_manager.py +118 -0
- wl_cli/commands/initenv/initenv.py +169 -0
- wl_cli/commands/initenv/services/__init__.py +11 -0
- wl_cli/commands/initenv/services/environment_initializer.py +288 -0
- wl_cli/commands/initenv/services/git_lfs_initializer.py +26 -0
- wl_cli/commands/initenv/services/project_structure_initializer.py +52 -0
- wl_cli/commands/lfs/README.md +221 -0
- wl_cli/commands/lfs/__init__.py +5 -0
- wl_cli/commands/lfs/cli.py +106 -0
- wl_cli/commands/lfs/config.py +164 -0
- wl_cli/commands/lfs/hook.py +61 -0
- wl_cli/commands/lfs/initializer.py +531 -0
- wl_cli/commands/lfs/manager.py +95 -0
- wl_cli/commands/lfs/policy.py +165 -0
- wl_cli/commands/lfs/watcher.py +294 -0
- wl_cli/commands/lint/__init__.py +1 -0
- wl_cli/commands/lint/lint_command.py +297 -0
- wl_cli/commands/lint/lint_executor.py +409 -0
- wl_cli/commands/lint/lint_reporter.py +579 -0
- wl_cli/commands/lint/lint_run.py +258 -0
- wl_cli/commands/lint/mypy_config.py +90 -0
- wl_cli/commands/registry.py +103 -0
- wl_cli/commands/self/__init__.py +7 -0
- wl_cli/commands/self/common/__init__.py +8 -0
- wl_cli/commands/self/common/capabilities.py +30 -0
- wl_cli/commands/self/common/config.py +27 -0
- wl_cli/commands/self/common/version_cache.py +85 -0
- wl_cli/commands/self/handlers/__init__.py +19 -0
- wl_cli/commands/self/handlers/base_handler.py +28 -0
- wl_cli/commands/self/handlers/install_handler.py +85 -0
- wl_cli/commands/self/handlers/status_handler.py +66 -0
- wl_cli/commands/self/handlers/uninstall_handler.py +58 -0
- wl_cli/commands/self/handlers/update_handler.py +102 -0
- wl_cli/commands/self/handlers/version_handler.py +16 -0
- wl_cli/commands/self/self_command.py +237 -0
- wl_cli/commands/self/services/__init__.py +15 -0
- wl_cli/commands/self/services/installation_manager.py +187 -0
- wl_cli/commands/self/services/local_installer.py +165 -0
- wl_cli/commands/self/services/pypi_updater.py +278 -0
- wl_cli/commands/self/services/windows_update.py +174 -0
- wl_cli/commands/testcommands/__init__.py +8 -0
- wl_cli/commands/testcommands/base_dependency_analyzer.py +198 -0
- wl_cli/commands/testcommands/batch_processor.py +278 -0
- wl_cli/commands/testcommands/cache_manager.py +1156 -0
- wl_cli/commands/testcommands/coverage_analyzer.py +955 -0
- wl_cli/commands/testcommands/coverage_cache_manager.py +183 -0
- wl_cli/commands/testcommands/progress_manager.py +79 -0
- wl_cli/commands/testcommands/python_env_detector.py +207 -0
- wl_cli/commands/testcommands/report_generator.py +101 -0
- wl_cli/commands/testcommands/single_test_executor.py +250 -0
- wl_cli/commands/testcommands/speed_checker.py +118 -0
- wl_cli/commands/testcommands/test_command_builder.py +165 -0
- wl_cli/commands/testcommands/test_commands.py +786 -0
- wl_cli/commands/testcommands/test_reporter.py +181 -0
- wl_cli/commands/testcommands/test_result_handler.py +96 -0
- wl_cli/commands/testcommands/test_runner.py +1343 -0
- wl_cli/commands/testcommands/test_utils.py +197 -0
- wl_cli/commands/testcommands/utils/__init__.py +17 -0
- wl_cli/commands/testcommands/utils/coverage_parser.py +98 -0
- wl_cli/commands/testcommands/utils/env_info.py +36 -0
- wl_cli/commands/testcommands/utils/junit_parser.py +75 -0
- wl_cli/commands/testcommands/utils/markdown_utils.py +20 -0
- wl_cli/commands/testcommands/utils/project_root.py +61 -0
- wl_cli/commands/update/__init__.py +9 -0
- wl_cli/commands/update/services/__init__.py +21 -0
- wl_cli/commands/update/services/backup_manager.py +207 -0
- wl_cli/commands/update/services/component_manager.py +83 -0
- wl_cli/commands/update/services/conflict_resolver.py +189 -0
- wl_cli/commands/update/services/vendors_updater.py +85 -0
- wl_cli/commands/update/services/version_tracker.py +127 -0
- wl_cli/commands/update/update_command.py +270 -0
- wl_cli/commands/update/utils/__init__.py +3 -0
- wl_cli/commands/version/__init__.py +9 -0
- wl_cli/commands/version/version_command.py +155 -0
- wl_cli/commands/workflow.py +477 -0
- wl_cli/env/__init__.py +5 -0
- wl_cli/env/cli.py +167 -0
- wl_cli/env_status.py +157 -0
- wl_cli/envelope.py +91 -0
- wl_cli/exceptions.py +85 -0
- wl_cli/lib/__init__.py +3 -0
- wl_cli/lib/rust_utils.py +35 -0
- wl_cli/mcp/__init__.py +6 -0
- wl_cli/mcp/capabilities.py +19 -0
- wl_cli/mcp/cli.py +22 -0
- wl_cli/mcp/gitlab.py +553 -0
- wl_cli/mcp/k8s.py +344 -0
- wl_cli/mcp/protocol.py +159 -0
- wl_cli/platform.py +139 -0
- wl_cli/quality/__init__.py +18 -0
- wl_cli/utils/__init__.py +7 -0
- wl_cli/utils/cache.py +491 -0
- wl_cli/utils/cache_ledger.py +355 -0
- wl_cli/utils/cache_store.py +546 -0
- wl_cli/utils/config/__init__.py +27 -0
- wl_cli/utils/config/config_loader.py +163 -0
- wl_cli/utils/config/core.py +862 -0
- wl_cli/utils/config/defaults.py +142 -0
- wl_cli/utils/config/env_exporter.py +86 -0
- wl_cli/utils/config/env_parser.py +108 -0
- wl_cli/utils/config/validation.py +280 -0
- wl_cli/utils/error_handler.py +165 -0
- wl_cli/utils/file_copier.py +56 -0
- wl_cli/utils/file_operations.py +506 -0
- wl_cli/utils/language_utils.py +122 -0
- wl_cli/utils/lazy_import.py +240 -0
- wl_cli/utils/log_levels.py +35 -0
- wl_cli/utils/log_rotators.py +74 -0
- wl_cli/utils/logging.py +458 -0
- wl_cli/utils/output_context.py +142 -0
- wl_cli/utils/performance/__init__.py +1 -0
- wl_cli/utils/performance/decorators.py +111 -0
- wl_cli/utils/performance/exporter.py +38 -0
- wl_cli/utils/performance/models.py +16 -0
- wl_cli/utils/performance/monitor.py +161 -0
- wl_cli/utils/performance_monitor.py +32 -0
- wl_cli/utils/platform_adapter.py +131 -0
- wl_cli/utils/pre_commit.py +266 -0
- wl_cli/utils/pre_commit_config.py +72 -0
- wl_cli/utils/root.py +521 -0
- wl_cli/utils/root_fallback.py +256 -0
- wl_cli/utils/run_evidence.py +236 -0
- wl_cli/utils/structured_logger.py +18 -0
- wl_cli/utils/structured_logging/__init__.py +19 -0
- wl_cli/utils/structured_logging/config.py +337 -0
- wl_cli/utils/structured_logging/core.py +177 -0
- wl_cli/utils/structured_logging/env.py +56 -0
- wl_cli/utils/structured_logging/filtering.py +75 -0
- wl_cli/utils/structured_logging/filters.py +55 -0
- wl_cli/utils/structured_logging/formatters.py +251 -0
- wl_cli/utils/structured_logging/handlers.py +308 -0
- wl_cli/utils/structured_logging/logger.py +354 -0
- wl_cli/utils/subprocess.py +71 -0
- wl_cli/utils/subprocess_utils.py +260 -0
- wl_cli/utils/test_utils/__init__.py +5 -0
- wl_cli/utils/test_utils/test_filter.py +36 -0
- wl_cli/utils/uv_run.py +79 -0
- wl_cli/utils/uv_tool.py +117 -0
- wl_cli/utils/uv_tree.py +71 -0
- wl_cli/utils/uv_workspace.py +174 -0
- wl_cli/utils/version/__init__.py +15 -0
- wl_cli/utils/version/pypi_version_checker.py +95 -0
- wl_cli/utils/version/version_comparator.py +133 -0
- wl_cli/utils/version/version_detectors.py +312 -0
- wl_cli/utils/version/version_service.py +131 -0
- wl_cli/utils/version/version_updater.py +198 -0
- wl_cli/utils/wl_dir_updater.py +1440 -0
- wl_cli/utils/workspace_detector/__init__.py +28 -0
- wl_cli/utils/workspace_detector/core.py +161 -0
- wl_cli/utils/workspace_detector/detection_strategies.py +107 -0
- wl_cli/utils/workspace_detector/exceptions.py +5 -0
- wl_cli/utils/workspace_detector/types.py +17 -0
- wl_cli/utils/workspace_detector/venv_resolver.py +84 -0
- wl_cli/vendors/config/.codespellrc +2 -0
- wl_cli/vendors/config/dependencies.toml +10 -0
- wl_cli/vendors/config/mypy.ini +62 -0
- wl_cli/vendors/config/pyproject_defaults.toml +28 -0
- wl_cli/vendors/config/template_config.toml +24 -0
- wl_cli/vendors/config/tool_configs.toml +76 -0
- wl_cli/vendors/git/.gitignore +122 -0
- wl_cli/vendors/git/.pre-commit-config.yaml +37 -0
- wl_cli/vendors/hooks/applypatch-msg.sample +15 -0
- wl_cli/vendors/hooks/commit-msg.sample +24 -0
- wl_cli/vendors/hooks/fsmonitor-watchman.sample +174 -0
- wl_cli/vendors/hooks/post-update.sample +8 -0
- wl_cli/vendors/hooks/pre-applypatch.sample +14 -0
- wl_cli/vendors/hooks/pre-commit +45 -0
- wl_cli/vendors/hooks/pre-commit.legacy +31 -0
- wl_cli/vendors/hooks/pre-commit.sample +49 -0
- wl_cli/vendors/hooks/pre-merge-commit.sample +13 -0
- wl_cli/vendors/hooks/pre-push.sample +60 -0
- wl_cli/vendors/hooks/pre-rebase.sample +169 -0
- wl_cli/vendors/hooks/pre-receive.sample +24 -0
- wl_cli/vendors/hooks/prepare-commit-msg.sample +42 -0
- wl_cli/vendors/hooks/push-to-checkout.sample +78 -0
- wl_cli/vendors/hooks/sendemail-validate.sample +77 -0
- wl_cli/vendors/hooks/unix/applypatch-msg.sample +15 -0
- wl_cli/vendors/hooks/unix/check_lockfile.py +58 -0
- wl_cli/vendors/hooks/unix/check_lockfile.sh +36 -0
- wl_cli/vendors/hooks/unix/commit-msg.sample +24 -0
- wl_cli/vendors/hooks/unix/fsmonitor-watchman.sample +174 -0
- wl_cli/vendors/hooks/unix/post-update.sample +8 -0
- wl_cli/vendors/hooks/unix/pre-applypatch.sample +14 -0
- wl_cli/vendors/hooks/unix/pre-commit +190 -0
- wl_cli/vendors/hooks/unix/pre-commit.legacy +31 -0
- wl_cli/vendors/hooks/unix/pre-commit.py +81 -0
- wl_cli/vendors/hooks/unix/pre-commit.sample +49 -0
- wl_cli/vendors/hooks/unix/pre-merge-commit.sample +13 -0
- wl_cli/vendors/hooks/unix/pre-push +417 -0
- wl_cli/vendors/hooks/unix/pre-push.sample +53 -0
- wl_cli/vendors/hooks/unix/pre-rebase.sample +169 -0
- wl_cli/vendors/hooks/unix/pre-receive.sample +24 -0
- wl_cli/vendors/hooks/unix/prepare-commit-msg.sample +42 -0
- wl_cli/vendors/hooks/update.sample +128 -0
- wl_cli/vendors/hooks/win/work.bat +63 -0
- wl_cli/vendors/project/.gitignore +90 -0
- wl_cli/vendors/project/.python-version +1 -0
- wl_cli/vendors/project/LICENSE +21 -0
- wl_cli/vendors/project/README.md +0 -0
- wl_cli/vendors/project/pyproject.toml +27 -0
- wl_cli/vendors/project/pyproject_no_workspace.toml +16 -0
- wl_cli/vendors/project/pyproject_workspace.toml +14 -0
- wl_cli/vendors/readme/README.md +120 -0
- wl_cli/vendors/rust/Cargo.toml +14 -0
- wl_cli/vendors/rust/lib/__init__.py +3 -0
- wl_cli/vendors/rust/lib/rust_utils.py +31 -0
- wl_cli/vendors/rust/src/lib.rs +13 -0
- wl_cli/vendors/rust/src/main.rs +3 -0
- wl_cli/vendors/rust/tests/test_rust_fallback.py +40 -0
- wl_cli/vendors/sop_doc/git-dev-sop.md +220 -0
- wl_cli/vendors/sop_doc/industrial-standard-sop.md +145 -0
- wl_cli/vendors/sop_doc/python-sop.md +342 -0
- wl_cli/vendors/sop_doc/rust-readme.md +219 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Clean command utilities package
|
|
3
|
+
|
|
4
|
+
Note: This package is kept for backward compatibility.
|
|
5
|
+
New code should import directly from the modules at the clean package level:
|
|
6
|
+
- wl_cli.commands.clean.core
|
|
7
|
+
- wl_cli.commands.clean.python
|
|
8
|
+
- wl_cli.commands.clean.rust
|
|
9
|
+
- wl_cli.commands.clean.venv
|
|
10
|
+
- wl_cli.commands.clean.build
|
|
11
|
+
- wl_cli.commands.clean.lfs
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from ..core import remove_directories, remove_files
|
|
15
|
+
from ..python import remove_egg_info_dirs, remove_log_files, remove_pycache_dirs
|
|
16
|
+
from ..rust import clean_rust_artifacts, remove_rust_analyzer_dirs
|
|
17
|
+
from ..venv import (
|
|
18
|
+
remove_auto_activation_scripts,
|
|
19
|
+
remove_uv_lock,
|
|
20
|
+
remove_virtual_environments,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"remove_directories",
|
|
25
|
+
"remove_files",
|
|
26
|
+
"remove_log_files",
|
|
27
|
+
"remove_pycache_dirs",
|
|
28
|
+
"remove_egg_info_dirs",
|
|
29
|
+
"remove_rust_analyzer_dirs",
|
|
30
|
+
"clean_rust_artifacts",
|
|
31
|
+
"remove_virtual_environments",
|
|
32
|
+
"remove_auto_activation_scripts",
|
|
33
|
+
"remove_uv_lock",
|
|
34
|
+
]
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Virtual environment cleaning utilities for clean command.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import shutil
|
|
7
|
+
|
|
8
|
+
from wl_cli.utils.logging import log_info_pair
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def remove_virtual_environments(dry_run: bool = False) -> None:
|
|
12
|
+
"""
|
|
13
|
+
Remove virtual environments
|
|
14
|
+
删除虚拟环境
|
|
15
|
+
"""
|
|
16
|
+
venv_dirs = [".venv", "venv"]
|
|
17
|
+
for venv_dir in venv_dirs:
|
|
18
|
+
if os.path.exists(venv_dir):
|
|
19
|
+
try:
|
|
20
|
+
if dry_run:
|
|
21
|
+
log_info_pair(
|
|
22
|
+
f"Would remove virtual environment directory: {venv_dir}",
|
|
23
|
+
f"将删除虚拟环境目录: {venv_dir}",
|
|
24
|
+
)
|
|
25
|
+
else:
|
|
26
|
+
shutil.rmtree(venv_dir)
|
|
27
|
+
log_info_pair(
|
|
28
|
+
f"Removed virtual environment directory: {venv_dir}",
|
|
29
|
+
f"已删除虚拟环境目录: {venv_dir}",
|
|
30
|
+
)
|
|
31
|
+
except Exception as e:
|
|
32
|
+
log_info_pair(
|
|
33
|
+
f"Failed to remove virtual environment {venv_dir}: {e}",
|
|
34
|
+
f"删除虚拟环境 {venv_dir} 失败: {e}",
|
|
35
|
+
)
|
|
36
|
+
else:
|
|
37
|
+
log_info_pair(
|
|
38
|
+
f"Virtual environment directory {venv_dir} does not exist, skipping...",
|
|
39
|
+
f"虚拟环境目录 {venv_dir} 不存在,跳过...",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def remove_auto_activation_scripts(dry_run: bool = False) -> None:
|
|
44
|
+
"""
|
|
45
|
+
Remove auto-activation scripts
|
|
46
|
+
删除自动激活脚本
|
|
47
|
+
"""
|
|
48
|
+
auto_activate_scripts = ["auto_activate_venv.bat", "auto_activate_venv.sh"]
|
|
49
|
+
for script in auto_activate_scripts:
|
|
50
|
+
if os.path.exists(script):
|
|
51
|
+
try:
|
|
52
|
+
if dry_run:
|
|
53
|
+
log_info_pair(
|
|
54
|
+
f"Would remove auto-activation script: {script}",
|
|
55
|
+
f"将删除自动激活脚本: {script}",
|
|
56
|
+
)
|
|
57
|
+
else:
|
|
58
|
+
os.remove(script)
|
|
59
|
+
log_info_pair(
|
|
60
|
+
f"Removed auto-activation script: {script}",
|
|
61
|
+
f"已删除自动激活脚本: {script}",
|
|
62
|
+
)
|
|
63
|
+
except Exception as e:
|
|
64
|
+
log_info_pair(
|
|
65
|
+
f"Failed to remove auto-activation script {script}: {e}",
|
|
66
|
+
f"删除自动激活脚本 {script} 失败: {e}",
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def remove_uv_lock(dry_run: bool = False) -> None:
|
|
71
|
+
"""
|
|
72
|
+
Remove uv.lock file
|
|
73
|
+
删除uv.lock文件
|
|
74
|
+
"""
|
|
75
|
+
uv_lock_file = "uv.lock"
|
|
76
|
+
if os.path.exists(uv_lock_file):
|
|
77
|
+
try:
|
|
78
|
+
if dry_run:
|
|
79
|
+
log_info_pair(
|
|
80
|
+
f"Would remove {uv_lock_file} file", f"将删除 {uv_lock_file} 文件"
|
|
81
|
+
)
|
|
82
|
+
else:
|
|
83
|
+
os.remove(uv_lock_file)
|
|
84
|
+
log_info_pair(
|
|
85
|
+
f"Removed {uv_lock_file} file", f"已删除 {uv_lock_file} 文件"
|
|
86
|
+
)
|
|
87
|
+
except Exception as e:
|
|
88
|
+
log_info_pair(
|
|
89
|
+
f"Failed to remove {uv_lock_file} file: {e}",
|
|
90
|
+
f"删除 {uv_lock_file} 文件失败: {e}",
|
|
91
|
+
)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"""Shortcut command for dead code cleanup."""
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Any, cast
|
|
5
|
+
|
|
6
|
+
import click
|
|
7
|
+
|
|
8
|
+
from wl_cli.commands import Command, validate_command_args
|
|
9
|
+
from wl_cli.commands.clean.dead_code.dead_code_command import DeadCodeCommand
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class CleanupCommand(Command):
|
|
13
|
+
"""Run dead code cleanup."""
|
|
14
|
+
|
|
15
|
+
@property
|
|
16
|
+
def name(self) -> str:
|
|
17
|
+
return "cleanup"
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def help(self) -> str:
|
|
21
|
+
return "Run dead-code cleanup"
|
|
22
|
+
|
|
23
|
+
@validate_command_args()
|
|
24
|
+
def execute(
|
|
25
|
+
self,
|
|
26
|
+
dry_run: bool = False,
|
|
27
|
+
scan_only: bool = False,
|
|
28
|
+
json: bool = False,
|
|
29
|
+
**kwargs: Any,
|
|
30
|
+
) -> int:
|
|
31
|
+
_ = kwargs
|
|
32
|
+
command = DeadCodeCommand()
|
|
33
|
+
scan_without_fixing = dry_run or scan_only
|
|
34
|
+
|
|
35
|
+
return cast(
|
|
36
|
+
"int",
|
|
37
|
+
command.run(
|
|
38
|
+
dry_run=scan_without_fixing,
|
|
39
|
+
json=json,
|
|
40
|
+
),
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@click.command()
|
|
45
|
+
@click.option(
|
|
46
|
+
"--dry-run",
|
|
47
|
+
is_flag=True,
|
|
48
|
+
help="Only scan without fixing",
|
|
49
|
+
)
|
|
50
|
+
@click.option(
|
|
51
|
+
"--scan-only",
|
|
52
|
+
is_flag=True,
|
|
53
|
+
help="Same as --dry-run",
|
|
54
|
+
)
|
|
55
|
+
@click.option(
|
|
56
|
+
"--json",
|
|
57
|
+
is_flag=True,
|
|
58
|
+
help="Output JSON format",
|
|
59
|
+
)
|
|
60
|
+
def cleanup_command(
|
|
61
|
+
dry_run: bool,
|
|
62
|
+
scan_only: bool,
|
|
63
|
+
json: bool,
|
|
64
|
+
) -> None:
|
|
65
|
+
"""Cleanup command Click wrapper."""
|
|
66
|
+
cmd = CleanupCommand()
|
|
67
|
+
result = cmd.execute(
|
|
68
|
+
dry_run=dry_run,
|
|
69
|
+
scan_only=scan_only,
|
|
70
|
+
json=json,
|
|
71
|
+
)
|
|
72
|
+
if result:
|
|
73
|
+
sys.exit(result)
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""Click-based command base class for WL Commands."""
|
|
2
|
+
|
|
3
|
+
from abc import ABC, abstractmethod
|
|
4
|
+
from typing import Any
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ClickCommandBase(ABC):
|
|
8
|
+
"""Pure Click-style command base class.
|
|
9
|
+
|
|
10
|
+
Replaces argparse-style CommandBase with Click-native decorator pattern.
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
def __init__(self, **dependencies: Any) -> None:
|
|
14
|
+
"""Initialize the command with dependencies.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
**dependencies: Dependencies for the command
|
|
18
|
+
"""
|
|
19
|
+
self._dependencies = dependencies
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
@abstractmethod
|
|
23
|
+
def name(self) -> str:
|
|
24
|
+
"""Get the command name."""
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
@property
|
|
28
|
+
def help(self) -> str:
|
|
29
|
+
"""Get the command help text."""
|
|
30
|
+
return f"{self.name} command"
|
|
31
|
+
|
|
32
|
+
@property
|
|
33
|
+
def aliases(self) -> list[str]:
|
|
34
|
+
"""Get command aliases."""
|
|
35
|
+
return []
|
|
36
|
+
|
|
37
|
+
@abstractmethod
|
|
38
|
+
def execute(self, **kwargs: Any) -> None:
|
|
39
|
+
"""Execute the command with Click-passed kwargs."""
|
|
40
|
+
pass
|
|
41
|
+
|
|
42
|
+
def before_execute(self, **kwargs: Any) -> None:
|
|
43
|
+
"""Lifecycle hook called before execution."""
|
|
44
|
+
return None
|
|
45
|
+
|
|
46
|
+
def after_execute(self, result: Any = None) -> None:
|
|
47
|
+
"""Lifecycle hook called after execution."""
|
|
48
|
+
return None
|
|
49
|
+
|
|
50
|
+
def run(self, **kwargs: Any) -> Any:
|
|
51
|
+
"""Run with lifecycle and error handling around execute."""
|
|
52
|
+
try:
|
|
53
|
+
validated_kwargs = self.validate_args(**kwargs)
|
|
54
|
+
self.before_execute(**validated_kwargs)
|
|
55
|
+
result = self.execute(**validated_kwargs)
|
|
56
|
+
self.after_execute(result)
|
|
57
|
+
return result
|
|
58
|
+
except Exception as error:
|
|
59
|
+
self.handle_error(error)
|
|
60
|
+
raise
|
|
61
|
+
|
|
62
|
+
def validate_args(self, **kwargs: Any) -> dict[str, Any]:
|
|
63
|
+
"""Validate command arguments."""
|
|
64
|
+
return kwargs
|
|
65
|
+
|
|
66
|
+
def handle_error(self, error: Exception) -> None:
|
|
67
|
+
"""Default error handler; override for custom behavior."""
|
|
68
|
+
raise error
|
|
69
|
+
|
|
70
|
+
def log_info(self, en_msg: str, zh_msg: str | None = None) -> None:
|
|
71
|
+
"""Log messages in English and optionally Chinese."""
|
|
72
|
+
try:
|
|
73
|
+
from wl_cli.utils.logging import log_info
|
|
74
|
+
|
|
75
|
+
log_info(en_msg, lang="en")
|
|
76
|
+
if zh_msg is not None:
|
|
77
|
+
log_info(zh_msg, lang="zh")
|
|
78
|
+
except Exception:
|
|
79
|
+
pass
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Config commands package."""
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
"""Config command using Click decorators.
|
|
2
|
+
|
|
3
|
+
Examples:
|
|
4
|
+
wl config list
|
|
5
|
+
wl config get log_level
|
|
6
|
+
wl config set log_level DEBUG
|
|
7
|
+
wl config set log_console true
|
|
8
|
+
wl config set language en # Only show English messages
|
|
9
|
+
wl config set language zh # Only show Chinese messages
|
|
10
|
+
wl config set language auto # Show messages based on system language (default)
|
|
11
|
+
wl config log get log_level
|
|
12
|
+
wl config log set log_level DEBUG
|
|
13
|
+
wl config log list
|
|
14
|
+
wl config log reset
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
import click
|
|
18
|
+
|
|
19
|
+
from ...utils.config import get_config_manager
|
|
20
|
+
from ...utils.config.defaults import RUNTIME_DERIVED_KEYS
|
|
21
|
+
from ...utils.logging import log_error_pair
|
|
22
|
+
|
|
23
|
+
# CLI usage errors (``click.UsageError``, exit code 2) are deliberately
|
|
24
|
+
# English-only, whatever the ``language`` setting says (#198). Click frames
|
|
25
|
+
# them with its own English ``Usage:``/``Error:`` text, they are consumed by
|
|
26
|
+
# scripts and terminals rather than by a reader, and Click's built-in errors
|
|
27
|
+
# (unknown option, missing argument) are English too -- translating only the
|
|
28
|
+
# messages below would leave a mixed-language error page. Operational
|
|
29
|
+
# failures that carry advice still go through ``log_error_pair`` (see the
|
|
30
|
+
# save-failure path), which honours ``WL_LANGUAGE``.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class ConfigCommand:
|
|
34
|
+
"""Implementation of the config command."""
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def name(self) -> str:
|
|
38
|
+
return "config"
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def help(self) -> str:
|
|
42
|
+
return "Manage wl configuration"
|
|
43
|
+
|
|
44
|
+
def _handle_get_action(self, config_manager, key: str | None):
|
|
45
|
+
"""Handle the 'get' action."""
|
|
46
|
+
if not key:
|
|
47
|
+
# A validation failure is a failed command: click.UsageError exits
|
|
48
|
+
# non-zero and writes the message to stderr, like the save-failure
|
|
49
|
+
# path below (#194).
|
|
50
|
+
raise click.UsageError("key is required for get action")
|
|
51
|
+
|
|
52
|
+
value = config_manager.get(key)
|
|
53
|
+
if value is not None:
|
|
54
|
+
print(f"{key} = {value}")
|
|
55
|
+
else:
|
|
56
|
+
print(f"{key} is not set")
|
|
57
|
+
|
|
58
|
+
def _handle_set_action(self, config_manager, key: str | None, value: str | None):
|
|
59
|
+
"""Handle the 'set' action."""
|
|
60
|
+
if not key or value is None:
|
|
61
|
+
raise click.UsageError("both key and value are required for set action")
|
|
62
|
+
|
|
63
|
+
if key == "language" and value not in ["en", "zh", "auto"]:
|
|
64
|
+
raise click.UsageError("language must be one of 'en', 'zh', or 'auto'")
|
|
65
|
+
|
|
66
|
+
converted_value = self._convert_value(value)
|
|
67
|
+
if not config_manager.set(key, converted_value):
|
|
68
|
+
# A failed write is a failed command: report it in both languages and
|
|
69
|
+
# exit non-zero instead of claiming "Set ..." (#177).
|
|
70
|
+
log_error_pair(
|
|
71
|
+
f"Failed to save configuration '{key}' to {config_manager.config_file}",
|
|
72
|
+
f"无法将配置 '{key}' 保存到 {config_manager.config_file}",
|
|
73
|
+
)
|
|
74
|
+
raise SystemExit(1)
|
|
75
|
+
print(f"Set {key} = {converted_value}")
|
|
76
|
+
|
|
77
|
+
def _handle_list_action(self, config_manager):
|
|
78
|
+
"""Handle the 'list' action."""
|
|
79
|
+
all_config = config_manager.get_all()
|
|
80
|
+
if all_config:
|
|
81
|
+
print("Current configuration:")
|
|
82
|
+
for k, v in all_config.items():
|
|
83
|
+
print(f" {k} = {v}")
|
|
84
|
+
else:
|
|
85
|
+
print("No configuration values set")
|
|
86
|
+
|
|
87
|
+
def _handle_reset_action(self, config_manager):
|
|
88
|
+
"""Handle the 'reset' action.
|
|
89
|
+
|
|
90
|
+
Runtime-derived keys are *removed*, not reset to their default: the
|
|
91
|
+
default is a derivation of the running process, and writing it back
|
|
92
|
+
would re-freeze the value #208 keeps out of the file (#208).
|
|
93
|
+
"""
|
|
94
|
+
default_config = config_manager._get_default_config()
|
|
95
|
+
saved = True
|
|
96
|
+
for key in config_manager.get_all():
|
|
97
|
+
if key not in default_config:
|
|
98
|
+
saved = config_manager.set(key, None) and saved
|
|
99
|
+
|
|
100
|
+
for key, value in default_config.items():
|
|
101
|
+
if key in RUNTIME_DERIVED_KEYS:
|
|
102
|
+
continue
|
|
103
|
+
saved = config_manager.set(key, value) and saved
|
|
104
|
+
|
|
105
|
+
for key in sorted(RUNTIME_DERIVED_KEYS):
|
|
106
|
+
saved = config_manager.unset(key) and saved
|
|
107
|
+
|
|
108
|
+
if not saved:
|
|
109
|
+
log_error_pair(
|
|
110
|
+
"Failed to reset configuration: some values could not be saved",
|
|
111
|
+
"重置配置失败:部分配置值无法保存",
|
|
112
|
+
)
|
|
113
|
+
raise SystemExit(1)
|
|
114
|
+
|
|
115
|
+
print("Configuration reset to default values")
|
|
116
|
+
|
|
117
|
+
def _handle_log_list_action(self, config_manager):
|
|
118
|
+
"""Handle the 'log list' action."""
|
|
119
|
+
all_config = config_manager.get_all()
|
|
120
|
+
log_config = {k: v for k, v in all_config.items() if k.startswith("log_")}
|
|
121
|
+
if log_config:
|
|
122
|
+
print("Current log configuration:")
|
|
123
|
+
for k, v in log_config.items():
|
|
124
|
+
print(f" {k} = {v}")
|
|
125
|
+
else:
|
|
126
|
+
print("No log configuration values set")
|
|
127
|
+
|
|
128
|
+
def _handle_log_reset_action(self, config_manager):
|
|
129
|
+
"""Handle the 'log reset' action."""
|
|
130
|
+
default_config = config_manager._get_default_config()
|
|
131
|
+
saved = True
|
|
132
|
+
for key in config_manager.get_all():
|
|
133
|
+
if key.startswith("log_") and key not in default_config:
|
|
134
|
+
saved = config_manager.set(key, None) and saved
|
|
135
|
+
|
|
136
|
+
for key, value in default_config.items():
|
|
137
|
+
if key.startswith("log_"):
|
|
138
|
+
saved = config_manager.set(key, value) and saved
|
|
139
|
+
|
|
140
|
+
if not saved:
|
|
141
|
+
log_error_pair(
|
|
142
|
+
"Failed to reset log configuration: some values could not be saved",
|
|
143
|
+
"重置日志配置失败:部分配置值无法保存",
|
|
144
|
+
)
|
|
145
|
+
raise SystemExit(1)
|
|
146
|
+
|
|
147
|
+
print("Log configuration reset to default values")
|
|
148
|
+
|
|
149
|
+
def _convert_value(self, value: str):
|
|
150
|
+
"""Convert string value to appropriate type."""
|
|
151
|
+
if value.lower() in ("none", "null"):
|
|
152
|
+
return None
|
|
153
|
+
|
|
154
|
+
if value.lower() in ("true", "false"):
|
|
155
|
+
return value.lower() == "true"
|
|
156
|
+
|
|
157
|
+
try:
|
|
158
|
+
return int(value)
|
|
159
|
+
except ValueError:
|
|
160
|
+
pass
|
|
161
|
+
|
|
162
|
+
try:
|
|
163
|
+
return float(value)
|
|
164
|
+
except ValueError:
|
|
165
|
+
pass
|
|
166
|
+
|
|
167
|
+
return value
|
|
168
|
+
|
|
169
|
+
def execute(
|
|
170
|
+
self,
|
|
171
|
+
config_action: str | None = None,
|
|
172
|
+
key: str | None = None,
|
|
173
|
+
value: str | None = None,
|
|
174
|
+
log_action: str | None = None,
|
|
175
|
+
**kwargs,
|
|
176
|
+
) -> None:
|
|
177
|
+
"""Execute config command."""
|
|
178
|
+
config_manager = get_config_manager()
|
|
179
|
+
|
|
180
|
+
if config_action == "get":
|
|
181
|
+
self._handle_get_action(config_manager, key)
|
|
182
|
+
|
|
183
|
+
elif config_action == "set":
|
|
184
|
+
self._handle_set_action(config_manager, key, value)
|
|
185
|
+
|
|
186
|
+
elif config_action == "list":
|
|
187
|
+
self._handle_list_action(config_manager)
|
|
188
|
+
|
|
189
|
+
elif config_action == "reset":
|
|
190
|
+
self._handle_reset_action(config_manager)
|
|
191
|
+
|
|
192
|
+
elif config_action == "log_list":
|
|
193
|
+
self._handle_log_list_action(config_manager)
|
|
194
|
+
|
|
195
|
+
elif config_action == "log_reset":
|
|
196
|
+
self._handle_log_reset_action(config_manager)
|
|
197
|
+
|
|
198
|
+
elif config_action == "log":
|
|
199
|
+
if log_action == "get":
|
|
200
|
+
self._handle_get_action(config_manager, key)
|
|
201
|
+
elif log_action == "set":
|
|
202
|
+
self._handle_set_action(config_manager, key, value)
|
|
203
|
+
elif log_action == "list":
|
|
204
|
+
self._handle_log_list_action(config_manager)
|
|
205
|
+
elif log_action == "reset":
|
|
206
|
+
self._handle_log_reset_action(config_manager)
|
|
207
|
+
else:
|
|
208
|
+
# Unreachable through Click: no subcommand passes a "log"
|
|
209
|
+
# config_action any more. Raised rather than printed into a
|
|
210
|
+
# wide-open exit 0, which would report failure as success
|
|
211
|
+
# (#198).
|
|
212
|
+
raise AssertionError(
|
|
213
|
+
f"unreachable log action branch: log_action={log_action!r}"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
else:
|
|
217
|
+
# Unreachable through Click: every subcommand passes one of the
|
|
218
|
+
# actions handled above. Same reasoning as the log branch (#198).
|
|
219
|
+
raise AssertionError(
|
|
220
|
+
f"unreachable config action branch: config_action={config_action!r}"
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
@click.group()
|
|
225
|
+
def config_command():
|
|
226
|
+
"""Manage wl configuration."""
|
|
227
|
+
pass
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@config_command.command()
|
|
231
|
+
@click.argument("key")
|
|
232
|
+
def get(key: str):
|
|
233
|
+
"""Get a configuration value."""
|
|
234
|
+
cmd = ConfigCommand()
|
|
235
|
+
cmd.execute(config_action="get", key=key)
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
@config_command.command()
|
|
239
|
+
@click.argument("key")
|
|
240
|
+
@click.argument("value")
|
|
241
|
+
def set(key: str, value: str):
|
|
242
|
+
"""Set a configuration value."""
|
|
243
|
+
cmd = ConfigCommand()
|
|
244
|
+
cmd.execute(config_action="set", key=key, value=value)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@config_command.command(name="list-config")
|
|
248
|
+
@click.pass_context
|
|
249
|
+
def list_config(ctx: click.Context):
|
|
250
|
+
"""List all configuration values."""
|
|
251
|
+
cmd = ConfigCommand()
|
|
252
|
+
cmd.execute(config_action="list")
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
@config_command.command()
|
|
256
|
+
@click.pass_context
|
|
257
|
+
def reset(ctx: click.Context):
|
|
258
|
+
"""Reset configuration to default values."""
|
|
259
|
+
cmd = ConfigCommand()
|
|
260
|
+
cmd.execute(config_action="reset")
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@config_command.command()
|
|
264
|
+
@click.argument("key")
|
|
265
|
+
def log_get(key: str):
|
|
266
|
+
"""Get a log configuration value."""
|
|
267
|
+
cmd = ConfigCommand()
|
|
268
|
+
cmd.execute(config_action="get", key=key)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
@config_command.command()
|
|
272
|
+
@click.argument("key")
|
|
273
|
+
@click.argument("value")
|
|
274
|
+
def log_set(key: str, value: str):
|
|
275
|
+
"""Set a log configuration value."""
|
|
276
|
+
cmd = ConfigCommand()
|
|
277
|
+
cmd.execute(config_action="set", key=key, value=value)
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
@config_command.command(name="log-list")
|
|
281
|
+
def log_list():
|
|
282
|
+
"""List all log configuration values."""
|
|
283
|
+
cmd = ConfigCommand()
|
|
284
|
+
cmd.execute(config_action="log_list")
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
@config_command.command(name="log-reset")
|
|
288
|
+
def log_reset():
|
|
289
|
+
"""Reset log configuration to default values."""
|
|
290
|
+
cmd = ConfigCommand()
|
|
291
|
+
cmd.execute(config_action="log_reset")
|