Skip to content

Commit f981b79

Browse files
committed
Installation specific API calls, link to gitconsensus library
1 parent d0e752c commit f981b79

File tree

2 files changed

+95
-9
lines changed

2 files changed

+95
-9
lines changed

gitconsensusservice/cli.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import re
33
from gitconsensusservice.services import github
44
import yaml
5+
from gitconsensus.repository import Repository
56

67

78
@click.group()
@@ -31,6 +32,13 @@ def install_token(install_id):
3132
click.echo(token)
3233

3334

35+
@cli.command(short_help="Get an authentication token for the provided installation.")
36+
@click.argument('install_id')
37+
def install_repos(install_id):
38+
token = github.get_installation_repositories(install_id)
39+
dump(token)
40+
41+
3442
@cli.command(short_help="List details about the current application.")
3543
def application():
3644
dump(github.get_app())
@@ -41,6 +49,39 @@ def jwt():
4149
click.echo(github.get_jwt())
4250

4351

52+
@cli.command(short_help="List all open pull requests for the specific install and repository.")
53+
@click.argument('install_id')
54+
@click.argument('username')
55+
@click.argument('repository_name')
56+
def prs(install_id, username, repository_name):
57+
dump(github.list_prs(install_id, username, repository_name))
58+
59+
60+
@cli.command(short_help="Display detailed information about a specific pull request")
61+
@click.argument('install_id')
62+
@click.argument('username')
63+
@click.argument('repository_name')
64+
@click.argument('pull_request')
65+
def pr(install_id, username, repository_name, pull_request):
66+
repo = get_repository(install_id, username, repository_name)
67+
request = repo.getPullRequest(pull_request)
68+
click.echo("PR#%s: %s" % (request.number, request.pr.title))
69+
consensus = repo.getConsensus()
70+
click.echo("Mergeable: %s" % (consensus.isMergeable(request),))
71+
click.echo("Is Blocked: %s" % (request.isBlocked(),))
72+
click.echo("Is Allowed: %s" % (consensus.isAllowed(request),))
73+
click.echo("Has Quorum: %s" % (consensus.hasQuorum(request),))
74+
click.echo("Has Votes: %s" % (consensus.hasVotes(request),))
75+
click.echo("Has Aged: %s" % (consensus.hasAged(request),))
76+
click.echo("Should Close: %s" % (request.shouldClose(),))
77+
click.echo("Last Update: %s" % (request.hoursSinceLastUpdate(),))
78+
79+
80+
def get_repository(install_id, username, repository_name):
81+
client = github.get_github3_client(install_id)
82+
return Repository(username, repository_name, client)
83+
84+
4485
def dump(obj):
4586
click.echo(yaml.dump(obj, default_flow_style=False))
4687

gitconsensusservice/services/github.py

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
import re
55
import requests
66
import time
7+
from gitconsensus.repository import Repository
78
from gitconsensusservice import app
9+
import github3
810

911

1012
def get_jwt():
@@ -40,14 +42,11 @@ def request(url, method='GET'):
4042
response = requestfunc('https://api.github.com/%s' % (url,), headers=headers)
4143
response.raise_for_status()
4244
retobj = response.json()
43-
if 'Link' in response.headers:
44-
regex = r"\<https://api.github.com/([^>]*)\>; rel=\"([a-z]*)\""
45-
groups = re.findall(regex, response.headers['Link'])
46-
for group in groups:
47-
if group[1] == 'next':
48-
nextresults = request(group[1])
49-
retobj += nextresults
50-
break
45+
46+
nextpage = get_link_from_response(response)
47+
if nextpage:
48+
nextresults = request(nextpage)
49+
retobj += nextresults
5150
return retobj
5251

5352

@@ -73,9 +72,55 @@ def get_installation_token(installation_id):
7372
expiration = tokens[installation_id]['expires_at']
7473
testtime = datetime.now() - timedelta(minutes=3)
7574
exptime = datetime.strptime(expiration, "%Y-%m-%dT%H:%M:%SZ")
76-
if exptime < testtime:
75+
if exptime > testtime:
7776
return tokens[installation_id]['token']
7877

7978
url = "installations/%s/access_tokens" % (installation_id,)
8079
tokens[installation_id] = request(url, 'POST')
8180
return tokens[installation_id]['token']
81+
82+
83+
def get_installation_repositories(installation_id, url=False):
84+
if not url:
85+
url = 'https://api.github.com/installation/repositories'
86+
res = installation_request(installation_id, url)
87+
repodata = res.json()
88+
repos = [repo['full_name'] for repo in repodata['repositories']]
89+
nextpage = get_link_from_response(res)
90+
if nextpage:
91+
repos += get_installation_repositories(installation_id, nextpage)
92+
return repos
93+
94+
95+
def installation_request(installation_id, url):
96+
client = get_github3_client(installation_id)
97+
headers = {'Accept': 'application/vnd.github.machine-man-preview+json'}
98+
res = client._get(url, headers=headers)
99+
res.raise_for_status()
100+
return res
101+
102+
103+
def list_prs(installation_id, user, repo):
104+
repository = get_repository(installation_id, user, repo).repository
105+
prs = repository.iter_pulls(state="open")
106+
return [pr.number for pr in prs]
107+
108+
109+
def get_repository(install_id, username, repository_name):
110+
client = get_github3_client(install_id)
111+
return Repository(username, repository_name, client)
112+
113+
114+
def get_github3_client(installation_id):
115+
token = get_installation_token(installation_id)
116+
return github3.login(token=token)
117+
118+
119+
def get_link_from_response(response):
120+
if 'Link' in response.headers:
121+
regex = r"\<https://api.github.com/([^>]*)\>; rel=\"([a-z]*)\""
122+
groups = re.findall(regex, response.headers['Link'])
123+
for group in groups:
124+
if group[1] == 'next':
125+
return group[1]
126+
return False

0 commit comments

Comments
 (0)