Completed
Push — develop ( 8e3cf4...604c57 )
by Jace
01:38
created

coveragespace/cli.py (1 issue)

Labels
Severity
1
"""Update project metrics on The Coverage Space.
2
3
Usage:
4
  coverage.space <owner/repo> <metric> [<value>] [--verbose] [--exit-code]
5
  coverage.space (-h | --help)
6
  coverage.space (-V | --version)
7
8
Options:
9
  -h --help         Show this help screen.
10
  -V --version      Show the program version.
11
  -v --verbose      Always display the coverage metrics.
12
  -x --exit-code    Return non-zero exit code on failures.
13
14
"""
15
16 1
from __future__ import unicode_literals
17
18 1
import sys
19 1
import time
20 1
import json
21 1
import logging
22
23 1
import six
24 1
from docopt import docopt
25 1
import requests
26 1
import colorama
27 1
from backports.shutil_get_terminal_size import get_terminal_size
28
29 1
from . import API, VERSION
30
31 1
from .plugins import get_coverage
32 1
from .cache import Cache
33
34
35 1
log = logging.getLogger(__name__)
36 1
cache = Cache()
37
38
39 1
def main():
40
    """Run the program."""
41 1
    colorama.init(autoreset=True)
42 1
    arguments = docopt(__doc__, version=VERSION)
43
44 1
    slug = arguments['<owner/repo>']
45 1
    metric = arguments['<metric>']
46 1
    value = arguments['<value>'] or get_coverage()
47 1
    verbose = arguments['--verbose']
48 1
    hardfail = arguments['--exit-code']
49
50 1
    if verbose:
51 1
        logging.basicConfig(
52
            level=logging.DEBUG,
53
            format="%(levelname)s: %(name)s: %(message)s",
54
        )
55
56 1
    success = call(slug, metric, value, verbose, hardfail)
57
58 1
    if not success and hardfail:
59 1
        sys.exit(1)
60
61
62 1
def call(slug, metric, value, verbose=False, hardfail=False):
63
    """Call the API and display errors."""
64 1
    url = "{}/{}".format(API, slug)
65 1
    data = {metric: value}
66 1
    response = request(url, data)
67
68 1
    if response.status_code == 200:
69 1
        if verbose:
70 1
            display("coverage increased", response.json(), colorama.Fore.GREEN)
71 1
        return True
72
73 1
    elif response.status_code == 422:
74 1
        color = colorama.Fore.RED if hardfail else colorama.Fore.YELLOW
75 1
        display("coverage decreased", response.json(), color)
76 1
        return False
77
78
    else:
79 1
        try:
80 1
            data = response.json()
81 1
            display("coverage unknown", data, colorama.Fore.RED)
0 ignored issues
show
The Instance of AnsiCodes does not seem to have a member named RED.

This check looks for calls to members that are non-existent. These calls will fail.

The member could have been renamed or removed.

Loading history...
82 1
        except (TypeError, ValueError) as exc:
83 1
            data = response.data.decode('utf-8')
84 1
            log.error("%s\n\nwhen decoding response:\n\n%s\n", exc, data)
85 1
        return False
86
87
88 1
def request(url, data):
89
    """Make request to external API."""
90 1
    log.info("Updating %s: %s", url, data)
91
92 1
    response = cache.get(url, data)
93 1
    if response is None:
94 1
        for _ in range(3):
95 1
            response = requests.put(url, data=data)
96 1
            if response.status_code == 500:
97 1
                time.sleep(3)
98 1
                continue
99
            else:
100 1
                break
101 1
        cache.set(url, data, response)
102
103 1
    log.info("Response: %s", response)
104
105 1
    return response
106
107
108 1
def display(title, data, color=""):
109
    """Write colored text to the console."""
110 1
    color += colorama.Style.BRIGHT
111 1
    width, _ = get_terminal_size()
112 1
    six.print_(color + "{0:=^{1}}".format(' ' + title + ' ', width))
113 1
    six.print_(color + json.dumps(data, indent=4))
114
    six.print_(color + '=' * width)
115