Skip to content

Instantly share code, notes, and snippets.

@deconstructionalism
Created April 25, 2018 04:52
Show Gist options
  • Select an option

  • Save deconstructionalism/fa4b283bb01b8b4a20f458e4218e4297 to your computer and use it in GitHub Desktop.

Select an option

Save deconstructionalism/fa4b283bb01b8b4a20f458e4218e4297 to your computer and use it in GitHub Desktop.
#!/bin/bash
# -------------------- #
# SYSTEM BACKUP SCRIPT #
# -------------------- #
# PURPOSE: Backup importang config files and program
# installed dependency lists to a private gist
# automatically.
# IMPORTANT: Do not rename:
# - this script
# - `config_files`
# YOU CAN:
# - add files you want to backup to `config_files`
# - add expressions to generate install lists for
# programs in "GENERATE INSTALL LIST FILES" section
# - expressions must output a file with a
# "[program_name].install" formatted name
# - add a function named "install_[program_name]" to
# `system_backup_ restore.py` in "INSTALL FUNCTIONS"
# section with `install_file` as in input to do
# whatever you want with the install file contents
config_files=("~/com.googlecode.iterm2.plist" \
"~/.zshrc" \
"~/.bashrc" \
"~/.bash_profile" \
"~/.vimrc" \
"~/.bashrc" \
"~/.config/nvim/init.vim")
# GET PATH OF THIS SCRIPT
dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
self_path="$dir/`basename $0`"
# MAKE TEMP DIR FOR INSTALL LIST FILES
tmp_dir="/tmp/`date \"+CONFIG_BACKUP.%y-%m-%d.%H-%M-%S\"`"
mkdir $tmp_dir
cd $tmp_dir
# GENERATE INSTALL LIST FILES
apm list --installed --bare > apm.install
code --list-extensions > code.install
brew leaves > brew.install
system_profiler SPApplicationsDataType -xml > apps.install
# GET SPACE-SEPARATED LIST OF INSTALL LIST FILES
install_files=$(find *.install | tr '\n' ' ')
# MAKE PRIVATE GIST WITH ALL FILES
# includes: config_files, install list files, this script
gist -p -o $self_path $install_files ${config_files[@]} -d "`date` - full config backup"
#!/usr/bin/python
'''
# ---------------------------- #
# SYSTEM BACKUP RESTORE SCRIPT #
# ---------------------------- #
'''
import json
import re
import requests
import sys
import xml.etree.ElementTree
from subprocess import Popen, PIPE
try:
gist_id = sys.argv[1]
except:
print('ERROR: YOU MUST PASS A GIST ID FOR A "system_backup.sh" GENERATED GIST AS FIRST ARGUMENT!')
sys.exit(0)
gist_url = "https://api.github.com/gists/{}".format(gist_id)
r = requests.get(gist_url)
if not r.status_code == 200:
print('REQUEST TO {} FAILED WITH HTTP CODE {}!'.format(gist_url, r.status_code))
sys.exit(1)
res = json.loads(r.text)
files = { k: v['content'] for k, v in res['files'].items() }
def find_install_files(block_regex, file_regex, file_name='system_backup.sh'):
f = files[file_name]
block = re.findall(block_regex, f)[0]
return re.findall(file_regex, block)
config_files = find_install_files(r'config_files=\([\S\s]*?\)', r'"(.*?)"')
install_files = [k for k, v in files.items() if k.endswith('.install')]
# install_files = find_install_files(r'install_files=\([\S\s]*?\)', r'"(.*?)"')
def run_installer(command):
cmd_list = command if isinstance(command, list) else command.split(' ')
proc =Popen(cmd_list, stdout=PIPE, stderr=PIPE)
output, error = proc.communicate()
if output:
print(output)
if error:
print('ERROR: {}'.format(error))
file_to_list = lambda x: list(filter(None, x.split('\n')))
def install_apm(install_file):
''' install Atom packages '''
for pkg in file_to_list(install_file):
run_installer('apm install {}'.format(pkg))
def install_code(install_file):
''' install VSCode extensions '''
for ext in file_to_list(install_file):
run_installer('code --install-extension {}'.format(ext))
def install_brew(install_file):
''' install brew formulae '''
for leaf in file_to_list(install_file):
run_installer('brew install {}'.format(leaf))
def install_app(install_file):
''' list non-apple macOS apps '''
with open('apps.txt', 'w', encoding='utf-8') as f:
f.write(install_file)
print('wrote apps.txt')
for install_file in install_files:
install_func = 'install_{}'.format(install_file.rstrip('.install'))
if install_func in locals() and callable(locals()[install_func]):
print('\nRUNNING INSTALL FUNCTION `{}`'.format(install_func))
locals()[install_func](files[install_file])
else:
print('\nERROR: INSTALL FUNCTION FOR "{}" NOT IN THIS SCRIPT'.format(install_file))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment