Test Failed
Branch v4.0-dev (e44d7e)
by Emmanuel
04:49
created

configreader.Config._parse()   A

Complexity

Conditions 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 2

Importance

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