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,270 @@
1
+ """
2
+ Update command group for wl_cli.
3
+
4
+ This module provides the 'wl update' command family.
5
+ """
6
+
7
+ from typing import cast
8
+
9
+ import click
10
+
11
+ from wl_cli.commands.update.services.backup_manager import BackupManager
12
+ from wl_cli.commands.update.services.component_manager import ComponentManager
13
+ from wl_cli.commands.update.services.vendors_updater import VendorsUpdater
14
+ from wl_cli.utils.logging import log_info_pair
15
+ from wl_cli.utils.wl_dir_updater import check_and_update_wl_dir, compare_versions
16
+
17
+ from ...utils.root import RootKind
18
+ from ...utils.root_fallback import current_root
19
+
20
+
21
+ @click.group(
22
+ name="update",
23
+ help="Update commands for wl_cli itself and vendor templates.",
24
+ )
25
+ def update_command():
26
+ """Update command group."""
27
+ pass
28
+
29
+
30
+ @update_command.command()
31
+ @click.argument("path", default=None, required=False)
32
+ def self(path: str | None = None):
33
+ """Update wl_cli itself (alias for 'wl self update').
34
+
35
+ Args:
36
+ path: Optional path to local source or version specification.
37
+ """
38
+ from wl_cli.commands.self.self_command import (
39
+ self_command as original_self_command,
40
+ )
41
+
42
+ ctx = click.get_current_context()
43
+ args = ["update"]
44
+ if path:
45
+ args.append(path)
46
+
47
+ with cast("click.Context", ctx.parent):
48
+ original_self_command.main(args=args, standalone_mode=True)
49
+
50
+
51
+ @update_command.command()
52
+ @click.option(
53
+ "--check", is_flag=True, help="Check for updates without applying changes"
54
+ )
55
+ @click.option(
56
+ "--dry-run", is_flag=True, help="Show what would be updated without making changes"
57
+ )
58
+ @click.option("--force", is_flag=True, help="Force update even if already up to date")
59
+ @click.option("--backup", is_flag=True, help="Create backup before updating")
60
+ def vendor(
61
+ check: bool = False,
62
+ dry_run: bool = False,
63
+ force: bool = False,
64
+ backup: bool = False,
65
+ ):
66
+ """Update vendor templates and .wl directory.
67
+
68
+ Args:
69
+ check: Only check for updates without applying changes
70
+ dry_run: Show what would be updated without making changes
71
+ force: Force update even if already up to date
72
+ backup: Create backup before updating
73
+ """
74
+ import json
75
+
76
+ from wl_cli import __version__
77
+
78
+ log_info_pair("Checking vendor template updates...", "正在检查供应商模板更新...")
79
+
80
+ # Root-anchored (#125): was a bare ``Path(".wl")`` against the process CWD,
81
+ # so ``wl update vendor`` from a subdirectory read the subdirectory's ``.wl``
82
+ # and reported "no .wl directory"; it now reads the deploy root's. See
83
+ # docs/adr/0006-root-resolution-layering.md.
84
+ wl_dir = current_root(RootKind.DEPLOY).wl_dir()
85
+ if not wl_dir.exists():
86
+ log_info_pair(
87
+ "No .wl directory found. Run 'wl init' first.",
88
+ "未找到 .wl 目录,请先运行 'wl init'。",
89
+ )
90
+ return
91
+
92
+ if check or dry_run:
93
+ config_file = wl_dir / "config.json"
94
+ if config_file.exists():
95
+ try:
96
+ with open(config_file, encoding="utf-8") as f:
97
+ config = json.load(f)
98
+ wl_dir_version = config.get("version", "unknown")
99
+ log_info_pair(
100
+ f"Current .wl directory version: {wl_dir_version}",
101
+ f"当前 .wl 目录版本:{wl_dir_version}",
102
+ )
103
+ log_info_pair(
104
+ f"Current wl version: {__version__}", f"当前 wl 版本:{__version__}"
105
+ )
106
+ except Exception as e:
107
+ log_info_pair(
108
+ f"Could not read version info: {e}", f"无法读取版本信息:{e}"
109
+ )
110
+ else:
111
+ log_info_pair(
112
+ "No config.json found. Would create/update .wl directory.",
113
+ "未找到 config.json,将创建/更新 .wl 目录。",
114
+ )
115
+
116
+ # Vendor freshness comes from the independent .wl/vendors.version stamp
117
+ # (#177): config.json.version is advanced by the self-sync on every
118
+ # command, so a verdict read from it said "already up to date" even when
119
+ # the vendor tree was missing -- the next real update would then copy
120
+ # files. Reuse the same dry-run check the copy path uses; it reports its
121
+ # own bilingual verdict.
122
+ VendorsUpdater(wl_dir).check()
123
+
124
+ if dry_run:
125
+ log_info_pair(
126
+ "Would update vendor templates and .wl directory",
127
+ "将更新供应商模板和 .wl 目录",
128
+ )
129
+ else:
130
+ if backup:
131
+ backup_manager = BackupManager(wl_dir)
132
+ backup_manager.create_backup()
133
+
134
+ check_and_update_wl_dir()
135
+
136
+ vendors_updater = VendorsUpdater(wl_dir)
137
+ # ``force`` used to be a dead flag: declared and documented, never read.
138
+ # Pass it through so ``wl update vendor --force`` re-copies even when
139
+ # the vendor stamp is current (#177).
140
+ vendors_updater.update(dry_run=False, force=force)
141
+
142
+
143
+ @update_command.command()
144
+ def status():
145
+ """Show current version and status."""
146
+ import json
147
+
148
+ from wl_cli import __version__
149
+
150
+ log_info_pair("Update Status:", "更新状态:")
151
+ log_info_pair(f" wl_cli version: {__version__}", f" wl_cli 版本:{__version__}")
152
+
153
+ # Root-anchored (#125): the deploy root's ``.wl``, not the process CWD's.
154
+ wl_dir = current_root(RootKind.DEPLOY).wl_dir()
155
+ if wl_dir.exists():
156
+ config_file = wl_dir / "config.json"
157
+ if config_file.exists():
158
+ try:
159
+ with open(config_file, encoding="utf-8") as f:
160
+ config = json.load(f)
161
+ wl_dir_version = config.get("version", "unknown")
162
+ log_info_pair(
163
+ f" .wl directory version: {wl_dir_version}",
164
+ f" .wl 目录版本:{wl_dir_version}",
165
+ )
166
+
167
+ version_compare = compare_versions(wl_dir_version, __version__)
168
+ if version_compare < 0:
169
+ log_info_pair(
170
+ " Status: Updates available!", " 状态:有可用更新!"
171
+ )
172
+ elif version_compare == 0:
173
+ log_info_pair(" Status: Up to date", " 状态:已是最新")
174
+ else:
175
+ log_info_pair(
176
+ " Status: .wl directory is newer than installed version",
177
+ " 状态:.wl 目录比安装的版本新",
178
+ )
179
+ except Exception as e:
180
+ log_info_pair(
181
+ f" Could not read version info: {e}", f" 无法读取版本信息:{e}"
182
+ )
183
+ else:
184
+ log_info_pair(
185
+ " No config.json found in .wl directory",
186
+ " .wl 目录中未找到 config.json",
187
+ )
188
+ else:
189
+ log_info_pair(" No .wl directory found", " 未找到 .wl 目录")
190
+
191
+
192
+ @update_command.command()
193
+ def list():
194
+ """List all available update components."""
195
+ component_manager = ComponentManager()
196
+ components = component_manager.get_all_components()
197
+
198
+ log_info_pair("Available update components:", "可用更新组件:")
199
+
200
+ for comp_id, comp_info in components.items():
201
+ log_info_pair(
202
+ f" - {comp_id}: {comp_info['description']}",
203
+ f" - {comp_id}:{comp_info['description']}",
204
+ )
205
+
206
+
207
+ @update_command.command()
208
+ @click.argument("backup_id", default=None, required=False)
209
+ def rollback(backup_id: str | None = None):
210
+ """Rollback to a previous backup (latest if no ID specified).
211
+
212
+ Args:
213
+ backup_id: Optional specific backup ID to rollback to.
214
+ """
215
+ backup_manager = BackupManager()
216
+ backup_manager.rollback_to_backup(backup_id)
217
+
218
+
219
+ @update_command.command()
220
+ def check():
221
+ """Check for available updates."""
222
+ import json
223
+
224
+ from wl_cli import __version__
225
+
226
+ log_info_pair("Checking for updates...", "检查更新...")
227
+
228
+ # Root-anchored (#125): the deploy root's ``.wl``, not the process CWD's.
229
+ wl_dir = current_root(RootKind.DEPLOY).wl_dir()
230
+ if not wl_dir.exists():
231
+ log_info_pair(
232
+ "No .wl directory found. Run 'wl init' first.",
233
+ "未找到 .wl 目录,请先运行 'wl init'。",
234
+ )
235
+ return
236
+
237
+ config_file = wl_dir / "config.json"
238
+ if config_file.exists():
239
+ try:
240
+ with open(config_file, encoding="utf-8") as f:
241
+ config = json.load(f)
242
+ wl_dir_version = config.get("version", "unknown")
243
+ log_info_pair(
244
+ f"Current .wl directory version: {wl_dir_version}",
245
+ f"当前 .wl 目录版本:{wl_dir_version}",
246
+ )
247
+ log_info_pair(
248
+ f"Current wl version: {__version__}", f"当前 wl 版本:{__version__}"
249
+ )
250
+
251
+ version_compare = compare_versions(wl_dir_version, __version__)
252
+ if version_compare < 0:
253
+ log_info_pair("✓ Updates available!", "✓ 有可用更新!")
254
+ elif version_compare == 0:
255
+ log_info_pair("✓ Already up to date!", "✓ 已是最新版本!")
256
+ else:
257
+ log_info_pair(
258
+ "! .wl directory version is newer than wl version",
259
+ "! .wl 目录比安装的版本新",
260
+ )
261
+ except Exception as e:
262
+ log_info_pair(f"Could not read version info: {e}", f"无法读取版本信息:{e}")
263
+ else:
264
+ log_info_pair(
265
+ "No config.json found. Will create/update .wl directory.",
266
+ "未找到 config.json,将创建/更新 .wl 目录。",
267
+ )
268
+
269
+ vendors_updater = VendorsUpdater()
270
+ vendors_updater.check()
@@ -0,0 +1,3 @@
1
+ """
2
+ Utilities for update command.
3
+ """
@@ -0,0 +1,9 @@
1
+ """
2
+ Version command module.
3
+
4
+ This module provides version management commands.
5
+ """
6
+
7
+ from .version_command import VersionCommand, version_command
8
+
9
+ __all__ = ["VersionCommand", "version_command"]
@@ -0,0 +1,155 @@
1
+ """
2
+ Version command implementation for WL Commands.
3
+
4
+ Provides commands to manage project versions:
5
+ - show: Display current version
6
+ - sync: Sync VERSION file to __init__.py and Cargo.toml
7
+ - bump: Increment version number
8
+ """
9
+
10
+ from typing import Any
11
+
12
+ import click
13
+
14
+ from ...commands import Command
15
+ from ...exceptions import CommandError
16
+ from ...utils.logging import log_info
17
+ from ...utils.version.version_service import VersionService
18
+ from ...utils.version.version_updater import VersionUpdater
19
+
20
+
21
+ class VersionCommand(Command):
22
+ """Version command - manage project versions"""
23
+
24
+ def __init__(self) -> None:
25
+ """Initialize version command"""
26
+ self.version_service = VersionService()
27
+ self.version_updater = VersionUpdater()
28
+
29
+ @property
30
+ def name(self) -> str:
31
+ """Get command name"""
32
+ return "version"
33
+
34
+ @property
35
+ def help(self) -> str:
36
+ """Get command help text"""
37
+ return "Manage project versions"
38
+
39
+ def execute(self, *_, **kwargs: Any) -> None:
40
+ """Execute the version command."""
41
+ subcommand = kwargs.get("subcommand")
42
+ if subcommand == "show":
43
+ self._handle_show(kwargs)
44
+ elif subcommand == "sync":
45
+ self._handle_sync(kwargs)
46
+ elif subcommand == "bump":
47
+ self._handle_bump(kwargs)
48
+ else:
49
+ raise CommandError("Please specify a subcommand: show, sync, or bump")
50
+
51
+ def _handle_show(self, kwargs: dict[str, Any]) -> None:
52
+ """Handle show subcommand."""
53
+ current_version = self.version_service.get_current_version()
54
+ click.echo(f"Current version: {current_version}")
55
+
56
+ def _handle_sync(self, kwargs: dict[str, Any]) -> None:
57
+ """Handle sync subcommand."""
58
+ # Read version from VERSION file
59
+ from pathlib import Path
60
+
61
+ version_file = Path("VERSION")
62
+ if not version_file.exists():
63
+ raise CommandError("VERSION file not found")
64
+
65
+ current_version = version_file.read_text(encoding="utf-8").strip()
66
+
67
+ log_info(f"Syncing version {current_version} to all files...")
68
+
69
+ # Update all files
70
+ self.version_updater._update_python_version(current_version)
71
+ self.version_updater._update_rust_version(current_version)
72
+
73
+ log_info("✓ Version synchronization complete")
74
+
75
+ def _handle_bump(self, kwargs: dict[str, Any]) -> None:
76
+ """Handle bump subcommand."""
77
+ part = kwargs.get("part", "patch")
78
+
79
+ # Get current version
80
+ current_version = self.version_service.get_current_version()
81
+ log_info(f"Current version: {current_version}")
82
+
83
+ # Split version into parts
84
+ try:
85
+ version_parts = list(map(int, current_version.split(".")))
86
+ # Ensure we have at least 3 parts
87
+ while len(version_parts) < 3:
88
+ version_parts.append(0)
89
+
90
+ # Increment the specified part
91
+ if part == "major":
92
+ version_parts[0] += 1
93
+ version_parts[1] = 0
94
+ version_parts[2] = 0
95
+ elif part == "minor":
96
+ version_parts[1] += 1
97
+ version_parts[2] = 0
98
+ else: # patch
99
+ version_parts[2] += 1
100
+
101
+ # If there's a 4th part, reset it
102
+ if len(version_parts) > 3:
103
+ version_parts[3] = 0
104
+
105
+ new_version = ".".join(map(str, version_parts))
106
+
107
+ log_info(f"New version: {new_version}")
108
+
109
+ # Update all files
110
+ self.version_updater._update_version_file(new_version)
111
+ self.version_updater._update_python_version(new_version)
112
+ self.version_updater._update_rust_version(new_version)
113
+
114
+ log_info(f"✓ Version bumped from {current_version} to {new_version}")
115
+
116
+ except Exception as e:
117
+ raise CommandError(f"Failed to bump version: {e}")
118
+
119
+
120
+ @click.group(name="version")
121
+ def version_group():
122
+ """Manage project versions"""
123
+ pass
124
+
125
+
126
+ @version_group.command(name="show")
127
+ def version_show():
128
+ """Show current project version"""
129
+ cmd = VersionCommand()
130
+ cmd.execute(subcommand="show")
131
+
132
+
133
+ @version_group.command(name="sync")
134
+ def version_sync():
135
+ """Sync VERSION file to __init__.py and Cargo.toml"""
136
+ cmd = VersionCommand()
137
+ cmd.execute(subcommand="sync")
138
+
139
+
140
+ @version_group.command(name="bump")
141
+ @click.argument(
142
+ "part",
143
+ type=click.Choice(["major", "minor", "patch"]),
144
+ default="patch",
145
+ required=False,
146
+ )
147
+ def version_bump(part: str):
148
+ """Increment version number (major, minor, patch)"""
149
+ cmd = VersionCommand()
150
+ cmd.execute(subcommand="bump", part=part)
151
+
152
+
153
+ def version_command():
154
+ """Version command Click group."""
155
+ return version_group