Ticket #8290: config-provider.patch
| File config-provider.patch, 6.9 KB (added by Joachim Hoessler <hoessler@…>, 3 years ago) |
|---|
-
trac/env.py
36 36 from trac.versioncontrol import RepositoryManager 37 37 from trac.web.href import Href 38 38 39 __all__ = ['Environment', 'IEnvironmentSetupParticipant', 'open_environment'] 39 __all__ = ['Environment', 'IEnvironmentSetupParticipant', 'open_environment', 40 'IConfigurationProvider'] 40 41 41 42 43 class IConfigurationProvider(Interface): 44 """Extension point interface for components that want to provide configuration 45 settings.""" 46 47 def sections(): 48 """Return a list of section names.""" 49 50 def has_section(section): 51 """Returns True if option exists in section.""" 52 53 def options(section): 54 """Return a list of `(name, value)` tuples for every option in the 55 specified section.""" 56 57 def has_option(section, option): 58 """Returns True if option exists in section.""" 59 60 def get(section, option): 61 """Return the value of the specified option. 62 63 Valid default input is a string. Returns a string. 64 """ 65 66 42 67 class IEnvironmentSetupParticipant(Interface): 43 68 """Extension point interface for components that need to participate in the 44 69 creation and upgrading of Trac environments, for example to create … … 74 99 * wiki and ticket attachments. 75 100 """ 76 101 setup_participants = ExtensionPoint(IEnvironmentSetupParticipant) 102 config_provider = ExtensionPoint(IConfigurationProvider) 77 103 78 104 shared_plugins_dir = PathOption('inherit', 'plugins_dir', '', 79 105 """Path of the directory containing additional plugins. … … 210 236 if create: 211 237 for setup_participant in self.setup_participants: 212 238 setup_participant.environment_created() 239 self.config.config_provider.extend(self.config_provider) 213 240 214 241 def component_activated(self, component): 215 242 """Initialize additional member variables for components. -
trac/config.py
43 43 self.filename = filename 44 44 self.parser = ConfigParser() 45 45 self.parent = None 46 self.config_provider = [] 46 47 self._lastmtime = 0 47 48 self._sections = {} 48 49 self.parse_if_needed() … … 145 146 while parent: 146 147 sections |= set(parent.parser.sections()) 147 148 parent = parent.parent 149 for provider in self.config_provider: 150 sections |= set(provider.sections()) 148 151 return sorted(sections) 149 152 150 153 def has_option(self, section, option): … … 162 165 for parent_option, val in self.parent.options(section): 163 166 if parent_option == option: 164 167 return True 168 # check additional provider 169 for provider in self.config_provider: 170 if provider.has_option(section, option): 171 return True 165 172 # Check the registry 166 173 if (section, option) in Option.registry: 167 174 return True … … 253 260 if self.config.parser.has_option(self.name, name): 254 261 return True 255 262 if self.config.parent: 256 return name in self.config.parent[self.name] 263 if name in self.config.parent[self.name]: 264 return True 265 for provider in self.config.config_provider: 266 if provider.has_option(self.name, name): 267 return True 257 268 return False 258 269 259 270 def __iter__(self): … … 265 276 if self.config.parent: 266 277 for option in self.config.parent[self.name]: 267 278 if option.lower() not in options: 279 options.add(option.lower()) 268 280 yield option 281 for provider in self.config.config_provider: 282 if provider.has_section(self.name): 283 for option in provider.options(self.name): 284 if option.lower() not in options: 285 options.add(option.lower()) 286 yield option 269 287 270 288 def __repr__(self): 271 289 return '<Section [%s]>' % (self.name) 290 291 def _get(self, name): 292 if self.config.parser.has_option(self.name, name): 293 return self.config.parser.get(self.name, name) 294 elif self.config.parent: 295 return self.config.parent[self.name]._get(name) 296 return None 297 272 298 273 299 def get(self, name, default=''): 274 300 """Return the value of the specified option. 275 301 276 302 Valid default input is a string. Returns a string. 277 303 """ 278 if self.config.parser.has_option(self.name, name): 279 value = self.config.parser.get(self.name, name) 280 elif self.config.parent: 281 value = self.config.parent[self.name].get(name, default) 282 else: 304 value = self._get(name) 305 306 if not value: 307 for provider in self.config.config_provider: 308 if provider.has_option(self.name, name): 309 value = provider.get(self.name, name) 310 311 if not value: 283 312 option = Option.registry.get((self.name, name)) 284 313 if option: 285 314 value = option.default or default -
trac/tests/config.py
244 244 finally: 245 245 os.remove(sitename) 246 246 247 def test_with_provider(self): 248 class mock_provider(object): 249 def sections(self): 250 return ['a', 'b'] 251 def options(self, section): 252 if section == 'a': 253 return ['option_a'] 254 if section == 'b': 255 return ['option_b'] 256 else: 257 return None 258 def has_section(self, section): 259 return section in self.sections() 260 def has_option(self, section, option): 261 return ((section == 'a' and option == 'option_a') 262 or (section == 'b' and option == 'option_b')) 263 def get(self, section, option): 264 if section == 'a' and option == 'option_a': 265 return 'y' 266 if section == 'b' and option == 'option_b': 267 return 'z' 268 provider = mock_provider() 269 self._write(['[a]', 'option = x']) 270 config = self._read() 271 config.config_provider.append(provider) 272 self.assertEquals('x', config.get('a', 'option')) 273 self.assertEquals('y', config.get('a', 'option_a')) 274 self.assertEquals('z', config.get('b', 'option_b')) 275 self.assertEquals([('option', u'x'), ('option_a', u'y')], list(config.options('a'))) 247 276 248 277 def suite(): 249 278 return unittest.makeSuite(ConfigurationTestCase, 'test')
