1
|
|
|
import types |
2
|
|
|
from pathlib import Path |
3
|
|
|
import logging |
4
|
|
|
import os |
5
|
|
|
|
6
|
|
|
from groundwork.configuration.exceptions import InvalidParameter |
7
|
|
|
from groundwork.configuration.config import Config |
8
|
|
|
|
9
|
|
|
|
10
|
|
|
class ConfigManager: |
11
|
|
|
""" |
12
|
|
|
Loads different configuration files and sets their attributes as attributes of its own instance. |
13
|
|
|
|
14
|
|
|
A configuration file must be an importable python file. |
15
|
|
|
|
16
|
|
|
Only uppercase attributes are loaded. Everything else is ignored. Example:: |
17
|
|
|
|
18
|
|
|
import os |
19
|
|
|
APP_NAME = "My APP" # Is used |
20
|
|
|
APP_PATH = os.path.abspath(".") # Is used |
21
|
|
|
app_test = "test" # Is NOT used |
22
|
|
|
MY_OWN_VAR = "nice" # Is used |
23
|
|
|
""" |
24
|
|
|
def __init__(self, config_files=[]): |
25
|
|
|
#: An instance of :class:`~groundwork.configuration.configmanager.Config` for storing all |
26
|
|
|
#: configuration parameters. |
27
|
|
|
self.config = None |
28
|
|
|
|
29
|
|
|
self.log = logging.getLogger(__name__) |
30
|
|
|
self.log.debug("Starting Configuration initialisation") |
31
|
|
|
self.invalid_parameters = ["FILES"] |
32
|
|
|
|
33
|
|
|
if isinstance(config_files, list): |
34
|
|
|
self.config_files = config_files |
35
|
|
|
else: |
36
|
|
|
raise TypeError("config_files must be a list of strings") |
37
|
|
|
|
38
|
|
|
absolute_files = [] |
39
|
|
|
for file in config_files: |
40
|
|
|
if not isinstance(file, str): |
41
|
|
|
raise TypeError("config_files members must be strings") |
42
|
|
|
try: |
43
|
|
|
absolute_file = Path(file).resolve() |
44
|
|
|
except FileNotFoundError: |
45
|
|
|
self.log.warning("Config-file not found %s" % file) |
46
|
|
|
continue |
47
|
|
|
else: |
48
|
|
|
absolute_files.append(str(absolute_file)) |
49
|
|
|
|
50
|
|
|
self.config_files = absolute_files |
51
|
|
|
|
52
|
|
|
def load(self, config_files): |
53
|
|
|
""" |
54
|
|
|
Creates a configuration instance from class :class:`~groundwork.configuration.configmanager.Config` from all |
55
|
|
|
files in self.files and set the dictionary items as attributes of of this instance. |
56
|
|
|
|
57
|
|
|
:return: Instance of :class:`~groundwork.configuration.configmanager.Config` |
58
|
|
|
""" |
59
|
|
|
config = Config() |
60
|
|
|
|
61
|
|
|
for config_file in config_files: |
62
|
|
|
if not os.path.isabs(config_file): |
63
|
|
|
config_file = os.path.join(os.getcwd(), config_file) |
64
|
|
|
|
65
|
|
|
self.log.debug("Loading configuration from %s" % config_file) |
66
|
|
|
d = types.ModuleType('config') |
67
|
|
|
d.__file__ = config_file |
68
|
|
|
try: |
69
|
|
|
with open(config_file) as current_config_file: |
70
|
|
|
exec(compile(current_config_file.read(), config_file, 'exec'), d.__dict__) |
71
|
|
|
except IOError as e: |
72
|
|
|
e.strerror = 'Unable to load configuration file (%s)' % e.strerror |
73
|
|
|
raise |
74
|
|
|
for key in dir(d): |
75
|
|
|
if key.isupper(): |
76
|
|
|
if key not in self.invalid_parameters: |
77
|
|
|
setattr(config, key, getattr(d, key)) |
78
|
|
|
else: |
79
|
|
|
raise InvalidParameter("%s is not allowed as name for a configuration parameter" % key) |
80
|
|
|
return config |
81
|
|
|
|