-
Notifications
You must be signed in to change notification settings - Fork 0
/
autoupdater.py
65 lines (49 loc) · 1.86 KB
/
autoupdater.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
#!/usr/bin/env python3
import atexit
import inspect
import os
import subprocess
import sys
import threading
# This interval is 10 minutes because it's fun to see your updates come out
# when you want them to.
INTERVAL = int(1 * 60 * 10) # seconds
update_condition = threading.Condition()
filepath = None
def _get_output(args):
process = subprocess.run(args,
stdout=subprocess.PIPE)
assert process.returncode == 0
return process.stdout.decode("ascii").strip()
def _worker():
remote = "origin"
branch = _get_output(["git", "symbolic-ref", "--short", "HEAD"])
commit_hash = _get_output(["git", "rev-parse", "HEAD"])
while True:
command = subprocess.run(["git", "pull", remote, branch],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL)
if command.returncode == 0:
new_commit_hash = _get_output(["git", "rev-parse", "HEAD"])
if new_commit_hash != commit_hash:
restart()
with update_condition:
update_condition.wait(INTERVAL)
def restart():
if hasattr(atexit, "_run_exitfuncs"):
# We're about to leave in a way that's not expected by
# Python.
# This means that some things, including atexit callbacks,
# won't be run.
# We want them to run because ircbot.py relies on them, so
# this is our kind-of CPython hack.
atexit._run_exitfuncs()
os.execlp(sys.executable, sys.executable, filepath)
def initialize():
# TODO: Not use globals.
global filepath
# Initialize the auto-updater. Must be called in the main script.
parent_globals = inspect.currentframe().f_back.f_globals
assert parent_globals["__name__"] == "__main__"
filepath = parent_globals["__file__"]
threading.Thread(target=_worker).start()