rbtools.hooks.common
1
import logging
2
import re
3
import subprocess
4
5
from rbtools.api.client import RBClient
6
from rbtools.api.errors import APIError, ServerInterfaceError
7
8
9
SUBMITTED = 'submitted'
10
11
12
class HookError(Exception):
13
    pass
14
15
16
def _make_api_client(server_url, username, password):
17
    """Returns an RBClient object for the server.
18
19
    The RBClient will be instantiated with the proper arguments
20
    for talking to the provided Review Board server url.
21
    """
22
    return RBClient(server_url, username=username, password=password)
23
24
def get_api(server_url, username, password):
25
    """Returns an RBClient instance and the associated root resource.
26
27
    Hooks should use this method to gain access to the API,
28
    instead of instantianting their own client.
29
    """
30
    api_client = _make_api_client(server_url, username, password)
31
32
    try:
33
        api_root = api_client.get_root()
34
    except ServerInterfaceError, e:
35
        raise HookError('Could not reach the Review Board server at %s'
36
                        % server_url)
37
    except APIError, e:
38
        raise HookError('Unexpected API Error: %s' % e)
39
40
    return api_client, api_root
41
42
def execute(command):
43
    """Executes the specified command and returns the stdout output."""
44
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
45
    return process.communicate()[0].strip()
46
47
def get_review_request_id(regex, commit_message):
48
    """Returns the review request ID referenced in the commit message.
49
50
    We assume there is only one review request to be closed per commit. If a
51
    matching review request cannot be found, we return None.
52
    """
53
    pattern = re.compile(regex, re.IGNORECASE)
54
    match = pattern.search(commit_message)
55
    review_request_id = (match and match.group('id')) or None
56
    return review_request_id
57
58
def get_review_request(review_request_id, api_root):
59
    """Returns the review request resource for the given ID."""
60
    try:
61
        review_request = api_root.get_review_request(
62
            review_request_id=review_request_id)
63
    except APIError, e:
64
        raise HookError('Error getting review request: %s' % e)
65
66
    return review_request
67
68
def close_review_request(server_url, username, password, review_request_id,
69
                         description):
70
    """Closes the specified review request as submitted."""
71
    api_client, api_root = get_api(server_url, username, password)
72
    review_request = get_review_request(review_request_id, api_root)
73
74
    if review_request.status == SUBMITTED:
75
        logging.warning('Review request #%s is already %s.',
76
                        review_request_id, SUBMITTED)
77
        return
78
79
    if description:
80
        review_request = review_request.update(status=SUBMITTED,
81
                                               description=description)
82
    else:
83
        review_request = review_request.update(status=SUBMITTED)
84
85
    print('Review request #%s is set to %s.' %
86
          (review_request_id, review_request.status))
87
88
def get_review_request_approval(server_url, username, password,
89
                                review_request_id):
90
    """Returns the approval information for the given review request."""
91
    api_client, api_root = get_api(server_url, username, password)
92
    review_request = get_review_request(review_request_id, api_root)
93
94
    return review_request.approved, review_request.approval_failure
Loading...