-
Notifications
You must be signed in to change notification settings - Fork 0
/
buildstatus
executable file
·211 lines (186 loc) · 8.82 KB
/
buildstatus
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
#!/usr/bin/env python3
# -*- coding: UTF-8 -*-
"""
A small and simple commandline interface for the buildserver 'API'
"""
__author__ = 'basti.endres@fablab.fau.de'
__license__ = 'UNILICENSE'
import configparser
from os import getcwd, path, listdir
from sys import argv
import re
import requests
import simplejson
import subprocess
from datetime import datetime
from dateutil.relativedelta import *
import inspect
SCRIPT_PATH = path.realpath(path.dirname(inspect.getfile(inspect.currentframe())))
with open(SCRIPT_PATH + '/config.cfg', 'r') as f:
CONFIG_STRING = '[dummy_section]\n' + f.read()
CFG = configparser.ConfigParser()
CFG.read_string(CONFIG_STRING)
BUILDSERVER = CFG.get('dummy_section', 'buildserver').replace('"', '')
BUILDSERVER_TRIGGER_URL = CFG.get('dummy_section', 'buildserver_trigger_url').replace('"', '')
TCOLORS = {'HEADER': '\033[95m', 'BLUE': '\033[94m', 'GREEN': '\033[92m',
'WARNING': '\033[93m', 'FAIL': '\033[91m',
'ENDC': '\033[0m', 'BOLD': '\033[1m', 'UNDERLINE': '\033[4m'}
def colorize(color, message, no_color=False):
"""
colorize the message with the termcolor 'color'
if not no_color or argument '--no-color' or '-n'
"""
if '--no-color' in argv or '-n' in argv or no_color:
return message
else:
return "%s%s%s" % (color, message, TCOLORS['ENDC'])
def format_date_diff(reld, no_color=False):
"""
Adds an apting termcolor to the relativedelta (if no_color is not true
and returns it as human readable string
"""
if reld.years > 0:
return colorize(TCOLORS['FAIL'], "{y} years and {m} months ago".format(y=reld.years, m=reld.months), no_color)
elif reld.months > 0:
return colorize(TCOLORS['FAIL'], "{m} months and {d} days ago".format(m=reld.months, d=reld.days), no_color)
elif reld.days > 0:
return colorize(TCOLORS['WARNING'], "{d} days and {h} hours ago".format(d=reld.days, h=reld.hours), no_color)
elif reld.hours > 0:
return colorize(TCOLORS['WARNING'], "{h} hours and {m} min. ago".format(h=reld.hours, m=reld.minutes), no_color)
elif reld.minutes > 0:
return colorize(TCOLORS['GREEN'], "{} minutes ago".format(reld.minutes), no_color)
else:
return colorize(TCOLORS['GREEN'], "just some seconds ago", no_color)
def do_check():
"""
runs some checks for the current git repo
"""
# submodule check # TODO won't work
try:
subm = subprocess.check_output(['git', 'submodule', 'foreach', 'git', 'remote', 'update'], ).decode('utf-8')
subm += subprocess.check_output(['git', 'submodule', 'foreach', 'git', 'status', '-uno']).decode('utf-8')
if "Head detached" in subm:
subm = "submodule: " + colorize(TCOLORS['WARNING'], "HEAD detached")
elif "git push" in subm:
subm = "submodule: " + colorize(TCOLORS['WARNING'], "local changes")
elif "On branch " in subm:
subm = "submodule: " + colorize(TCOLORS['GREEN'], "up to date")
else:
subm = "submodule: " + colorize(TCOLORS['WARNING'], "remote changes")
except subprocess.CalledProcessError:
subm = "submodule: " + colorize(TCOLORS['FAIL'], "unknown")
todos = 0
links = []
for tex in listdir('.'):
if tex.endswith('.tex'):
try:
# replace is a workaround for broken url regex :)
text = open(tex, 'r', encoding='utf8').read().replace(' ', '\n')
# TODOs
r = re.compile(r"todo", re.IGNORECASE)
todos += len(r.findall(text))
# Links to check
r = re.compile(r"\\url\{(.*)\}")
for l in r.findall(text):
if l not in links:
links.append(l)
except Exception:
try:
print(colorize(TCOLORS['FAIL'], "Can't read file '%s'" % tex))
except UnicodeEncodeError:
print(colorize(TCOLORS['FAIL'], "Can't open a file and I can't tell you wich file it is"))
todo_color = TCOLORS['GREEN'] if todos < 5 else TCOLORS['FAIL'] if todos > 20 else TCOLORS['WARNING']
todo_message = colorize(todo_color, str(todos))
if todos == 0:
todo_message = colorize(TCOLORS['GREEN'], "no todos found")
if len(links) == 0:
links_message = colorize(TCOLORS['GREEN'], "no links found")
else:
links_message = "\n - " + "\n - ".join(str(l) for l in links)
return subm, 'todos: ' + todo_message, 'links: ' + links_message
if __name__ == "__main__":
if "-t" in argv or "--trigger" in argv:
"""
trigger building
"""
URL = BUILDSERVER_TRIGGER_URL
HEADERS = {'Accept': 'application/json', 'User-Agent': 'buildserver-client'}
r = requests.get(URL, headers=HEADERS)
if not r.ok:
print(colorize(TCOLORS['FAIL'], "Threre was an problem while accessing the API"))
exit(1)
text = str(r.text).strip()
if text:
print(colorize(TCOLORS['BOLD'], "Answer from server is:"))
print(r.content)
else:
print(colorize(TCOLORS['GREEN'], "successfully triggered building"))
else:
"""
show buildstatus
"""
REPO = getcwd().split('/')[-1]
URL = BUILDSERVER + REPO + "/status.json"
HEADERS = {'Accept': 'application/json', 'User-Agent': 'buildserver-client'}
r = requests.get(URL, headers=HEADERS)
if not r.ok:
print(colorize(TCOLORS['WARNING'], "There was an problem while accessing the API"))
exit(1)
try:
status = r.json()
except simplejson.JSONDecodeError:
status = {'status': 'unknown', 'updated-human': 'unknown', 'updated': 'unknown', 'commit': 'unknown'}
status_color = TCOLORS['GREEN'] if status['status'] == "success" else \
TCOLORS['WARNING'] if status['status'] == "pending" else TCOLORS['FAIL']
try:
git_status = subprocess.check_output(['git', 'status', '--porcelain', '--untracked-files=no'],
stderr=subprocess.DEVNULL).decode('utf-8')
git_status = 'ok' if git_status == '' else 'local changes'
except subprocess.CalledProcessError:
git_status = 'error'
try:
commit = subprocess.check_output(
['git', 'log', '--pretty=format:"%h"', '--abbrev-commit', '--date=short', '-1'],
stderr=subprocess.DEVNULL).decode('utf-8').strip('"')
except subprocess.CalledProcessError:
commit = 'unknown'
try:
commit_date = subprocess.check_output(
['git', 'log', '--pretty=format:"%ad"', '--abbrev-commit', '--date=raw', '-1'],
stderr=subprocess.DEVNULL).decode('utf-8').strip('"')
commit_date = datetime.fromtimestamp(int(commit_date.split(' ')[0]))
commit_date = format_date_diff(relativedelta(datetime.now(), commit_date), True)
except subprocess.CalledProcessError:
commit_date = colorize(TCOLORS['WARNING'], 'unknown')
if 'commit' not in status.keys():
status['commit'] = 'unknown'
commit_color = TCOLORS['GREEN'] if status['commit'] == commit else TCOLORS['WARNING']
if commit == 'unknown' or status['commit'] == 'unknown':
commit_color = TCOLORS['FAIL']
commit_message = status['commit'] if status['commit'] == commit else status['commit'] + " local commit is: " + commit
if status['updated'].isdigit():
updated = datetime.utcfromtimestamp(int(status['updated']))
rd = relativedelta(datetime.utcnow(), updated)
tdiff = format_date_diff(rd)
else:
tdiff = colorize(TCOLORS['FAIL'], "couldn't read the date from buildserver")
if len(argv) > 1 and ("-c" in argv or "--check" in argv):
check = True
(submod_status, todos, links) = do_check()
else:
check = False
(submod_status, todos, links) = ('unknown', 'unknown', 'unknown')
# print data
print(colorize(TCOLORS['BOLD'], "Build status for '{repo}'".format(repo=REPO)))
print("on " + colorize(TCOLORS['UNDERLINE'], BUILDSERVER + REPO))
print("github url: " + colorize(TCOLORS['UNDERLINE'], "https://github.com/fau-fablab/" + REPO))
if git_status == 'local changes':
print("repo: " + colorize(TCOLORS['WARNING'], "there are local changes"))
if check:
print(submod_status)
print(todos)
print(links)
print("status: " + colorize(status_color, status['status']))
print("commit: " + colorize(commit_color, commit_message) + ' (' + str(commit_date) + ')')
print("build date: " + status['updated-human'] + " ({diff})".format(diff=tdiff))
exit(0)