Files
mango/tools/socks.sync

137 lines
3.3 KiB
Python
Executable File

#!/usr/bin/env python3
# vim: ft=python
# -*- mode: python -*-
import json
import os
import sys
import subprocess
help_str = ('A config file `sync.json` has been created in {}. '
'Please specify the remote host and destination directory in this '
'config file and then run the sync script again.').format(os.path.join(os.getcwd(), '.config'))
config_filename = os.path.join('.config', 'sync.json')
rsync_path = os.getenv('RSYNC_PATH', default = 'rsync')
def in_source_tree():
return os.path.isfile('tools/socks.sync')
def create_sample_config():
config_file = open(config_filename, mode='w')
data = {
'targets': {
'example': {
'host': 'Hostname',
'user': 'User to connect to the remote host as (optional)',
'path': 'Destination directory on remote host'
}
},
'default_target': 'example'
}
json.dump(data, config_file, indent=4)
def read_config():
config_file = None
try:
config_file = open('sync.json')
except (OSError, FileNotFoundError):
create_sample_config()
print(help_str)
exit(0)
return json.load(config_file)
def check_config(cfg):
if not 'targets' in cfg:
print('No targets specified in config file')
exit(-1)
def make_full_target(target):
path = target['path'].replace('\\', '/')
if path[-1] != '/':
path += '/'
out = '{}:{}'.format(target['host'], path)
if 'user' in target:
out = '{}@{}'.format(target['user'], out)
return out
def print_available_targets(targets):
print('Available targets:')
for name, target in targets.items():
print(' * {} ({})'.format(name, make_full_target(target)))
if not in_source_tree():
print('This script must be executed from the root of the Socks source tree')
exit(-1)
config = read_config()
check_config(config);
targets = config['targets']
if len(sys.argv) < 2:
print('No mode specified. Available modes:')
print(' * pull: Update the local source tree to match the remote source tree')
print(' * push: Upload the remote source tree to match the local source tree')
exit(0)
mode = sys.argv[1]
if mode != 'pull' and mode != 'push':
print('Invalid sync mode "{}"'.format(mode))
exit(-1)
target_name = ''
if len(sys.argv) < 3:
if 'default_target' in config:
target_name = config['default_target']
print('No target specified. Using default target "{}"'.format(target_name))
else:
print('No target specified (and no default target configured)')
print_available_targets(config['targets'])
exit(0)
if target_name not in targets:
print('Unknown target "{}"'.format(target_name))
print_available_targets(config['targets'])
exit(-1)
target = targets[target_name]
print('Syncing source tree with {} ({})'.format(make_full_target(target), mode))
rsync_args = [
rsync_path,
'-azhP',
'--exclude',
'build/'
]
if mode == 'pull':
rsync_args += [ make_full_target(target), '.' ]
else:
rsync_args += [ '.', make_full_target(target) ]
rsync = subprocess.Popen(rsync_args)
rsync.communicate()
if rsync.returncode == 0:
print('** Sync completed successfully')
else:
print('** Sync failed (error {})'.format(rsync.errorcode))
exit(rsync.returncode)