py-wlcli 0.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- py_wlcli-0.8.0.dist-info/METADATA +139 -0
- py_wlcli-0.8.0.dist-info/RECORD +320 -0
- py_wlcli-0.8.0.dist-info/WHEEL +4 -0
- py_wlcli-0.8.0.dist-info/entry_points.txt +2 -0
- py_wlcli-0.8.0.dist-info/licenses/LICENSE +21 -0
- wl_cli/__init__.py +27 -0
- wl_cli/__main__.py +130 -0
- wl_cli/capabilities.py +79 -0
- wl_cli/cc/__init__.py +5 -0
- wl_cli/cc/checks.py +1019 -0
- wl_cli/cc/cli.py +370 -0
- wl_cli/cc/mutate.py +1350 -0
- wl_cli/cli_click.py +156 -0
- wl_cli/commands/__init__.py +84 -0
- wl_cli/commands/base.py +80 -0
- wl_cli/commands/buildcommands/__init__.py +1 -0
- wl_cli/commands/buildcommands/build.py +71 -0
- wl_cli/commands/buildcommands/build_utils.py +47 -0
- wl_cli/commands/buildcommands/builders/__init__.py +18 -0
- wl_cli/commands/buildcommands/builders/cleanup.py +35 -0
- wl_cli/commands/buildcommands/builders/coordinator.py +122 -0
- wl_cli/commands/buildcommands/builders/environment.py +81 -0
- wl_cli/commands/buildcommands/builders/rust_builder.py +39 -0
- wl_cli/commands/buildcommands/builders/stubs.py +58 -0
- wl_cli/commands/buildcommands/dist.py +326 -0
- wl_cli/commands/buildcommands/test.py +89 -0
- wl_cli/commands/clean/__init__.py +1 -0
- wl_cli/commands/clean/build.py +151 -0
- wl_cli/commands/clean/clean.py +294 -0
- wl_cli/commands/clean/clean_utils.py +77 -0
- wl_cli/commands/clean/core.py +236 -0
- wl_cli/commands/clean/dead_code/__init__.py +0 -0
- wl_cli/commands/clean/dead_code/dead_code_command.py +70 -0
- wl_cli/commands/clean/dead_code/detector.py +161 -0
- wl_cli/commands/clean/dead_code/fixer.py +176 -0
- wl_cli/commands/clean/dead_code/reporter.py +295 -0
- wl_cli/commands/clean/dead_code/utils.py +0 -0
- wl_cli/commands/clean/lfs.py +215 -0
- wl_cli/commands/clean/python.py +81 -0
- wl_cli/commands/clean/rust.py +91 -0
- wl_cli/commands/clean/utils/__init__.py +34 -0
- wl_cli/commands/clean/venv.py +91 -0
- wl_cli/commands/cleanup.py +73 -0
- wl_cli/commands/click_base.py +79 -0
- wl_cli/commands/config/__init__.py +1 -0
- wl_cli/commands/config/config.py +291 -0
- wl_cli/commands/debug/__init__.py +6 -0
- wl_cli/commands/debug/debug.py +309 -0
- wl_cli/commands/debug/debug_cache.py +86 -0
- wl_cli/commands/debug/debug_subagent.py +156 -0
- wl_cli/commands/debug/output_formatter.py +165 -0
- wl_cli/commands/debug/source_hasher.py +92 -0
- wl_cli/commands/format/__init__.py +13 -0
- wl_cli/commands/format/format_cache_adapter.py +125 -0
- wl_cli/commands/format/format_command.py +197 -0
- wl_cli/commands/format/format_coordinator.py +191 -0
- wl_cli/commands/format/format_executor.py +470 -0
- wl_cli/commands/format/format_outcome.py +44 -0
- wl_cli/commands/format/format_path_handler.py +1016 -0
- wl_cli/commands/format/format_progress.py +62 -0
- wl_cli/commands/format/format_reporter.py +31 -0
- wl_cli/commands/format/python_formatter.py +506 -0
- wl_cli/commands/format/rust_formatter.py +106 -0
- wl_cli/commands/gate/__init__.py +1 -0
- wl_cli/commands/gate/gate_command.py +862 -0
- wl_cli/commands/gate/preflight.py +445 -0
- wl_cli/commands/git/__init__.py +1 -0
- wl_cli/commands/git/config.py +169 -0
- wl_cli/commands/git/git_facts.py +60 -0
- wl_cli/commands/git/git_flow.py +86 -0
- wl_cli/commands/git/hook.py +112 -0
- wl_cli/commands/git/policy.py +216 -0
- wl_cli/commands/git/push_update.py +82 -0
- wl_cli/commands/initenv/__init__.py +1 -0
- wl_cli/commands/initenv/common/__init__.py +23 -0
- wl_cli/commands/initenv/common/check_git_bash.py +78 -0
- wl_cli/commands/initenv/common/error_handler.py +68 -0
- wl_cli/commands/initenv/common/exceptions.py +52 -0
- wl_cli/commands/initenv/components/__init__.py +4 -0
- wl_cli/commands/initenv/components/cargo_sync.py +240 -0
- wl_cli/commands/initenv/components/config_manager.py +106 -0
- wl_cli/commands/initenv/components/directory_utils.py +71 -0
- wl_cli/commands/initenv/components/git/__init__.py +9 -0
- wl_cli/commands/initenv/components/git/branch_creator.py +143 -0
- wl_cli/commands/initenv/components/git/git_flow_interface.py +24 -0
- wl_cli/commands/initenv/components/git/git_flow_manager.py +159 -0
- wl_cli/commands/initenv/components/git/git_lfs_manager.py +272 -0
- wl_cli/commands/initenv/components/git/git_utility.py +254 -0
- wl_cli/commands/initenv/components/git/gitignore_manager.py +53 -0
- wl_cli/commands/initenv/components/git_initializer.py +212 -0
- wl_cli/commands/initenv/components/i18n_manager.py +104 -0
- wl_cli/commands/initenv/components/log_manager.py +241 -0
- wl_cli/commands/initenv/components/project_structure/__init__.py +23 -0
- wl_cli/commands/initenv/components/project_structure/config_generator.py +360 -0
- wl_cli/commands/initenv/components/project_structure/directory_creator.py +184 -0
- wl_cli/commands/initenv/components/project_structure/hook_source.py +110 -0
- wl_cli/commands/initenv/components/project_structure/hooks_manager.py +995 -0
- wl_cli/commands/initenv/components/project_structure/readme_handler.py +56 -0
- wl_cli/commands/initenv/components/project_structure/rust_files_handler.py +30 -0
- wl_cli/commands/initenv/components/project_structure/setup_handler.py +103 -0
- wl_cli/commands/initenv/components/project_structure/sop_generator.py +73 -0
- wl_cli/commands/initenv/components/project_structure/template_copier.py +104 -0
- wl_cli/commands/initenv/components/project_structure/template_manager.py +195 -0
- wl_cli/commands/initenv/components/pyproject_generator.py +194 -0
- wl_cli/commands/initenv/components/rust_initializer.py +145 -0
- wl_cli/commands/initenv/components/symlink_cleaner.py +99 -0
- wl_cli/commands/initenv/components/symlink_manager.py +52 -0
- wl_cli/commands/initenv/components/venv_manager.py +118 -0
- wl_cli/commands/initenv/initenv.py +169 -0
- wl_cli/commands/initenv/services/__init__.py +11 -0
- wl_cli/commands/initenv/services/environment_initializer.py +288 -0
- wl_cli/commands/initenv/services/git_lfs_initializer.py +26 -0
- wl_cli/commands/initenv/services/project_structure_initializer.py +52 -0
- wl_cli/commands/lfs/README.md +221 -0
- wl_cli/commands/lfs/__init__.py +5 -0
- wl_cli/commands/lfs/cli.py +106 -0
- wl_cli/commands/lfs/config.py +164 -0
- wl_cli/commands/lfs/hook.py +61 -0
- wl_cli/commands/lfs/initializer.py +531 -0
- wl_cli/commands/lfs/manager.py +95 -0
- wl_cli/commands/lfs/policy.py +165 -0
- wl_cli/commands/lfs/watcher.py +294 -0
- wl_cli/commands/lint/__init__.py +1 -0
- wl_cli/commands/lint/lint_command.py +297 -0
- wl_cli/commands/lint/lint_executor.py +409 -0
- wl_cli/commands/lint/lint_reporter.py +579 -0
- wl_cli/commands/lint/lint_run.py +258 -0
- wl_cli/commands/lint/mypy_config.py +90 -0
- wl_cli/commands/registry.py +103 -0
- wl_cli/commands/self/__init__.py +7 -0
- wl_cli/commands/self/common/__init__.py +8 -0
- wl_cli/commands/self/common/capabilities.py +30 -0
- wl_cli/commands/self/common/config.py +27 -0
- wl_cli/commands/self/common/version_cache.py +85 -0
- wl_cli/commands/self/handlers/__init__.py +19 -0
- wl_cli/commands/self/handlers/base_handler.py +28 -0
- wl_cli/commands/self/handlers/install_handler.py +85 -0
- wl_cli/commands/self/handlers/status_handler.py +66 -0
- wl_cli/commands/self/handlers/uninstall_handler.py +58 -0
- wl_cli/commands/self/handlers/update_handler.py +102 -0
- wl_cli/commands/self/handlers/version_handler.py +16 -0
- wl_cli/commands/self/self_command.py +237 -0
- wl_cli/commands/self/services/__init__.py +15 -0
- wl_cli/commands/self/services/installation_manager.py +187 -0
- wl_cli/commands/self/services/local_installer.py +165 -0
- wl_cli/commands/self/services/pypi_updater.py +278 -0
- wl_cli/commands/self/services/windows_update.py +174 -0
- wl_cli/commands/testcommands/__init__.py +8 -0
- wl_cli/commands/testcommands/base_dependency_analyzer.py +198 -0
- wl_cli/commands/testcommands/batch_processor.py +278 -0
- wl_cli/commands/testcommands/cache_manager.py +1156 -0
- wl_cli/commands/testcommands/coverage_analyzer.py +955 -0
- wl_cli/commands/testcommands/coverage_cache_manager.py +183 -0
- wl_cli/commands/testcommands/progress_manager.py +79 -0
- wl_cli/commands/testcommands/python_env_detector.py +207 -0
- wl_cli/commands/testcommands/report_generator.py +101 -0
- wl_cli/commands/testcommands/single_test_executor.py +250 -0
- wl_cli/commands/testcommands/speed_checker.py +118 -0
- wl_cli/commands/testcommands/test_command_builder.py +165 -0
- wl_cli/commands/testcommands/test_commands.py +786 -0
- wl_cli/commands/testcommands/test_reporter.py +181 -0
- wl_cli/commands/testcommands/test_result_handler.py +96 -0
- wl_cli/commands/testcommands/test_runner.py +1343 -0
- wl_cli/commands/testcommands/test_utils.py +197 -0
- wl_cli/commands/testcommands/utils/__init__.py +17 -0
- wl_cli/commands/testcommands/utils/coverage_parser.py +98 -0
- wl_cli/commands/testcommands/utils/env_info.py +36 -0
- wl_cli/commands/testcommands/utils/junit_parser.py +75 -0
- wl_cli/commands/testcommands/utils/markdown_utils.py +20 -0
- wl_cli/commands/testcommands/utils/project_root.py +61 -0
- wl_cli/commands/update/__init__.py +9 -0
- wl_cli/commands/update/services/__init__.py +21 -0
- wl_cli/commands/update/services/backup_manager.py +207 -0
- wl_cli/commands/update/services/component_manager.py +83 -0
- wl_cli/commands/update/services/conflict_resolver.py +189 -0
- wl_cli/commands/update/services/vendors_updater.py +85 -0
- wl_cli/commands/update/services/version_tracker.py +127 -0
- wl_cli/commands/update/update_command.py +270 -0
- wl_cli/commands/update/utils/__init__.py +3 -0
- wl_cli/commands/version/__init__.py +9 -0
- wl_cli/commands/version/version_command.py +155 -0
- wl_cli/commands/workflow.py +477 -0
- wl_cli/env/__init__.py +5 -0
- wl_cli/env/cli.py +167 -0
- wl_cli/env_status.py +157 -0
- wl_cli/envelope.py +91 -0
- wl_cli/exceptions.py +85 -0
- wl_cli/lib/__init__.py +3 -0
- wl_cli/lib/rust_utils.py +35 -0
- wl_cli/mcp/__init__.py +6 -0
- wl_cli/mcp/capabilities.py +19 -0
- wl_cli/mcp/cli.py +22 -0
- wl_cli/mcp/gitlab.py +553 -0
- wl_cli/mcp/k8s.py +344 -0
- wl_cli/mcp/protocol.py +159 -0
- wl_cli/platform.py +139 -0
- wl_cli/quality/__init__.py +18 -0
- wl_cli/utils/__init__.py +7 -0
- wl_cli/utils/cache.py +491 -0
- wl_cli/utils/cache_ledger.py +355 -0
- wl_cli/utils/cache_store.py +546 -0
- wl_cli/utils/config/__init__.py +27 -0
- wl_cli/utils/config/config_loader.py +163 -0
- wl_cli/utils/config/core.py +862 -0
- wl_cli/utils/config/defaults.py +142 -0
- wl_cli/utils/config/env_exporter.py +86 -0
- wl_cli/utils/config/env_parser.py +108 -0
- wl_cli/utils/config/validation.py +280 -0
- wl_cli/utils/error_handler.py +165 -0
- wl_cli/utils/file_copier.py +56 -0
- wl_cli/utils/file_operations.py +506 -0
- wl_cli/utils/language_utils.py +122 -0
- wl_cli/utils/lazy_import.py +240 -0
- wl_cli/utils/log_levels.py +35 -0
- wl_cli/utils/log_rotators.py +74 -0
- wl_cli/utils/logging.py +458 -0
- wl_cli/utils/output_context.py +142 -0
- wl_cli/utils/performance/__init__.py +1 -0
- wl_cli/utils/performance/decorators.py +111 -0
- wl_cli/utils/performance/exporter.py +38 -0
- wl_cli/utils/performance/models.py +16 -0
- wl_cli/utils/performance/monitor.py +161 -0
- wl_cli/utils/performance_monitor.py +32 -0
- wl_cli/utils/platform_adapter.py +131 -0
- wl_cli/utils/pre_commit.py +266 -0
- wl_cli/utils/pre_commit_config.py +72 -0
- wl_cli/utils/root.py +521 -0
- wl_cli/utils/root_fallback.py +256 -0
- wl_cli/utils/run_evidence.py +236 -0
- wl_cli/utils/structured_logger.py +18 -0
- wl_cli/utils/structured_logging/__init__.py +19 -0
- wl_cli/utils/structured_logging/config.py +337 -0
- wl_cli/utils/structured_logging/core.py +177 -0
- wl_cli/utils/structured_logging/env.py +56 -0
- wl_cli/utils/structured_logging/filtering.py +75 -0
- wl_cli/utils/structured_logging/filters.py +55 -0
- wl_cli/utils/structured_logging/formatters.py +251 -0
- wl_cli/utils/structured_logging/handlers.py +308 -0
- wl_cli/utils/structured_logging/logger.py +354 -0
- wl_cli/utils/subprocess.py +71 -0
- wl_cli/utils/subprocess_utils.py +260 -0
- wl_cli/utils/test_utils/__init__.py +5 -0
- wl_cli/utils/test_utils/test_filter.py +36 -0
- wl_cli/utils/uv_run.py +79 -0
- wl_cli/utils/uv_tool.py +117 -0
- wl_cli/utils/uv_tree.py +71 -0
- wl_cli/utils/uv_workspace.py +174 -0
- wl_cli/utils/version/__init__.py +15 -0
- wl_cli/utils/version/pypi_version_checker.py +95 -0
- wl_cli/utils/version/version_comparator.py +133 -0
- wl_cli/utils/version/version_detectors.py +312 -0
- wl_cli/utils/version/version_service.py +131 -0
- wl_cli/utils/version/version_updater.py +198 -0
- wl_cli/utils/wl_dir_updater.py +1440 -0
- wl_cli/utils/workspace_detector/__init__.py +28 -0
- wl_cli/utils/workspace_detector/core.py +161 -0
- wl_cli/utils/workspace_detector/detection_strategies.py +107 -0
- wl_cli/utils/workspace_detector/exceptions.py +5 -0
- wl_cli/utils/workspace_detector/types.py +17 -0
- wl_cli/utils/workspace_detector/venv_resolver.py +84 -0
- wl_cli/vendors/config/.codespellrc +2 -0
- wl_cli/vendors/config/dependencies.toml +10 -0
- wl_cli/vendors/config/mypy.ini +62 -0
- wl_cli/vendors/config/pyproject_defaults.toml +28 -0
- wl_cli/vendors/config/template_config.toml +24 -0
- wl_cli/vendors/config/tool_configs.toml +76 -0
- wl_cli/vendors/git/.gitignore +122 -0
- wl_cli/vendors/git/.pre-commit-config.yaml +37 -0
- wl_cli/vendors/hooks/applypatch-msg.sample +15 -0
- wl_cli/vendors/hooks/commit-msg.sample +24 -0
- wl_cli/vendors/hooks/fsmonitor-watchman.sample +174 -0
- wl_cli/vendors/hooks/post-update.sample +8 -0
- wl_cli/vendors/hooks/pre-applypatch.sample +14 -0
- wl_cli/vendors/hooks/pre-commit +45 -0
- wl_cli/vendors/hooks/pre-commit.legacy +31 -0
- wl_cli/vendors/hooks/pre-commit.sample +49 -0
- wl_cli/vendors/hooks/pre-merge-commit.sample +13 -0
- wl_cli/vendors/hooks/pre-push.sample +60 -0
- wl_cli/vendors/hooks/pre-rebase.sample +169 -0
- wl_cli/vendors/hooks/pre-receive.sample +24 -0
- wl_cli/vendors/hooks/prepare-commit-msg.sample +42 -0
- wl_cli/vendors/hooks/push-to-checkout.sample +78 -0
- wl_cli/vendors/hooks/sendemail-validate.sample +77 -0
- wl_cli/vendors/hooks/unix/applypatch-msg.sample +15 -0
- wl_cli/vendors/hooks/unix/check_lockfile.py +58 -0
- wl_cli/vendors/hooks/unix/check_lockfile.sh +36 -0
- wl_cli/vendors/hooks/unix/commit-msg.sample +24 -0
- wl_cli/vendors/hooks/unix/fsmonitor-watchman.sample +174 -0
- wl_cli/vendors/hooks/unix/post-update.sample +8 -0
- wl_cli/vendors/hooks/unix/pre-applypatch.sample +14 -0
- wl_cli/vendors/hooks/unix/pre-commit +190 -0
- wl_cli/vendors/hooks/unix/pre-commit.legacy +31 -0
- wl_cli/vendors/hooks/unix/pre-commit.py +81 -0
- wl_cli/vendors/hooks/unix/pre-commit.sample +49 -0
- wl_cli/vendors/hooks/unix/pre-merge-commit.sample +13 -0
- wl_cli/vendors/hooks/unix/pre-push +417 -0
- wl_cli/vendors/hooks/unix/pre-push.sample +53 -0
- wl_cli/vendors/hooks/unix/pre-rebase.sample +169 -0
- wl_cli/vendors/hooks/unix/pre-receive.sample +24 -0
- wl_cli/vendors/hooks/unix/prepare-commit-msg.sample +42 -0
- wl_cli/vendors/hooks/update.sample +128 -0
- wl_cli/vendors/hooks/win/work.bat +63 -0
- wl_cli/vendors/project/.gitignore +90 -0
- wl_cli/vendors/project/.python-version +1 -0
- wl_cli/vendors/project/LICENSE +21 -0
- wl_cli/vendors/project/README.md +0 -0
- wl_cli/vendors/project/pyproject.toml +27 -0
- wl_cli/vendors/project/pyproject_no_workspace.toml +16 -0
- wl_cli/vendors/project/pyproject_workspace.toml +14 -0
- wl_cli/vendors/readme/README.md +120 -0
- wl_cli/vendors/rust/Cargo.toml +14 -0
- wl_cli/vendors/rust/lib/__init__.py +3 -0
- wl_cli/vendors/rust/lib/rust_utils.py +31 -0
- wl_cli/vendors/rust/src/lib.rs +13 -0
- wl_cli/vendors/rust/src/main.rs +3 -0
- wl_cli/vendors/rust/tests/test_rust_fallback.py +40 -0
- wl_cli/vendors/sop_doc/git-dev-sop.md +220 -0
- wl_cli/vendors/sop_doc/industrial-standard-sop.md +145 -0
- wl_cli/vendors/sop_doc/python-sop.md +342 -0
- wl_cli/vendors/sop_doc/rust-readme.md +219 -0
|
@@ -0,0 +1,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,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
|