root/software/misc/git_monitor.py @ 30849ea7
| 3d6bc4b0 | David Sorber | #!/usr/bin/python3
|
|
import logging
|
|||
import subprocess
|
|||
import sys
|
|||
import time
|
|||
# --- Config ---
|
|||
# Polling duration in seconds
|
|||
POLLING_PERIOD = 15
|
|||
# Upstream branch identification
|
|||
UPSTREAM = 'origin/master'
|
|||
# Full path to cloned git repository
|
|||
GIT_DIR = '/home/dsorber/dev/repo'
|
|||
# Full path to "action" script to be executed after any changes have been
|
|||
# pulled
|
|||
ACTION_SCRIPT = '/home/dsorber/Desktop/post_pull_action.sh'
|
|||
# Full path of file in which to log output. If empty log output will be written
|
|||
# to stdout.
|
|||
LOGFILE_PATH = ''
|
|||
def execute_command(command_str, quiet=True):
|
|||
error = False
|
|||
try:
|
|||
output = subprocess.check_output(command_str, shell=True,
|
|||
stderr=subprocess.STDOUT)
|
|||
output = output.decode('utf-8').strip()
|
|||
if output and not quiet:
|
|||
logging.debug(output)
|
|||
except subprocess.CalledProcessError:
|
|||
error = True
|
|||
if output:
|
|||
logging.error(output)
|
|||
else:
|
|||
logging.error('An error occurred while attempting to execute '
|
|||
'"{:s}"'.format(command_str))
|
|||
return (error, output)
|
|||
def main():
|
|||
logging.info('{:s} starting'.format(sys.argv[0].startswith('./') and
|
|||
sys.argv[0][2:] or sys.argv[0]))
|
|||
while True:
|
|||
# Git fetch first so we can compare reivsions
|
|||
logging.info('Fetching remote history')
|
|||
cmd = 'cd {:s}; git fetch'.format(GIT_DIR)
|
|||
error, _ = execute_command(cmd)
|
|||
if error:
|
|||
logging.warn('Script terminating due to previous error')
|
|||
break
|
|||
# Get local revision
|
|||
cmd = 'cd {:s}; git rev-parse @'.format(GIT_DIR)
|
|||
error, local_rev = execute_command(cmd)
|
|||
if error:
|
|||
logging.warn('Script terminating due to previous error')
|
|||
break
|
|||
# Get remote revision
|
|||
cmd = 'cd {:s}; git rev-parse "{:s}"'.format(GIT_DIR, UPSTREAM)
|
|||
error, remote_rev = execute_command(cmd)
|
|||
if error:
|
|||
logging.warn('Script terminating due to previous error')
|
|||
break
|
|||
# Get merge base revision
|
|||
cmd = 'cd {:s}; git merge-base @ "{:s}"'.format(GIT_DIR, UPSTREAM)
|
|||
error, base_rev = execute_command(cmd)
|
|||
if error:
|
|||
logging.warn('Script terminating due to previous error')
|
|||
break
|
|||
# Now decide what to do
|
|||
if local_rev == remote_rev:
|
|||
logging.info('Up-to-date with "{:s}"'.format(UPSTREAM))
|
|||
elif remote_rev == base_rev:
|
|||
logging.warn('Local changes found, need to push them')
|
|||
elif local_rev == base_rev:
|
|||
logging.info('Remote changes found, preparing to pull them')
|
|||
# Pull remote changes
|
|||
cmd = 'cd {:s}; git pull'.format(GIT_DIR)
|
|||
error, _ = execute_command(cmd, False)
|
|||
if error:
|
|||
logging.warn('Script terminating due to previous error')
|
|||
break
|
|||
# Now execute "action" script if one has been specified
|
|||
if ACTION_SCRIPT:
|
|||
cmd = '{:s}'.format(ACTION_SCRIPT)
|
|||
error, script_output = execute_command(cmd)
|
|||
if error:
|
|||
logging.warn('Script terminating due to previous error')
|
|||
break
|
|||
# Sleep for a while
|
|||
time.sleep(POLLING_PERIOD)
|
|||
logging.info('{:s} stopping'.format(sys.argv[0]))
|
|||
if __name__ == '__main__':
|
|||
if LOGFILE_PATH:
|
|||
logging.basicConfig(format='%(asctime)s|%(levelname)s|%(message)s',
|
|||
datefmt='%a %b %d %H:%M:%S %Y',
|
|||
filename=LOGFILE_PATH, level=logging.DEBUG)
|
|||
else:
|
|||
logging.basicConfig(format='%(asctime)s|%(levelname)s|%(message)s',
|
|||
datefmt='%a %b %d %H:%M:%S %Y',
|
|||
level=logging.DEBUG)
|
|||
sys.exit(main())
|