|
#!/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())
|