Completed
Push — develop ( 94bf94...058985 )
by Jace
02:22
created

parse_config()   A

Complexity

Conditions 3

Size

Total Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
c 0
b 0
f 0
dl 0
loc 13
rs 9.4285
ccs 10
cts 10
cp 1
crap 3
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4 1
import os
5 1
import sys
6 1
import argparse
7 1
try:
8 1
    import configparser  # Python 3
9
except ImportError:
10
    import ConfigParser as configparser  # Python 2
11 1
import subprocess
12 1
import logging
13
14
15 1
CONFIG_FILENAMES = ['.verchew', '.verchewrc', 'verchew.ini', '.verchew.ini']
16
17 1
log = logging.getLogger(__name__)
18
19
20 1
def main():
21 1
    args = parse_args()
22
    configure_logging(args.verbose)
23
    path = find_config()
24
    config = parse_config(path)
25
    if not check_dependencies(config):
26
        sys.exit(1)
27
28
29 1
def parse_args():
30 1
    parser = argparse.ArgumentParser()
31
    # TODO: add '--version' option
32
    # parser.add_argument('-V', '--version', action='version', version=VERSION)
33 1
    parser.add_argument('-v', '--verbose', action='count', default=0,
34
                        help="enable verbose logging")
35
36 1
    return parser.parse_args()
37
38
39 1
def configure_logging(count=0):
40
    if count == 0:
41
        level = logging.WARNING
42
    elif count == 1:
43
        level = logging.INFO
44
    else:
45
        level = logging.DEBUG
46
47
    logging.basicConfig(level=level, format="%(levelname)s: %(message)s")
48
49
50 1
def find_config(root=None, config_filenames=None):
51 1
    root = root or os.getcwd()
52 1
    config_filenames = config_filenames or CONFIG_FILENAMES
53
54 1
    path = None
55 1
    log.info("Looking for config file in: %s", root)
56 1
    log.debug("Filename options: %s", ", ".join(config_filenames))
57 1
    for filename in os.listdir(root):
58 1
        if filename in config_filenames:
59 1
            path = os.path.join(root, filename)
60 1
            log.info("Found config file: %s", path)
61 1
            return path
62
63 1
    msg = "No config file found in: {0}".format(root)
64 1
    raise RuntimeError(msg)
65
66
67 1
def parse_config(path):
68 1
    data = {}
69
70 1
    log.info("Parsing config file: %s", path)
71 1
    config = configparser.ConfigParser()
72 1
    config.read(path)
73
74 1
    for section in config.sections():
75 1
        data[section] = {}
76 1
        for name, value in config.items(section):
77 1
            data[section][name] = value
78
79 1
    return data
80
81
82 1
def check_dependencies(config):
83
    success = []
84
85
    for name, settings in config.items():
86
        show("Checking the version of {0}...".format(name), head=True)
87
        output = get_version(settings['cli'])
88
        if settings['version'] in output:
89
            show("✔ MATCHED: {0}".format(settings['version']))
90
            success.append("✔")
91
        else:
92
            show("✖ EXPECTED: {0}".format(settings['version']))
93
            success.append("✖")
94
95
    show("Results: " + " ".join(success), head=True)
96
97
    return "✖" not in success
98
99
100 1
def get_version(program):
101 1
    args = [program, '--version']
102
103 1
    show("$ {0}".format(" ".join(args)))
104 1
    try:
105 1
        output = subprocess.check_output(args, stderr=subprocess.STDOUT)
106 1
    except OSError:
107 1
        output = "command not found"
108 1
    log.debug("Command output: %r", output)
109
110 1
    show(output.splitlines()[0])
111
112 1
    return output
113
114
115 1
def show(text, start='', end='\n', head=False):
116
    """Python 2 and 3 compatible version of print."""
117 1
    if head:
118
        start = '\n'
119
        end = '\n\n'
120
121 1
    if log.getEffectiveLevel() < logging.WARNING:
122 1
        log.info(text)
123
    else:
124
        sys.stdout.write(start + text + end)
125
126
127
if __name__ == '__main__':  # pragma: no cover
128
    main()
129