-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_repos.py
executable file
·137 lines (93 loc) · 3.54 KB
/
check_repos.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
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
#!/usr/bin/env python3
import os
import subprocess
import time
from PIL import Image, ImageOps
from pystray import Icon, Menu, MenuItem
from lib.cli import args
from lib import utils, Notifier
curr_dir = os.path.dirname(os.path.realpath(__file__))
MESSAGE = "Repositories which are not up to date"
def _prepare_image(full_img_path):
return ImageOps.expand(Image.open(full_img_path), border=5, fill=0)
def get_image(rel_img_path):
return _prepare_image(os.path.join(curr_dir, rel_img_path))
icon_ok = get_image("images/ok.png")
icon_fail = get_image("images/fail.png")
icon_loading = get_image("images/loading.png")
def execute_command(command: str, cwd: str):
return subprocess.run(command.split(" "), cwd=cwd)
def repo_is_up_to_date(repo: utils.Repo):
commands = {
"fetch": "git fetch",
"is_up_to_date": f"git merge-base --is-ancestor origin/{repo.branch} {repo.branch}",
}
execute_command(commands["fetch"], cwd=repo.path)
returncode = execute_command(commands["is_up_to_date"], cwd=repo.path).returncode
return returncode == 0
def can_do_fast_forward(repo: utils.Repo):
returncode = execute_command(
f"git merge-base --is-ancestor {repo.branch} origin/{repo.branch}",
cwd=repo.path,
).returncode
return returncode == 0
def pull_changes(repo: utils.Repo):
execute_command(f"git pull", cwd=repo.path)
def pull_changes_for_list_of_repos(repos: list):
for repo in repos:
if repo.can_ff:
pull_changes(repo)
def void():
pass
def setup(icon: Icon):
icon.visible = True
is_up_to_date = True
while True:
output = []
wrong_output = []
# TODO: Please do it better...
repos, wrong_paths = utils.get_repos_and_wrong_paths(args.file)
if wrong_paths:
wrong_output.extend(["", "Those directories does not exist:"])
for path in wrong_paths:
wrong_output.append(f"- {path}")
for repo in repos:
if repo_is_up_to_date(repo):
continue
text = f"- {repo.path} ({repo.branch})"
repo.can_ff = can_do_fast_forward(repo)
if repo.can_ff:
text += " [FF]"
output.append(text)
was_up_to_date = is_up_to_date
is_up_to_date = not bool(output)
if is_up_to_date:
_icon = icon_ok
_items = [MenuItem("All existing repositories are up to date", action=void)]
else:
_icon = icon_fail
_items = [MenuItem(f"{MESSAGE}:", action=void)] + [
MenuItem(f"{text}", action=void) for text in output
]
if any(repo.can_ff for repo in repos):
_items.extend(
[
MenuItem("", action=void),
MenuItem(
text="Pull changes for fast forwardable repositories marked with [FF]",
action=pull_changes_for_list_of_repos(repos),
),
]
)
if was_up_to_date:
n = Notifier()
n.send_notification(output + wrong_output)
if wrong_paths:
_items.extend([MenuItem(f"{text}", action=void) for text in wrong_output])
_menu = Menu(*_items)
icon.icon = _icon
icon.menu = _menu
time.sleep(args.delay)
menu = Menu(MenuItem(text="Checking repositories...", action=void))
icon = Icon(name=MESSAGE, icon=icon_loading, menu=menu)
icon.run(setup)