Coverage for src / rhiza_tools / config.py: 100%

29 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-02-23 01:10 +0000

1"""Configuration management for rhiza-tools. 

2 

3This module provides configuration loading and access for rhiza-tools. 

4It reads configuration from a TOML file and provides convenient access 

5to tool-specific settings. 

6 

7Example: 

8 Load configuration from default path:: 

9 

10 from rhiza_tools.config import load_config 

11 

12 config = load_config() 

13 bumpversion_config = config.bumpversion 

14 

15 Load configuration from custom path:: 

16 

17 from pathlib import Path 

18 from rhiza_tools.config import load_config 

19 

20 config = load_config(Path("custom/.cfg.toml")) 

21 value = config.get("custom_key", "default_value") 

22""" 

23 

24from pathlib import Path 

25from typing import Any 

26 

27import tomlkit 

28from loguru import logger 

29 

30from rhiza_tools import console 

31 

32CONFIG_FILENAME = ".rhiza/.cfg.toml" 

33 

34 

35class RhizaConfig: 

36 """Rhiza tools configuration. 

37 

38 Manages loading and accessing configuration from a TOML file. Provides 

39 convenient access to tool-specific configuration sections. 

40 

41 Attributes: 

42 config_path: Path to the configuration TOML file. 

43 

44 Example: 

45 Basic usage:: 

46 

47 config = RhizaConfig() 

48 bumpversion = config.bumpversion 

49 custom_value = config.get("my_key", "default") 

50 

51 With custom path:: 

52 

53 config = RhizaConfig(Path("custom/.cfg.toml")) 

54 config.load() 

55 """ 

56 

57 def __init__(self, config_path: Path | None = None): 

58 """Initialize RhizaConfig. 

59 

60 Args: 

61 config_path: Path to the configuration file. If None, uses the 

62 default path defined in CONFIG_FILENAME. 

63 """ 

64 self.config_path = config_path or Path(CONFIG_FILENAME) 

65 self._data: dict[str, Any] = {} 

66 self.load() 

67 

68 def load(self) -> None: 

69 """Load configuration from file. 

70 

71 Reads and parses the TOML configuration file. If the file doesn't exist, 

72 the configuration will be empty. Logs errors if parsing fails. 

73 

74 Raises: 

75 Exception: If the configuration file exists but cannot be parsed. 

76 

77 Example: 

78 config = RhizaConfig(Path("custom/.cfg.toml")) 

79 config.load() 

80 """ 

81 if not self.config_path.exists(): 

82 logger.debug(f"Configuration file {self.config_path} not found.") 

83 return 

84 

85 try: 

86 with open(self.config_path) as f: 

87 self._data = tomlkit.parse(f.read()) 

88 except Exception as e: 

89 console.error(f"Failed to parse configuration file {self.config_path}: {e}") 

90 raise 

91 

92 @property 

93 def bumpversion(self) -> dict[str, Any]: 

94 """Get bumpversion configuration. 

95 

96 Returns: 

97 Dictionary containing bumpversion-specific configuration from the 

98 [tool.bumpversion] section of the configuration file. 

99 

100 Example: 

101 config = RhizaConfig() 

102 bv_config = config.bumpversion 

103 print(bv_config.get("current_version")) 

104 """ 

105 result: dict[str, Any] = self._data.get("tool", {}).get("bumpversion", {}) 

106 return result 

107 

108 def get(self, key: str, default: Any = None) -> Any: 

109 """Get configuration value. 

110 

111 Args: 

112 key: Configuration key to retrieve. 

113 default: Default value to return if key is not found. 

114 

115 Returns: 

116 The configuration value for the given key, or default if not found. 

117 

118 Example: 

119 config = RhizaConfig() 

120 value = config.get("custom_setting", "default_value") 

121 """ 

122 return self._data.get(key, default) 

123 

124 

125def load_config(path: Path | None = None) -> RhizaConfig: 

126 """Load configuration. 

127 

128 Convenience function to create and load a RhizaConfig instance. 

129 

130 Args: 

131 path: Path to the configuration file. If None, uses the default path. 

132 

133 Returns: 

134 A RhizaConfig instance with the configuration loaded. 

135 

136 Example: 

137 Load default configuration:: 

138 

139 config = load_config() 

140 

141 Load from custom path:: 

142 

143 from pathlib import Path 

144 config = load_config(Path("custom/.cfg.toml")) 

145 """ 

146 return RhizaConfig(path)