Completed
Push — master ( 6fd567...f65269 )
by Daniel
90:27 queued 15s
created

ConfigManager.load()   D

Complexity

Conditions 8

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 8
c 2
b 0
f 0
dl 0
loc 29
rs 4
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