#!/usr/bin/env python3 """Initialize your dotfiles setup. Usage: setup [--install] This will create symlinks in $HOME for every file listed in ./home in this repository. It will NOT delete existing files in $HOME; use the --install option to delete existing files. This script should work in any version of Python above v2.5""" import sys import os import os.path import shutil import re import subprocess import stat # Install? (deletes existing files in $HOME). install = "--install" in sys.argv # Get the path to the git repo. basedir = os.path.abspath(os.path.dirname(__file__)) homedir = os.environ.get("HOME", ".") source = os.path.join(basedir, "home") print("Setting up .dotfiles") print("====================") print("") if install: print("* Install mode: will delete files in $HOME and set up symlinks!") # Set up the submodules first. print("Initializing git submodules...") os.chdir(basedir) subprocess.call(["git", "submodule", "init"]) subprocess.call(["git", "submodule", "update"]) os.chdir(homedir) print("Submodules updated!") print("") def crawl(folder): """Recursively crawl a folder. Directories will be created relative to $HOME, and files in those directories will be symlinked.""" for item in sorted(os.listdir(folder)): # Resolve the path to this file relative to $HOME and the absolute # path to the symlink target. First get the path to the target. target = os.path.join(folder, item) # Remove the source dir prefix from it to get the path relative # to the "./home" folder, then use that for $HOME. path = re.sub(r'^%s/' % source, '', target) home = os.path.join(homedir, path) # If the target is a directory, make sure it exists relative to $HOME. if os.path.isdir(target): if not os.path.isdir(home): print("Create directory:", home) os.mkdir(home) # Recursively crawl it. crawl(target) continue # Otherwise it's a file. In install mode, delete the existing file. if os.path.exists(home) or os.path.islink(home): if install: print("Delete:", home) os.unlink(home) elif not os.path.islink(home): print("Found existing (non-link file), but not in --install mode:", home) continue # Already linked? if os.path.islink(home): link = os.readlink(home) if link == target: print("Already linked:", home) continue else: print("Delete existing link:", home) os.unlink(home) # Link it. print("Link: %s -> %s" % (home, target)) os.symlink(target, home) # Fix permissions. if path == ".ssh/config": print("chmod 600 .ssh/config") os.chmod(home, stat.S_IRUSR | stat.S_IWUSR) crawl(source) # vim:expandtab