coveragespace.cli.main()   A
last analyzed

Complexity

Conditions 5

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 16
nop 0
dl 0
loc 22
ccs 12
cts 12
cp 1
crap 5
rs 9.1333
c 0
b 0
f 0
1
"""Update project metrics on The Coverage Space.
2
3
Usage:
4
  coveragespace <owner/repo> <metric> [<value>] [--verbose] [--exit-code]
5
  coveragespace <owner/repo> --reset [--verbose]
6
  coveragespace (-h | --help)
7
  coveragespace (-V | --version)
8
9
Options:
10
  -h --help         Show this help screen.
11
  -V --version      Show the program version.
12
  -v --verbose      Always display the coverage metrics.
13
  -x --exit-code    Return non-zero exit code on failures.
14
15
"""
16
17 1
18
import json
19 1
import sys
20 1
from shutil import get_terminal_size
21 1
22
import colorama
23 1
import log
24 1
from docopt import DocoptExit, docopt
25 1
26 1
from . import API, VERSION, client, services
27
from .plugins import get_coverage, launch_report
28 1
29 1
30 1
def main():
31
    """Parse command-line arguments, configure logging, and run the program."""
32
    colorama.init(autoreset=True)
33 1
    arguments = docopt(__doc__, version=VERSION)
34
35
    slug = arguments['<owner/repo>']
36 1
    metric = arguments['<metric>']
37
    reset = arguments['--reset']
38 1
    value = arguments['<value>']
39 1
    verbose = arguments['--verbose']
40
    hardfail = arguments['--exit-code']
41 1
42 1
    log.reset()
43 1
    log.init(level=log.DEBUG if verbose else log.WARNING)
44 1
45 1
    if '/' not in slug:
46 1
        raise DocoptExit("<owner/repo> slug must contain a slash" + '\n')
47
48 1
    success = run(slug, metric, value, reset, verbose, hardfail)
49
50
    if not success and hardfail:
51
        sys.exit(1)
52
53 1
54 1
def run(*args, **kwargs):
55
    """Run the program."""
56 1
    if services.detected():
57
        log.info("Coverage check skipped when running on CI service")
58 1
        return True
59 1
60
    return call(*args, **kwargs)
61
62 1
63
def call(slug, metric, value, reset=False, verbose=False, hardfail=False):
64 1
    """Call the API and display errors."""
65 1
    url = "{}/{}".format(API, slug)
66 1
    if reset:
67
        data = {metric: None}
68 1
        response = client.delete(url, data)
69
    else:
70
        data = {metric: value or get_coverage()}
71 1
        response = client.get(url, data)
72
73 1
    if response.status_code == 200:
74 1
        if verbose:
75 1
            display("coverage increased", response.json(), colorama.Fore.GREEN)
76 1
        return True
77
78 1
    if response.status_code == 202:
79 1
        display("coverage reset", response.json(), colorama.Fore.BLUE)
80
        return True
81 1
82 1
    if response.status_code == 422:
83 1
        color = colorama.Fore.RED if hardfail else colorama.Fore.YELLOW
84 1
        data = response.json()
85
        message = "To reset metrics, run: ^coveragespace {} --reset$".format(slug)
86 1
        data['help'] = message  # type: ignore
87 1
        display("coverage decreased", data, color)
88 1
        launch_report()
89
        return False
90 1
91 1
    try:
92 1
        data = response.json()
93 1
        display("coverage unknown", data, colorama.Fore.RED)
94
    except (TypeError, ValueError) as exc:
95 1
        data = response.data.decode('utf-8')
96 1
        log.error("%s\n\nwhen decoding response:\n\n%s\n", exc, data)
97 1
    return False
98
99
100 1
def display(title, data, color=""):
101 1
    """Write colored text to the console."""
102 1
    color += colorama.Style.BRIGHT
103 1
    width, _ = get_terminal_size()
104 1
    print(color + "{0:=^{1}}".format(' ' + title + ' ', width))
105 1
    message = json.dumps(data, indent=4)
106 1
    message = message.replace('^', colorama.Fore.WHITE + colorama.Style.BRIGHT)
107
    message = message.replace('$', colorama.Style.RESET_ALL)
108
    print(message)
109
    print(color + '=' * width)
110