Coverage for src/qdrant_loader/cli/commands/init_cmd.py: 0%
81 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-08 06:05 +0000
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-08 06:05 +0000
1from __future__ import annotations
3from pathlib import Path
5from click.exceptions import ClickException
7from qdrant_loader.cli.config_loader import (
8 load_config_with_workspace as _load_config_with_workspace,
9)
10from qdrant_loader.cli.config_loader import setup_workspace as _setup_workspace_impl
11from qdrant_loader.cli.path_utils import (
12 create_database_directory as _create_db_dir_helper,
13)
14from qdrant_loader.cli.update_check import check_for_updates as _check_updates_helper
15from qdrant_loader.cli.version import get_version_str as _get_version_str
16from qdrant_loader.config import get_settings
17from qdrant_loader.config.state import DatabaseDirectoryError
18from qdrant_loader.config.workspace import validate_workspace_flags
19from qdrant_loader.utils.logging import LoggingConfig
21from . import run_init as _commands_run_init
24async def run_init_command(
25 workspace: Path | None,
26 config: Path | None,
27 env: Path | None,
28 force: bool,
29 log_level: str,
30 max_retries: int = 1,
31) -> None:
32 """Implementation for the `init` CLI command.
34 Keeps side-effects and logging identical to the previous inline implementation.
35 """
36 attempts = 0
37 while True:
38 try:
39 # Validate flag combinations
40 validate_workspace_flags(workspace, config, env)
42 # Setup logging first (workspace-aware later)
43 LoggingConfig.setup(
44 level=log_level, format="console", file="qdrant-loader.log"
45 )
46 logger = LoggingConfig.get_logger(__name__)
48 # Check for updates (non-blocking semantics preserved by immediate return)
49 try:
50 _check_updates_helper(_get_version_str())
51 except Exception:
52 # Update check failures should not break the command
53 pass
55 # Setup workspace if provided
56 workspace_config = None
57 if workspace:
58 workspace_config = _setup_workspace_impl(workspace)
59 logger.info(
60 "Using workspace", workspace=str(workspace_config.workspace_path)
61 )
62 if getattr(workspace_config, "env_path", None):
63 logger.info(
64 "Environment file found",
65 env_path=str(workspace_config.env_path),
66 )
67 if getattr(workspace_config, "config_path", None):
68 logger.info(
69 "Config file found",
70 config_path=str(workspace_config.config_path),
71 )
73 # Setup logging again with workspace-aware file path
74 log_file = (
75 str(workspace_config.logs_path)
76 if workspace_config
77 else "qdrant-loader.log"
78 )
79 LoggingConfig.setup(level=log_level, format="console", file=log_file)
81 # Load configuration
82 _load_config_with_workspace(workspace_config, config, env)
84 # Fetch settings
85 settings = get_settings()
86 if settings is None:
87 logger.error("settings_not_available")
88 raise ClickException("Settings not available")
90 # Delete and recreate the database file if it exists
91 db_path_str = settings.global_config.state_management.database_path
92 if db_path_str != ":memory:":
93 db_path = Path(db_path_str)
94 db_dir = db_path.parent
95 if not db_dir.exists():
96 if not _create_database_directory(db_dir):
97 raise ClickException(
98 "Database directory creation declined. Exiting."
99 )
101 if db_path.exists() and force:
102 logger.info("Resetting state database", database_path=str(db_path))
103 db_path.unlink()
104 logger.info(
105 "State database reset completed", database_path=str(db_path)
106 )
107 elif force:
108 logger.info(
109 "State database reset skipped (no existing database)",
110 database_path=str(db_path),
111 )
113 # Run initialization via command helper
114 await _commands_run_init(settings, force)
115 if force:
116 logger.info(
117 "Collection recreated successfully",
118 collection=settings.qdrant_collection_name,
119 )
120 else:
121 logger.info(
122 "Collection initialized successfully",
123 collection=settings.qdrant_collection_name,
124 )
126 # Completed successfully
127 return
129 except DatabaseDirectoryError as e:
130 # Mirror original behavior for directory creation prompts, then retry if allowed
131 if workspace is None:
132 # derive from current directory
133 target = Path(e.path).resolve()
134 else:
135 target = e.path.resolve()
136 if not _create_database_directory(target):
137 raise ClickException(
138 "Database directory creation declined. Exiting."
139 ) from e
141 if attempts >= max_retries:
142 raise ClickException(
143 "Initialization aborted after exhausting retries for database directory creation."
144 ) from e
145 attempts += 1
146 continue
148 except ClickException:
149 raise
150 except Exception as e:
151 logger = LoggingConfig.get_logger(__name__)
152 logger.error("init_failed", error=str(e))
153 raise ClickException(f"Failed to initialize collection: {str(e)!s}") from e
156def _create_database_directory(path: Path) -> bool:
157 """Create database directory with logging (non-interactive)."""
158 try:
159 abs_path = path.resolve()
160 LoggingConfig.get_logger(__name__).info(
161 "The database directory does not exist", path=str(abs_path)
162 )
163 created = _create_db_dir_helper(abs_path)
164 if created:
165 LoggingConfig.get_logger(__name__).info(f"Created directory: {abs_path}")
166 return created
167 except Exception as e: # pragma: no cover - error path
168 raise ClickException(f"Failed to create directory: {str(e)!s}") from e