-
Notifications
You must be signed in to change notification settings - Fork 1
/
git_utils.py
103 lines (87 loc) · 3.52 KB
/
git_utils.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
import json
import subprocess
import re
from urllib import request
from typing import Dict, Tuple, Any
class GitHubRepo:
def __init__(self, user, repo, token):
self.token = token
self.user = user
self.repo = repo
self.base = f"https://api.github.com/repos/{user}/{repo}/"
def headers(self):
return {
"Authorization": f"Bearer {self.token}",
}
def graphql(self, query: str) -> Dict[str, Any]:
return self._post(
"https://api.github.com/graphql", {"query": compress_query(query)}
)
def _post(self, full_url: str, body: Dict[str, Any]) -> Dict[str, Any]:
print("Requesting POST to", full_url, "with", body)
req = request.Request(full_url, headers=self.headers(), method="POST")
req.add_header("Content-Type", "application/json; charset=utf-8")
data = json.dumps(body)
data = data.encode("utf-8")
req.add_header("Content-Length", len(data))
with request.urlopen(req, data) as response:
response = json.loads(response.read())
return response
def post(self, url: str, data: Dict[str, Any]) -> Dict[str, Any]:
return self._post(self.base + url, data)
def get(self, url: str) -> Dict[str, Any]:
url = self.base + url
print("Requesting GET to", url)
req = request.Request(url, headers=self.headers())
with request.urlopen(req) as response:
response = json.loads(response.read())
return response
def delete(self, url: str) -> Dict[str, Any]:
url = self.base + url
print("Requesting DELETE to", url)
req = request.Request(url, headers=self.headers(), method="DELETE")
with request.urlopen(req) as response:
response = json.loads(response.read())
return response
def compress_query(query: str) -> str:
query = query.replace("\n", "")
query = re.sub("\s+", " ", query)
return query
def parse_remote(remote: str) -> Tuple[str, str]:
"""
Get a GitHub (user, repo) pair out of a git remote
"""
if remote.startswith("https://"):
# Parse HTTP remote
parts = remote.split("/")
if len(parts) < 2:
raise RuntimeError(f"Unable to parse remote '{remote}'")
return parts[-2], parts[-1].replace(".git", "")
else:
# Parse SSH remote
m = re.search(r":(.*)/(.*)\.git", remote)
if m is None or len(m.groups()) != 2:
raise RuntimeError(f"Unable to parse remote '{remote}'")
return m.groups()
def git(command):
command = ["git"] + command
print("Running", command)
proc = subprocess.run(command, stdout=subprocess.PIPE, check=True)
return proc.stdout.decode().strip()