Passed
Branch v4.0-dev (e005f1)
by Emmanuel
05:49
created

configreader   A

Complexity

Total Complexity 8

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Test Coverage

Coverage 94.87%

Importance

Changes 0
Metric Value
wmc 8
eloc 45
dl 0
loc 81
ccs 37
cts 39
cp 0.9487
rs 10
c 0
b 0
f 0
1
# coding: utf-8
2 1
"""Simple Config Reader."""
3
4 1
import anyconfig
5 1
from sys import stderr
6 1
from jsonschema.exceptions import _Error
7 1
from stakkr.file_utils import get_file, find_project_dir
8 1
from os import path
9
10
11 1
class Config:
12
    """
13
    Parser of Stakkr.
14
15
    Set default values and validate conf/compose.ini with conf/configspec.ini.
16
    """
17
18 1
    def __init__(self, config_file: str):
19
        """
20
        Build list of files to validate a config, set default values
21
        Then the given config file
22
        """
23
24 1
        if config_file is not None:
25 1
            self.config_file = path.abspath(config_file)
26 1
            self.project_dir = path.dirname(self.config_file)
27
        else:
28 1
            self.project_dir = find_project_dir()
29
            self.config_file = '{}/stakkr.yml'.format(self.project_dir)
30
31 1
        self._build_config_files_list()
32 1
        self._build_config_schemas_list()
33 1
        self.error = ''
34
35 1
    def display_errors(self):
36
        """Display errors in STDOUT."""
37 1
        from click import style
38
39 1
        msg = 'Failed validating main config or plugin configs ('
40 1
        msg += ', '.join(self.config_files)
41 1
        msg += '):\n    - {}'.format(self.error)
42 1
        stderr.write(style(msg, fg='red'))
43
44 1
    def read(self):
45
        """
46
        Parse the configs and validate it.
47
48
        It could be either local or from a plugin or local services
49
        (first local then packages by alphabetical order).
50
        """
51 1
        schema = anyconfig.multi_load(self.spec_files)
52 1
        config = anyconfig.multi_load(self.config_files)
53
        # Make sure the compiled configuration is valid
54 1
        try:
55 1
            anyconfig.validate(config, schema, safe=False)
56 1
        except _Error as error:
57 1
            self.error = '{} ({})'.format(error.message, ' -> '.join(error.path))
58 1
            return False
59
60 1
        config['project_dir'] = path.realpath(path.dirname(self.config_file))
61 1
        if config['project_name'] == '':
62 1
            config['project_name'] = path.basename(config['project_dir'])
63
64 1
        return config
65
66 1
    def _build_config_files_list(self):
67 1
        self.config_files = [
68
            # Stakkr default config
69
            get_file('static', 'config_default.yml'),
70
            # plugins default config
71
            '{}/plugins/*/config_default.yml'.format(self.project_dir),
72
            '{}/services/*/config_default.yml'.format(self.project_dir)]
73
        # Stakkr main config file finally with user's values
74 1
        self.config_files += [self.config_file]
75
76 1
    def _build_config_schemas_list(self):
77 1
        self.spec_files = [
78
            # Stakkr config validation
79
            get_file('static', 'config_schema.yml'),
80
            # plugins config validation
81
            '{}/plugins/*/config_schema.yml'.format(self.project_dir),
82
            '{}/services/*/config_schema.yml'.format(self.project_dir)]
83