Coverage for src/qdrant_loader/cli/config_loader.py: 56%

73 statements  

« prev     ^ index     » next       coverage.py v7.10.6, created at 2025-09-08 06:05 +0000

1from __future__ import annotations 

2 

3from pathlib import Path 

4from typing import Any 

5 

6from click.exceptions import ClickException 

7 

8from qdrant_loader.config.state import DatabaseDirectoryError 

9from qdrant_loader.utils.logging import LoggingConfig 

10 

11 

12# Back-compat shim for tests that import _get_logger from cli.cli 

13def _get_logger(): 

14 return LoggingConfig.get_logger(__name__) 

15 

16 

17def setup_workspace(workspace_path: Path): 

18 try: 

19 from qdrant_loader.config.workspace import ( 

20 create_workspace_structure, 

21 ) 

22 from qdrant_loader.config.workspace import setup_workspace as _setup 

23 

24 create_workspace_structure(workspace_path) 

25 workspace_config = _setup(workspace_path) 

26 logger = LoggingConfig.get_logger(__name__) 

27 logger.info("Using workspace", workspace=str(workspace_config.workspace_path)) 

28 if workspace_config.env_path: 

29 logger.info( 

30 "Environment file found", env_path=str(workspace_config.env_path) 

31 ) 

32 if workspace_config.config_path: 

33 logger.info( 

34 "Config file found", config_path=str(workspace_config.config_path) 

35 ) 

36 return workspace_config 

37 except ValueError as e: 

38 raise ClickException(str(e)) from e 

39 except Exception as e: # pragma: no cover - handled by CLI tests 

40 raise ClickException(f"Failed to setup workspace: {str(e)!s}") from e 

41 

42 

43def load_config_with_workspace( 

44 workspace_config: Any | None = None, 

45 config_path: Path | None = None, 

46 env_path: Path | None = None, 

47 skip_validation: bool = False, 

48) -> None: 

49 try: 

50 from qdrant_loader.config import initialize_config_with_workspace 

51 

52 if workspace_config: 

53 LoggingConfig.get_logger(__name__).debug( 

54 "Loading configuration in workspace mode" 

55 ) 

56 initialize_config_with_workspace( 

57 workspace_config, skip_validation=skip_validation 

58 ) 

59 else: 

60 LoggingConfig.get_logger(__name__).debug( 

61 "Loading configuration in traditional mode" 

62 ) 

63 load_config(config_path, env_path, skip_validation) 

64 except Exception as e: 

65 LoggingConfig.get_logger(__name__).error("config_load_failed", error=str(e)) 

66 raise ClickException(f"Failed to load configuration: {str(e)!s}") from e 

67 

68 

69def create_database_directory(path: Path) -> bool: 

70 try: 

71 abs_path = path.resolve() 

72 LoggingConfig.get_logger(__name__).info( 

73 "The database directory does not exist", path=str(abs_path) 

74 ) 

75 import click 

76 

77 if click.confirm("Would you like to create this directory?", default=True): 

78 abs_path.mkdir(parents=True, mode=0o755, exist_ok=True) 

79 LoggingConfig.get_logger(__name__).info("Created directory: %s", abs_path) 

80 return True 

81 return False 

82 except Exception as e: # pragma: no cover - interactive path 

83 raise ClickException(f"Failed to create directory: {str(e)!s}") from e 

84 

85 

86def load_config( 

87 config_path: Path | None = None, 

88 env_path: Path | None = None, 

89 skip_validation: bool = False, 

90) -> None: 

91 try: 

92 from qdrant_loader.config import initialize_config 

93 

94 if config_path is not None: 

95 if not config_path.exists(): 

96 LoggingConfig.get_logger(__name__).error( 

97 "config_not_found", path=str(config_path) 

98 ) 

99 raise ClickException(f"Config file not found: {str(config_path)!s}") 

100 initialize_config(config_path, env_path, skip_validation=skip_validation) 

101 return 

102 

103 default_config = Path("config.yaml") 

104 if default_config.exists(): 

105 initialize_config(default_config, env_path, skip_validation=skip_validation) 

106 return 

107 

108 raise ClickException( 

109 f"No config file found. Please specify a config file or create config.yaml in the current directory: {str(default_config)!s}" 

110 ) 

111 

112 except DatabaseDirectoryError as e: 

113 if skip_validation: 

114 return 

115 error_path = e.path 

116 abs_path = error_path.resolve() 

117 if not create_database_directory(abs_path): 

118 raise ClickException( 

119 "Database directory creation declined. Exiting." 

120 ) from e 

121 # After successful creation, initialize once using the original config_path if provided, 

122 # otherwise fall back to default config.yaml 

123 from qdrant_loader.config import initialize_config 

124 

125 target_config = config_path if config_path is not None else Path("config.yaml") 

126 initialize_config(target_config, env_path, skip_validation=skip_validation) 

127 except ClickException: 

128 raise 

129 except Exception as e: 

130 LoggingConfig.get_logger(__name__).error("config_load_failed", error=str(e)) 

131 raise ClickException(f"Failed to load configuration: {str(e)!s}") from e