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,53 @@
1
+ """Gitignore template manager."""
2
+
3
+ import shutil
4
+ from pathlib import Path
5
+
6
+ from wl_cli.utils.logging import log_info, log_info_pair
7
+
8
+
9
+ class GitignoreManager:
10
+ """Manager for .gitignore template operations."""
11
+
12
+ def __init__(self, skip_remote_ops: bool = False) -> None:
13
+ self.skip_remote_ops = skip_remote_ops
14
+
15
+ def copy_gitignore_template(self) -> None:
16
+ """Copy .gitignore template from vendors to project root.
17
+
18
+ Copies the .gitignore template from the vendors directory to the
19
+ current working directory if no .gitignore file already exists.
20
+ """
21
+ gitignore_path = Path(".gitignore")
22
+
23
+ # Only copy if .gitignore doesn't exist and not in test environment
24
+ if gitignore_path.exists() or self.skip_remote_ops:
25
+ return
26
+
27
+ try:
28
+ # Calculate path to vendors/git/.gitignore relative to this file
29
+ template_path = (
30
+ Path(__file__).parent.parent.parent.parent.parent
31
+ / "vendors"
32
+ / "git"
33
+ / ".gitignore"
34
+ )
35
+
36
+ log_info(f"Looking for .gitignore template at: {template_path}")
37
+
38
+ if template_path.exists():
39
+ shutil.copy2(template_path, ".gitignore")
40
+ log_info_pair(
41
+ "✓ .gitignore template copied successfully",
42
+ "✓ .gitignore 模板复制成功",
43
+ )
44
+ else:
45
+ log_info_pair(
46
+ f"Warning: .gitignore template not found at {template_path}",
47
+ f"警告: 未找到 .gitignore 模板 {template_path}",
48
+ )
49
+ except Exception as e:
50
+ log_info_pair(
51
+ f"Warning: Failed to copy .gitignore template: {e}",
52
+ f"警告: 复制 .gitignore 模板失败: {e}",
53
+ )
@@ -0,0 +1,212 @@
1
+ """Git initializer utility."""
2
+
3
+ import subprocess
4
+ from pathlib import Path
5
+
6
+ from ....utils.logging import log_debug_pair, log_info, log_info_pair
7
+ from ....utils.root import _clear_root_cache
8
+ from ..common.check_git_bash import check_git_bash_installed
9
+ from ..common.exceptions import GitInitError
10
+ from .git.git_flow_manager import GitFlowManager
11
+ from .git.gitignore_manager import GitignoreManager
12
+ from .log_manager import performance_monitor
13
+
14
+
15
+ class GitInitializer:
16
+ """Git repository initializer."""
17
+
18
+ def __init__(
19
+ self,
20
+ env: dict[str, str],
21
+ project_root: Path | None = None,
22
+ skip_remote_ops: bool = False,
23
+ ) -> None:
24
+ self.env = env
25
+ self.project_root = project_root or Path.cwd()
26
+ self.skip_remote_ops = skip_remote_ops
27
+ self.gitignore_manager = GitignoreManager(skip_remote_ops=skip_remote_ops)
28
+ self.git_flow_manager = GitFlowManager(env, skip_remote_ops=skip_remote_ops)
29
+
30
+ @performance_monitor
31
+ def initialize(self) -> None:
32
+ """
33
+ Initialize Git repository if it doesn't exist.
34
+ """
35
+ # Check for Git Bash (only runs on Windows)
36
+ check_git_bash_installed()
37
+
38
+ # Copy .gitignore template if it doesn't exist and we're not in a test environment
39
+ if not (self.project_root / ".gitignore").exists() and not self.skip_remote_ops:
40
+ self.gitignore_manager.copy_gitignore_template()
41
+
42
+ if not Path(".git").exists():
43
+ log_debug_pair("Initializing Git repository...", "初始化Git仓库...")
44
+ try:
45
+ if not self.git_flow_manager.git_utility.run_git_command(
46
+ ["git", "init"], description="Initialize Git repository"
47
+ ):
48
+ raise GitInitError(
49
+ "Failed to initialize Git repository after multiple attempts"
50
+ )
51
+ # The work tree did not exist a moment ago, so any DEPLOY root
52
+ # memoised for this directory came from the PROJECT fallback and
53
+ # is now wrong (it may point at a parent workspace or
54
+ # sub-package). Drop it so the rest of this run anchors the
55
+ # hooks leg at the root git just created (#103).
56
+ # The root module memoises every kind in one cache, including the
57
+ # negative answer (#113 User Story 17: "not found" is a cacheable
58
+ # answer, so a ``None`` asked for before this ``git init`` would
59
+ # otherwise stick for the whole process). This is the *only*
60
+ # invalidator now: the per-resolver clearers were deleted along
61
+ # with the resolvers themselves in #123.
62
+ _clear_root_cache()
63
+ log_info_pair("✓ Git repository initialized", "✓ Git仓库初始化完成")
64
+ except Exception as e:
65
+ log_info_pair(
66
+ "Warning: Failed to initialize Git repository",
67
+ "警告: 初始化Git仓库失败",
68
+ )
69
+ raise GitInitError(f"Failed to initialize Git repository: {e}")
70
+ else:
71
+ log_debug_pair(
72
+ "Git repository already exists, skipping initialization",
73
+ "Git仓库已存在,跳过初始化",
74
+ )
75
+
76
+ # Update repository if it already exists (skip during tests)
77
+ if not self.skip_remote_ops:
78
+ self.update_repository()
79
+
80
+ # Setup Git Flow branches (main, develop, features) and switch to features
81
+ if not self.skip_remote_ops:
82
+ try:
83
+ self.git_flow_manager.setup_git_flow_branches()
84
+ except Exception as e:
85
+ log_info_pair(
86
+ f"Warning: Failed to setup Git Flow branches: {e}",
87
+ f"警告: 设置Git Flow分支失败: {e}",
88
+ )
89
+ # Continue execution even if Git Flow setup fails
90
+
91
+ def setup_git_flow_branches(self, work_type: str) -> None:
92
+ """Setup Git Flow branches based on work type."""
93
+ self.git_flow_manager.setup_git_flow_branches_by_work_type(work_type)
94
+
95
+ def update_repository(self) -> None:
96
+ """Update the repository by pulling latest changes from all important branches.
97
+
98
+ This method:
99
+ 1. Updates the main branch
100
+ 2. Updates the develop branch
101
+ 3. Updates all feature branches (skipped in test environments)
102
+ 4. Switches back to the develop branch
103
+ """
104
+ log_info_pair("Updating repository...", "更新仓库...")
105
+
106
+ # Update main branch
107
+ log_info_pair("Updating main branch...", "更新main分支...")
108
+ self._update_branch("main")
109
+
110
+ # Update develop branch
111
+ log_info_pair("Updating develop branch...", "更新develop分支...")
112
+ self._update_branch("develop")
113
+
114
+ # Update all feature branches - skip in test environment to speed up tests
115
+ if not self.skip_remote_ops:
116
+ self._update_feature_branches()
117
+
118
+ # Switch back to develop branch as a safe default
119
+ log_info("Switching back to develop branch...")
120
+ self.git_flow_manager.git_utility.run_git_command(
121
+ ["git", "checkout", "develop"], description="Switch to develop branch"
122
+ )
123
+
124
+ def _update_branch(self, branch_name: str) -> bool:
125
+ """
126
+ Update a specific git branch.
127
+
128
+ Args:
129
+ branch_name: Name of the branch to update
130
+
131
+ Returns:
132
+ bool: True if branch was updated successfully
133
+ """
134
+ success = False
135
+
136
+ if self.git_flow_manager.git_utility.run_git_command(
137
+ ["git", "fetch", "origin", branch_name],
138
+ description=f"Fetch {branch_name} branch",
139
+ ):
140
+ if self.git_flow_manager.git_utility.run_git_command(
141
+ ["git", "checkout", branch_name],
142
+ description=f"Checkout {branch_name} branch",
143
+ ):
144
+ if self.git_flow_manager.git_utility.run_git_command(
145
+ ["git", "pull", "origin", branch_name],
146
+ description=f"Pull {branch_name} branch",
147
+ ):
148
+ log_info_pair(
149
+ f"✓ {branch_name} branch updated successfully",
150
+ f"✓ {branch_name}分支更新完成",
151
+ )
152
+ success = True
153
+
154
+ return success
155
+
156
+ def _update_feature_branches(self) -> None:
157
+ """
158
+ Update all feature branches in the repository.
159
+ """
160
+ log_info_pair(
161
+ "Updating all feature branches...", "拉取所有feature分支最新变更..."
162
+ )
163
+
164
+ try:
165
+ # Get all remote feature branches
166
+ result = subprocess.run(
167
+ ["git", "branch", "-r"],
168
+ check=True,
169
+ capture_output=True,
170
+ env=self.env,
171
+ text=True,
172
+ )
173
+
174
+ # Parse feature branches
175
+ feature_branches = [
176
+ line.strip()
177
+ for line in result.stdout.split("\n")
178
+ if line.strip().startswith("origin/feature/")
179
+ ]
180
+
181
+ # Update each feature branch
182
+ success_count = 0
183
+ for branch in feature_branches:
184
+ branch_name = branch.replace("origin/", "")
185
+ log_info_pair(f"Updating {branch_name}...", f"拉取{branch_name}...")
186
+
187
+ if self.git_flow_manager.git_utility.run_git_command(
188
+ ["git", "fetch", "origin", branch_name],
189
+ description=f"Fetch {branch_name}",
190
+ ):
191
+ success_count += 1
192
+
193
+ # Report results
194
+ if feature_branches:
195
+ total_count = len(feature_branches)
196
+ log_info_pair(
197
+ f"✓ Updated {success_count}/{total_count} feature branches",
198
+ f"✓ 已更新 {success_count}/{total_count} 个feature分支",
199
+ )
200
+ else:
201
+ log_info_pair("✓ No feature branches found", "✓ 未找到feature分支")
202
+
203
+ except subprocess.CalledProcessError as e:
204
+ log_info_pair(
205
+ f"Warning: Failed to list feature branches: {e.stderr}",
206
+ f"警告: 列出feature分支失败: {e.stderr}",
207
+ )
208
+ except Exception as e:
209
+ log_info_pair(
210
+ f"Warning: Failed to update feature branches: {e}",
211
+ f"警告: 更新feature分支失败: {e}",
212
+ )
@@ -0,0 +1,104 @@
1
+ """Internationalization manager utility."""
2
+
3
+
4
+ class I18nManager:
5
+ """Manager for internationalization support."""
6
+
7
+ def __init__(self, default_lang: str = "en") -> None:
8
+ self.default_lang = default_lang
9
+ self.current_lang = default_lang
10
+ self.translations: dict[str, dict[str, str]] = {}
11
+ self._load_default_translations()
12
+
13
+ def _load_default_translations(self) -> None:
14
+ """Load default translations."""
15
+ # Default translations for initenv module
16
+ default_translations = {
17
+ "git_init_start": {
18
+ "en": "Initializing Git repository...",
19
+ "zh": "初始化Git仓库...",
20
+ },
21
+ "git_init_success": {
22
+ "en": "✓ Git repository initialized",
23
+ "zh": "✓ Git仓库初始化完成",
24
+ },
25
+ "git_init_skip": {
26
+ "en": "Git repository already exists, skipping initialization",
27
+ "zh": "Git仓库已存在,跳过初始化",
28
+ },
29
+ "git_init_fail": {
30
+ "en": "Warning: Failed to initialize Git repository",
31
+ "zh": "警告: 初始化Git仓库失败",
32
+ },
33
+ "project_structure_start": {
34
+ "en": "Setting up project structure...",
35
+ "zh": "设置项目结构...",
36
+ },
37
+ "project_structure_success": {
38
+ "en": "✓ Project structure created successfully",
39
+ "zh": "✓ 项目结构创建成功",
40
+ },
41
+ "project_structure_fail": {
42
+ "en": "Warning: Failed to setup project structure",
43
+ "zh": "警告: 设置项目结构失败",
44
+ },
45
+ "rust_init_start": {
46
+ "en": "Initializing Rust environment...",
47
+ "zh": "初始化Rust环境...",
48
+ },
49
+ "rust_init_success": {
50
+ "en": "✓ Rust project initialized successfully",
51
+ "zh": "✓ Rust项目初始化成功",
52
+ },
53
+ "rust_init_fail": {
54
+ "en": "Warning: Failed to initialize Rust environment",
55
+ "zh": "警告: 初始化Rust环境失败",
56
+ },
57
+ "venv_create_start": {
58
+ "en": "Creating virtual environment...",
59
+ "zh": "创建虚拟环境...",
60
+ },
61
+ "venv_create_success": {
62
+ "en": "✓ Virtual environment created successfully",
63
+ "zh": "✓ 虚拟环境创建成功",
64
+ },
65
+ "venv_create_fail": {
66
+ "en": "Warning: Failed to create virtual environment",
67
+ "zh": "警告: 创建虚拟环境失败",
68
+ },
69
+ "init_complete": {
70
+ "en": "Project environment initialization completed!",
71
+ "zh": "项目环境初始化完成!",
72
+ },
73
+ }
74
+
75
+ for key, translations in default_translations.items():
76
+ self.add_translation(key, translations)
77
+
78
+ def add_translation(self, key: str, translations: dict[str, str]) -> None:
79
+ """Add translation for a key."""
80
+ self.translations[key] = translations
81
+
82
+ def get_text(self, key: str, lang: str | None = None) -> str:
83
+ """Get translated text by key."""
84
+ if key not in self.translations:
85
+ return key
86
+
87
+ target_lang = lang or self.current_lang
88
+ translations = self.translations[key]
89
+
90
+ if target_lang in translations:
91
+ return translations[target_lang]
92
+
93
+ if self.default_lang in translations:
94
+ return translations[self.default_lang]
95
+
96
+ # Return first available translation
97
+ if translations:
98
+ return next(iter(translations.values()))
99
+
100
+ return key
101
+
102
+ def t(self, key: str, lang: str | None = None) -> str:
103
+ """Shortcut for get_text."""
104
+ return self.get_text(key, lang)
@@ -0,0 +1,241 @@
1
+ """Log manager utility for initenv module."""
2
+
3
+ import time
4
+ from collections.abc import Callable
5
+ from functools import wraps
6
+ from typing import Any
7
+
8
+ from ....utils.log_levels import LogLevel
9
+ from ....utils.logging import (
10
+ StructuredLogger,
11
+ clear_log_context,
12
+ get_logger,
13
+ log_debug,
14
+ log_error,
15
+ log_exception,
16
+ log_info,
17
+ log_warning,
18
+ pop_log_context,
19
+ push_log_context,
20
+ )
21
+ from ....utils.logging import configure_logging as global_configure_logging
22
+
23
+
24
+ class LogManager:
25
+ """Manager for logging with levels - now using unified logging system."""
26
+
27
+ def __init__(self, name: str = "initenv") -> None:
28
+ self.logger: StructuredLogger = get_logger(name)
29
+ # Set default log level to INFO to match test expectations
30
+ self.logger.min_level = LogLevel.INFO
31
+
32
+ def info(self, message: str, lang: str = "en", **kwargs) -> None:
33
+ """Log info message."""
34
+ log_info(message, lang=lang, **kwargs)
35
+
36
+ def warning(self, message: str, **kwargs) -> None:
37
+ """Log warning message."""
38
+ log_warning(message, **kwargs)
39
+
40
+ def error(self, message: str, **kwargs) -> None:
41
+ """Log error message."""
42
+ log_error(message, **kwargs)
43
+
44
+ def debug(self, message: str, **kwargs) -> None:
45
+ """Log debug message."""
46
+ log_debug(message, **kwargs)
47
+
48
+ def push_context(self, **context) -> None:
49
+ """Push context to the logger's context stack."""
50
+ if hasattr(self.logger, "push_context"):
51
+ self.logger.push_context(**context)
52
+ else:
53
+ push_log_context(**context)
54
+
55
+ def pop_context(self) -> dict[str, Any] | None:
56
+ """Pop context from the logger's context stack."""
57
+ if hasattr(self.logger, "pop_context"):
58
+ return self.logger.pop_context()
59
+ else:
60
+ return pop_log_context()
61
+
62
+ def clear_context(self) -> None:
63
+ """Clear all context from the logger's context stack."""
64
+ if hasattr(self.logger, "clear_context"):
65
+ self.logger.clear_context()
66
+ else:
67
+ clear_log_context()
68
+
69
+ @staticmethod
70
+ def configure_logging(**kwargs) -> None:
71
+ """
72
+ Configure logging based on command-line arguments.
73
+
74
+ Args:
75
+ **kwargs: Command-line arguments including logging configuration
76
+ """
77
+ from wl_cli.utils.config import get_config_manager
78
+
79
+ config_manager = get_config_manager()
80
+
81
+ # Get logging configuration from kwargs
82
+ log_level = kwargs.get("log_level")
83
+ log_console = kwargs.get("log_console")
84
+ log_file = kwargs.get("log_file")
85
+ log_format = kwargs.get("log_format")
86
+ log_rotation = kwargs.get("log_rotation")
87
+
88
+ # Update configuration
89
+ config_updates = {}
90
+ if log_level:
91
+ config_updates["log_level"] = log_level
92
+ if log_console is not None:
93
+ config_updates["log_console"] = log_console
94
+ if log_file:
95
+ config_updates["log_file"] = log_file
96
+ if log_format:
97
+ config_updates["log_file_format"] = log_format
98
+ if log_rotation:
99
+ config_updates["log_max_size"] = log_rotation
100
+
101
+ # Apply configuration updates
102
+ for key, value in config_updates.items():
103
+ config_manager.set(key, value)
104
+
105
+ # Configure the global logger
106
+ if config_updates:
107
+ global_configure_logging(config_updates)
108
+
109
+ @staticmethod
110
+ def get_logger(
111
+ name: str = "initenv", config: dict[str, Any] | None = None
112
+ ) -> StructuredLogger:
113
+ """
114
+ Get a logger instance with the specified name and configuration.
115
+
116
+ Args:
117
+ name (str): Logger name.
118
+ config (Optional[Dict[str, Any]]): Logger configuration.
119
+
120
+ Returns:
121
+ StructuredLogger: Logger instance.
122
+ """
123
+ return get_logger(name, config)
124
+
125
+
126
+ def performance_monitor(func: Callable[..., Any]) -> Callable[..., Any]:
127
+ """Decorator to monitor function execution time and add context."""
128
+
129
+ @wraps(func)
130
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
131
+ # Add function context
132
+ context = {"function": func.__name__, "module": func.__module__}
133
+ push_log_context(**context)
134
+
135
+ start_time = time.time()
136
+ log_info(f"Starting {func.__name__}...")
137
+
138
+ try:
139
+ result = func(*args, **kwargs)
140
+ end_time = time.time()
141
+ execution_time = end_time - start_time
142
+ log_info(
143
+ f"Finished {func.__name__} in {execution_time:.2f} seconds",
144
+ duration=execution_time,
145
+ result="success",
146
+ )
147
+ return result
148
+ except Exception as e:
149
+ end_time = time.time()
150
+ execution_time = end_time - start_time
151
+ log_exception(
152
+ f"Error in {func.__name__} after {execution_time:.2f} seconds",
153
+ exc_info=e,
154
+ duration=execution_time,
155
+ result="error",
156
+ )
157
+ raise
158
+ finally:
159
+ pop_log_context()
160
+
161
+ return wrapper
162
+
163
+
164
+ def log_context(**context) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
165
+ """Decorator to add context to log messages."""
166
+
167
+ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
168
+ @wraps(func)
169
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
170
+ push_log_context(**context)
171
+ try:
172
+ return func(*args, **kwargs)
173
+ finally:
174
+ pop_log_context()
175
+
176
+ return wrapper
177
+
178
+ return decorator
179
+
180
+
181
+ def error_handler(func: Callable[..., Any]) -> Callable[..., Any]:
182
+ """Decorator to handle and log errors."""
183
+
184
+ @wraps(func)
185
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
186
+ try:
187
+ return func(*args, **kwargs)
188
+ except Exception as e:
189
+ log_exception(f"Error in {func.__name__}", exc_info=e)
190
+ raise
191
+
192
+ return wrapper
193
+
194
+
195
+ def debug_only(func: Callable[..., Any]) -> Callable[..., Any]:
196
+ """Decorator to only execute function in debug mode."""
197
+
198
+ @wraps(func)
199
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
200
+ logger = get_logger(func.__module__)
201
+ if logger.min_level <= LogLevel.DEBUG:
202
+ return func(*args, **kwargs)
203
+ return None
204
+
205
+ return wrapper
206
+
207
+
208
+ def timed_operation(
209
+ description: str,
210
+ ) -> Callable[[Callable[..., Any]], Callable[..., Any]]:
211
+ """Decorator to time and log an operation with a description."""
212
+
213
+ def decorator(func: Callable[..., Any]) -> Callable[..., Any]:
214
+ @wraps(func)
215
+ def wrapper(*args: Any, **kwargs: Any) -> Any:
216
+ start_time = time.time()
217
+ log_info(f"Starting {description}...")
218
+ try:
219
+ result = func(*args, **kwargs)
220
+ end_time = time.time()
221
+ execution_time = end_time - start_time
222
+ log_info(
223
+ f"Finished {description} in {execution_time:.2f} seconds",
224
+ duration=execution_time,
225
+ operation=description,
226
+ )
227
+ return result
228
+ except Exception as e:
229
+ end_time = time.time()
230
+ execution_time = end_time - start_time
231
+ log_exception(
232
+ f"Error in {description} after {execution_time:.2f} seconds",
233
+ exc_info=e,
234
+ duration=execution_time,
235
+ operation=description,
236
+ )
237
+ raise
238
+
239
+ return wrapper
240
+
241
+ return decorator
@@ -0,0 +1,23 @@
1
+ """Project structure utilities package."""
2
+
3
+ from .directory_creator import (
4
+ _create_init_files,
5
+ _create_readme,
6
+ _create_required_directories,
7
+ _normalize_project_name,
8
+ normalize_project_name,
9
+ setup_project_structure,
10
+ )
11
+ from .hooks_manager import sync_hooks
12
+ from .setup_handler import ProjectStructureSetup
13
+
14
+ __all__ = [
15
+ "ProjectStructureSetup",
16
+ "setup_project_structure",
17
+ "sync_hooks",
18
+ "_create_required_directories",
19
+ "_create_init_files",
20
+ "_create_readme",
21
+ "_normalize_project_name",
22
+ "normalize_project_name",
23
+ ]