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.
Files changed (320) hide show
  1. py_wlcli-0.8.0.dist-info/METADATA +139 -0
  2. py_wlcli-0.8.0.dist-info/RECORD +320 -0
  3. py_wlcli-0.8.0.dist-info/WHEEL +4 -0
  4. py_wlcli-0.8.0.dist-info/entry_points.txt +2 -0
  5. py_wlcli-0.8.0.dist-info/licenses/LICENSE +21 -0
  6. wl_cli/__init__.py +27 -0
  7. wl_cli/__main__.py +130 -0
  8. wl_cli/capabilities.py +79 -0
  9. wl_cli/cc/__init__.py +5 -0
  10. wl_cli/cc/checks.py +1019 -0
  11. wl_cli/cc/cli.py +370 -0
  12. wl_cli/cc/mutate.py +1350 -0
  13. wl_cli/cli_click.py +156 -0
  14. wl_cli/commands/__init__.py +84 -0
  15. wl_cli/commands/base.py +80 -0
  16. wl_cli/commands/buildcommands/__init__.py +1 -0
  17. wl_cli/commands/buildcommands/build.py +71 -0
  18. wl_cli/commands/buildcommands/build_utils.py +47 -0
  19. wl_cli/commands/buildcommands/builders/__init__.py +18 -0
  20. wl_cli/commands/buildcommands/builders/cleanup.py +35 -0
  21. wl_cli/commands/buildcommands/builders/coordinator.py +122 -0
  22. wl_cli/commands/buildcommands/builders/environment.py +81 -0
  23. wl_cli/commands/buildcommands/builders/rust_builder.py +39 -0
  24. wl_cli/commands/buildcommands/builders/stubs.py +58 -0
  25. wl_cli/commands/buildcommands/dist.py +326 -0
  26. wl_cli/commands/buildcommands/test.py +89 -0
  27. wl_cli/commands/clean/__init__.py +1 -0
  28. wl_cli/commands/clean/build.py +151 -0
  29. wl_cli/commands/clean/clean.py +294 -0
  30. wl_cli/commands/clean/clean_utils.py +77 -0
  31. wl_cli/commands/clean/core.py +236 -0
  32. wl_cli/commands/clean/dead_code/__init__.py +0 -0
  33. wl_cli/commands/clean/dead_code/dead_code_command.py +70 -0
  34. wl_cli/commands/clean/dead_code/detector.py +161 -0
  35. wl_cli/commands/clean/dead_code/fixer.py +176 -0
  36. wl_cli/commands/clean/dead_code/reporter.py +295 -0
  37. wl_cli/commands/clean/dead_code/utils.py +0 -0
  38. wl_cli/commands/clean/lfs.py +215 -0
  39. wl_cli/commands/clean/python.py +81 -0
  40. wl_cli/commands/clean/rust.py +91 -0
  41. wl_cli/commands/clean/utils/__init__.py +34 -0
  42. wl_cli/commands/clean/venv.py +91 -0
  43. wl_cli/commands/cleanup.py +73 -0
  44. wl_cli/commands/click_base.py +79 -0
  45. wl_cli/commands/config/__init__.py +1 -0
  46. wl_cli/commands/config/config.py +291 -0
  47. wl_cli/commands/debug/__init__.py +6 -0
  48. wl_cli/commands/debug/debug.py +309 -0
  49. wl_cli/commands/debug/debug_cache.py +86 -0
  50. wl_cli/commands/debug/debug_subagent.py +156 -0
  51. wl_cli/commands/debug/output_formatter.py +165 -0
  52. wl_cli/commands/debug/source_hasher.py +92 -0
  53. wl_cli/commands/format/__init__.py +13 -0
  54. wl_cli/commands/format/format_cache_adapter.py +125 -0
  55. wl_cli/commands/format/format_command.py +197 -0
  56. wl_cli/commands/format/format_coordinator.py +191 -0
  57. wl_cli/commands/format/format_executor.py +470 -0
  58. wl_cli/commands/format/format_outcome.py +44 -0
  59. wl_cli/commands/format/format_path_handler.py +1016 -0
  60. wl_cli/commands/format/format_progress.py +62 -0
  61. wl_cli/commands/format/format_reporter.py +31 -0
  62. wl_cli/commands/format/python_formatter.py +506 -0
  63. wl_cli/commands/format/rust_formatter.py +106 -0
  64. wl_cli/commands/gate/__init__.py +1 -0
  65. wl_cli/commands/gate/gate_command.py +862 -0
  66. wl_cli/commands/gate/preflight.py +445 -0
  67. wl_cli/commands/git/__init__.py +1 -0
  68. wl_cli/commands/git/config.py +169 -0
  69. wl_cli/commands/git/git_facts.py +60 -0
  70. wl_cli/commands/git/git_flow.py +86 -0
  71. wl_cli/commands/git/hook.py +112 -0
  72. wl_cli/commands/git/policy.py +216 -0
  73. wl_cli/commands/git/push_update.py +82 -0
  74. wl_cli/commands/initenv/__init__.py +1 -0
  75. wl_cli/commands/initenv/common/__init__.py +23 -0
  76. wl_cli/commands/initenv/common/check_git_bash.py +78 -0
  77. wl_cli/commands/initenv/common/error_handler.py +68 -0
  78. wl_cli/commands/initenv/common/exceptions.py +52 -0
  79. wl_cli/commands/initenv/components/__init__.py +4 -0
  80. wl_cli/commands/initenv/components/cargo_sync.py +240 -0
  81. wl_cli/commands/initenv/components/config_manager.py +106 -0
  82. wl_cli/commands/initenv/components/directory_utils.py +71 -0
  83. wl_cli/commands/initenv/components/git/__init__.py +9 -0
  84. wl_cli/commands/initenv/components/git/branch_creator.py +143 -0
  85. wl_cli/commands/initenv/components/git/git_flow_interface.py +24 -0
  86. wl_cli/commands/initenv/components/git/git_flow_manager.py +159 -0
  87. wl_cli/commands/initenv/components/git/git_lfs_manager.py +272 -0
  88. wl_cli/commands/initenv/components/git/git_utility.py +254 -0
  89. wl_cli/commands/initenv/components/git/gitignore_manager.py +53 -0
  90. wl_cli/commands/initenv/components/git_initializer.py +212 -0
  91. wl_cli/commands/initenv/components/i18n_manager.py +104 -0
  92. wl_cli/commands/initenv/components/log_manager.py +241 -0
  93. wl_cli/commands/initenv/components/project_structure/__init__.py +23 -0
  94. wl_cli/commands/initenv/components/project_structure/config_generator.py +360 -0
  95. wl_cli/commands/initenv/components/project_structure/directory_creator.py +184 -0
  96. wl_cli/commands/initenv/components/project_structure/hook_source.py +110 -0
  97. wl_cli/commands/initenv/components/project_structure/hooks_manager.py +995 -0
  98. wl_cli/commands/initenv/components/project_structure/readme_handler.py +56 -0
  99. wl_cli/commands/initenv/components/project_structure/rust_files_handler.py +30 -0
  100. wl_cli/commands/initenv/components/project_structure/setup_handler.py +103 -0
  101. wl_cli/commands/initenv/components/project_structure/sop_generator.py +73 -0
  102. wl_cli/commands/initenv/components/project_structure/template_copier.py +104 -0
  103. wl_cli/commands/initenv/components/project_structure/template_manager.py +195 -0
  104. wl_cli/commands/initenv/components/pyproject_generator.py +194 -0
  105. wl_cli/commands/initenv/components/rust_initializer.py +145 -0
  106. wl_cli/commands/initenv/components/symlink_cleaner.py +99 -0
  107. wl_cli/commands/initenv/components/symlink_manager.py +52 -0
  108. wl_cli/commands/initenv/components/venv_manager.py +118 -0
  109. wl_cli/commands/initenv/initenv.py +169 -0
  110. wl_cli/commands/initenv/services/__init__.py +11 -0
  111. wl_cli/commands/initenv/services/environment_initializer.py +288 -0
  112. wl_cli/commands/initenv/services/git_lfs_initializer.py +26 -0
  113. wl_cli/commands/initenv/services/project_structure_initializer.py +52 -0
  114. wl_cli/commands/lfs/README.md +221 -0
  115. wl_cli/commands/lfs/__init__.py +5 -0
  116. wl_cli/commands/lfs/cli.py +106 -0
  117. wl_cli/commands/lfs/config.py +164 -0
  118. wl_cli/commands/lfs/hook.py +61 -0
  119. wl_cli/commands/lfs/initializer.py +531 -0
  120. wl_cli/commands/lfs/manager.py +95 -0
  121. wl_cli/commands/lfs/policy.py +165 -0
  122. wl_cli/commands/lfs/watcher.py +294 -0
  123. wl_cli/commands/lint/__init__.py +1 -0
  124. wl_cli/commands/lint/lint_command.py +297 -0
  125. wl_cli/commands/lint/lint_executor.py +409 -0
  126. wl_cli/commands/lint/lint_reporter.py +579 -0
  127. wl_cli/commands/lint/lint_run.py +258 -0
  128. wl_cli/commands/lint/mypy_config.py +90 -0
  129. wl_cli/commands/registry.py +103 -0
  130. wl_cli/commands/self/__init__.py +7 -0
  131. wl_cli/commands/self/common/__init__.py +8 -0
  132. wl_cli/commands/self/common/capabilities.py +30 -0
  133. wl_cli/commands/self/common/config.py +27 -0
  134. wl_cli/commands/self/common/version_cache.py +85 -0
  135. wl_cli/commands/self/handlers/__init__.py +19 -0
  136. wl_cli/commands/self/handlers/base_handler.py +28 -0
  137. wl_cli/commands/self/handlers/install_handler.py +85 -0
  138. wl_cli/commands/self/handlers/status_handler.py +66 -0
  139. wl_cli/commands/self/handlers/uninstall_handler.py +58 -0
  140. wl_cli/commands/self/handlers/update_handler.py +102 -0
  141. wl_cli/commands/self/handlers/version_handler.py +16 -0
  142. wl_cli/commands/self/self_command.py +237 -0
  143. wl_cli/commands/self/services/__init__.py +15 -0
  144. wl_cli/commands/self/services/installation_manager.py +187 -0
  145. wl_cli/commands/self/services/local_installer.py +165 -0
  146. wl_cli/commands/self/services/pypi_updater.py +278 -0
  147. wl_cli/commands/self/services/windows_update.py +174 -0
  148. wl_cli/commands/testcommands/__init__.py +8 -0
  149. wl_cli/commands/testcommands/base_dependency_analyzer.py +198 -0
  150. wl_cli/commands/testcommands/batch_processor.py +278 -0
  151. wl_cli/commands/testcommands/cache_manager.py +1156 -0
  152. wl_cli/commands/testcommands/coverage_analyzer.py +955 -0
  153. wl_cli/commands/testcommands/coverage_cache_manager.py +183 -0
  154. wl_cli/commands/testcommands/progress_manager.py +79 -0
  155. wl_cli/commands/testcommands/python_env_detector.py +207 -0
  156. wl_cli/commands/testcommands/report_generator.py +101 -0
  157. wl_cli/commands/testcommands/single_test_executor.py +250 -0
  158. wl_cli/commands/testcommands/speed_checker.py +118 -0
  159. wl_cli/commands/testcommands/test_command_builder.py +165 -0
  160. wl_cli/commands/testcommands/test_commands.py +786 -0
  161. wl_cli/commands/testcommands/test_reporter.py +181 -0
  162. wl_cli/commands/testcommands/test_result_handler.py +96 -0
  163. wl_cli/commands/testcommands/test_runner.py +1343 -0
  164. wl_cli/commands/testcommands/test_utils.py +197 -0
  165. wl_cli/commands/testcommands/utils/__init__.py +17 -0
  166. wl_cli/commands/testcommands/utils/coverage_parser.py +98 -0
  167. wl_cli/commands/testcommands/utils/env_info.py +36 -0
  168. wl_cli/commands/testcommands/utils/junit_parser.py +75 -0
  169. wl_cli/commands/testcommands/utils/markdown_utils.py +20 -0
  170. wl_cli/commands/testcommands/utils/project_root.py +61 -0
  171. wl_cli/commands/update/__init__.py +9 -0
  172. wl_cli/commands/update/services/__init__.py +21 -0
  173. wl_cli/commands/update/services/backup_manager.py +207 -0
  174. wl_cli/commands/update/services/component_manager.py +83 -0
  175. wl_cli/commands/update/services/conflict_resolver.py +189 -0
  176. wl_cli/commands/update/services/vendors_updater.py +85 -0
  177. wl_cli/commands/update/services/version_tracker.py +127 -0
  178. wl_cli/commands/update/update_command.py +270 -0
  179. wl_cli/commands/update/utils/__init__.py +3 -0
  180. wl_cli/commands/version/__init__.py +9 -0
  181. wl_cli/commands/version/version_command.py +155 -0
  182. wl_cli/commands/workflow.py +477 -0
  183. wl_cli/env/__init__.py +5 -0
  184. wl_cli/env/cli.py +167 -0
  185. wl_cli/env_status.py +157 -0
  186. wl_cli/envelope.py +91 -0
  187. wl_cli/exceptions.py +85 -0
  188. wl_cli/lib/__init__.py +3 -0
  189. wl_cli/lib/rust_utils.py +35 -0
  190. wl_cli/mcp/__init__.py +6 -0
  191. wl_cli/mcp/capabilities.py +19 -0
  192. wl_cli/mcp/cli.py +22 -0
  193. wl_cli/mcp/gitlab.py +553 -0
  194. wl_cli/mcp/k8s.py +344 -0
  195. wl_cli/mcp/protocol.py +159 -0
  196. wl_cli/platform.py +139 -0
  197. wl_cli/quality/__init__.py +18 -0
  198. wl_cli/utils/__init__.py +7 -0
  199. wl_cli/utils/cache.py +491 -0
  200. wl_cli/utils/cache_ledger.py +355 -0
  201. wl_cli/utils/cache_store.py +546 -0
  202. wl_cli/utils/config/__init__.py +27 -0
  203. wl_cli/utils/config/config_loader.py +163 -0
  204. wl_cli/utils/config/core.py +862 -0
  205. wl_cli/utils/config/defaults.py +142 -0
  206. wl_cli/utils/config/env_exporter.py +86 -0
  207. wl_cli/utils/config/env_parser.py +108 -0
  208. wl_cli/utils/config/validation.py +280 -0
  209. wl_cli/utils/error_handler.py +165 -0
  210. wl_cli/utils/file_copier.py +56 -0
  211. wl_cli/utils/file_operations.py +506 -0
  212. wl_cli/utils/language_utils.py +122 -0
  213. wl_cli/utils/lazy_import.py +240 -0
  214. wl_cli/utils/log_levels.py +35 -0
  215. wl_cli/utils/log_rotators.py +74 -0
  216. wl_cli/utils/logging.py +458 -0
  217. wl_cli/utils/output_context.py +142 -0
  218. wl_cli/utils/performance/__init__.py +1 -0
  219. wl_cli/utils/performance/decorators.py +111 -0
  220. wl_cli/utils/performance/exporter.py +38 -0
  221. wl_cli/utils/performance/models.py +16 -0
  222. wl_cli/utils/performance/monitor.py +161 -0
  223. wl_cli/utils/performance_monitor.py +32 -0
  224. wl_cli/utils/platform_adapter.py +131 -0
  225. wl_cli/utils/pre_commit.py +266 -0
  226. wl_cli/utils/pre_commit_config.py +72 -0
  227. wl_cli/utils/root.py +521 -0
  228. wl_cli/utils/root_fallback.py +256 -0
  229. wl_cli/utils/run_evidence.py +236 -0
  230. wl_cli/utils/structured_logger.py +18 -0
  231. wl_cli/utils/structured_logging/__init__.py +19 -0
  232. wl_cli/utils/structured_logging/config.py +337 -0
  233. wl_cli/utils/structured_logging/core.py +177 -0
  234. wl_cli/utils/structured_logging/env.py +56 -0
  235. wl_cli/utils/structured_logging/filtering.py +75 -0
  236. wl_cli/utils/structured_logging/filters.py +55 -0
  237. wl_cli/utils/structured_logging/formatters.py +251 -0
  238. wl_cli/utils/structured_logging/handlers.py +308 -0
  239. wl_cli/utils/structured_logging/logger.py +354 -0
  240. wl_cli/utils/subprocess.py +71 -0
  241. wl_cli/utils/subprocess_utils.py +260 -0
  242. wl_cli/utils/test_utils/__init__.py +5 -0
  243. wl_cli/utils/test_utils/test_filter.py +36 -0
  244. wl_cli/utils/uv_run.py +79 -0
  245. wl_cli/utils/uv_tool.py +117 -0
  246. wl_cli/utils/uv_tree.py +71 -0
  247. wl_cli/utils/uv_workspace.py +174 -0
  248. wl_cli/utils/version/__init__.py +15 -0
  249. wl_cli/utils/version/pypi_version_checker.py +95 -0
  250. wl_cli/utils/version/version_comparator.py +133 -0
  251. wl_cli/utils/version/version_detectors.py +312 -0
  252. wl_cli/utils/version/version_service.py +131 -0
  253. wl_cli/utils/version/version_updater.py +198 -0
  254. wl_cli/utils/wl_dir_updater.py +1440 -0
  255. wl_cli/utils/workspace_detector/__init__.py +28 -0
  256. wl_cli/utils/workspace_detector/core.py +161 -0
  257. wl_cli/utils/workspace_detector/detection_strategies.py +107 -0
  258. wl_cli/utils/workspace_detector/exceptions.py +5 -0
  259. wl_cli/utils/workspace_detector/types.py +17 -0
  260. wl_cli/utils/workspace_detector/venv_resolver.py +84 -0
  261. wl_cli/vendors/config/.codespellrc +2 -0
  262. wl_cli/vendors/config/dependencies.toml +10 -0
  263. wl_cli/vendors/config/mypy.ini +62 -0
  264. wl_cli/vendors/config/pyproject_defaults.toml +28 -0
  265. wl_cli/vendors/config/template_config.toml +24 -0
  266. wl_cli/vendors/config/tool_configs.toml +76 -0
  267. wl_cli/vendors/git/.gitignore +122 -0
  268. wl_cli/vendors/git/.pre-commit-config.yaml +37 -0
  269. wl_cli/vendors/hooks/applypatch-msg.sample +15 -0
  270. wl_cli/vendors/hooks/commit-msg.sample +24 -0
  271. wl_cli/vendors/hooks/fsmonitor-watchman.sample +174 -0
  272. wl_cli/vendors/hooks/post-update.sample +8 -0
  273. wl_cli/vendors/hooks/pre-applypatch.sample +14 -0
  274. wl_cli/vendors/hooks/pre-commit +45 -0
  275. wl_cli/vendors/hooks/pre-commit.legacy +31 -0
  276. wl_cli/vendors/hooks/pre-commit.sample +49 -0
  277. wl_cli/vendors/hooks/pre-merge-commit.sample +13 -0
  278. wl_cli/vendors/hooks/pre-push.sample +60 -0
  279. wl_cli/vendors/hooks/pre-rebase.sample +169 -0
  280. wl_cli/vendors/hooks/pre-receive.sample +24 -0
  281. wl_cli/vendors/hooks/prepare-commit-msg.sample +42 -0
  282. wl_cli/vendors/hooks/push-to-checkout.sample +78 -0
  283. wl_cli/vendors/hooks/sendemail-validate.sample +77 -0
  284. wl_cli/vendors/hooks/unix/applypatch-msg.sample +15 -0
  285. wl_cli/vendors/hooks/unix/check_lockfile.py +58 -0
  286. wl_cli/vendors/hooks/unix/check_lockfile.sh +36 -0
  287. wl_cli/vendors/hooks/unix/commit-msg.sample +24 -0
  288. wl_cli/vendors/hooks/unix/fsmonitor-watchman.sample +174 -0
  289. wl_cli/vendors/hooks/unix/post-update.sample +8 -0
  290. wl_cli/vendors/hooks/unix/pre-applypatch.sample +14 -0
  291. wl_cli/vendors/hooks/unix/pre-commit +190 -0
  292. wl_cli/vendors/hooks/unix/pre-commit.legacy +31 -0
  293. wl_cli/vendors/hooks/unix/pre-commit.py +81 -0
  294. wl_cli/vendors/hooks/unix/pre-commit.sample +49 -0
  295. wl_cli/vendors/hooks/unix/pre-merge-commit.sample +13 -0
  296. wl_cli/vendors/hooks/unix/pre-push +417 -0
  297. wl_cli/vendors/hooks/unix/pre-push.sample +53 -0
  298. wl_cli/vendors/hooks/unix/pre-rebase.sample +169 -0
  299. wl_cli/vendors/hooks/unix/pre-receive.sample +24 -0
  300. wl_cli/vendors/hooks/unix/prepare-commit-msg.sample +42 -0
  301. wl_cli/vendors/hooks/update.sample +128 -0
  302. wl_cli/vendors/hooks/win/work.bat +63 -0
  303. wl_cli/vendors/project/.gitignore +90 -0
  304. wl_cli/vendors/project/.python-version +1 -0
  305. wl_cli/vendors/project/LICENSE +21 -0
  306. wl_cli/vendors/project/README.md +0 -0
  307. wl_cli/vendors/project/pyproject.toml +27 -0
  308. wl_cli/vendors/project/pyproject_no_workspace.toml +16 -0
  309. wl_cli/vendors/project/pyproject_workspace.toml +14 -0
  310. wl_cli/vendors/readme/README.md +120 -0
  311. wl_cli/vendors/rust/Cargo.toml +14 -0
  312. wl_cli/vendors/rust/lib/__init__.py +3 -0
  313. wl_cli/vendors/rust/lib/rust_utils.py +31 -0
  314. wl_cli/vendors/rust/src/lib.rs +13 -0
  315. wl_cli/vendors/rust/src/main.rs +3 -0
  316. wl_cli/vendors/rust/tests/test_rust_fallback.py +40 -0
  317. wl_cli/vendors/sop_doc/git-dev-sop.md +220 -0
  318. wl_cli/vendors/sop_doc/industrial-standard-sop.md +145 -0
  319. wl_cli/vendors/sop_doc/python-sop.md +342 -0
  320. 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")
@@ -0,0 +1,6 @@
1
+ """wl-debug command module - code quality validation."""
2
+
3
+ from .debug import DebugCommand, debug_command
4
+ from .debug_subagent import DebugSubagent, ErrorInfo, FixResult
5
+
6
+ __all__ = ["DebugCommand", "debug_command", "DebugSubagent", "ErrorInfo", "FixResult"]