dotfiles/install.py

103 lines
3.3 KiB
Python
Executable file

#!/usr/bin/env python3
import argparse
import os
import shutil
import socket
import sys
from functools import partial
from pathlib import Path
import mako.lookup
import mako.template
import requests
import toml
import yaml
BASE16_TEMPLATES_URL = 'https://raw.githubusercontent.com/chriskempson/base16-templates-source/master/list.yaml'
BASE16_TEMPLATES = yaml.safe_load(requests.get(BASE16_TEMPLATES_URL).text)
def get_base16(scheme, app, template='default'):
base_url = BASE16_TEMPLATES[app].replace('github.com', 'raw.githubusercontent.com') + '/master/';
config = yaml.safe_load(requests.get(base_url + 'templates/config.yaml').text)
output = config[template]['output']
extension = config[template]['extension']
return requests.get(base_url + output + '/base16-' + scheme + extension).text
def main():
parser = argparse.ArgumentParser(
description='Generates and installs dotfiles for this host.',
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_argument(
'-d', '--dotfiles',
help='The base directory of the dotfiles repository.',
type=Path,
default=Path(sys.argv[0]).parent,
)
parser.add_argument(
'-n', '--hostname',
help='The hostname or other identifying name of this system that will'
' be used to retrieve the host-specific configuration.',
default=os.environ.get('HOSTNAME') or socket.gethostname(),
)
parser.add_argument(
'-o', '--home',
help='The home directory where generated dotfiles will be installed.',
type=Path,
default=os.environ.get('HOME') or Path.home(),
)
args = parser.parse_args()
raw_dir = args.dotfiles / 'raw'
templates_dir = args.dotfiles / 'templates'
include_dir = args.dotfiles / 'include'
host_filename = args.dotfiles / 'hosts' / '{}.toml'.format(args.hostname)
if host_filename.exists():
with open(host_filename) as host_file:
host_config = toml.load(host_file)
else:
host_config = {}
host_config['name'] = args.hostname
lookup = mako.lookup.TemplateLookup(
directories=[
str(templates_dir),
str(include_dir),
],
)
for raw_path in raw_dir.glob('**/*'):
if not raw_path.is_file():
continue
rel_path = raw_path.relative_to(raw_dir)
output_path = args.home / rel_path
print(rel_path)
output_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy(raw_path, output_path)
for template_path in templates_dir.glob('**/*'):
if not template_path.is_file():
continue
rel_path = template_path.relative_to(templates_dir)
print(rel_path)
template = mako.template.Template(
filename=str(template_path),
strict_undefined=True,
lookup=lookup,
)
output = template.render(
host=host_config,
get_base16=partial(get_base16, host_config.get('base16-scheme', 'default-dark')),
)
output_path = args.home / template_path.relative_to(templates_dir)
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, 'w+') as output_file:
output_file.write(output)
if __name__ == '__main__':
main()