dotfiles / install.py

#!/usr/bin/env python

"""
Install the config files into their proper places.

Only works on Unix-type systems (Linux, OSX, etc.)
"""

import sys
import os

from fnmatch import fnmatch
from datetime import datetime
from ConfigParser import SafeConfigParser as CP

IGNORE = [
#    os.path.basename(__file__),
#    '.hg',
#    '.hgignore',
]

HOMEDIR = os.environ['HOME']
CFGFILE = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'defaults.conf')

def backup(f):
    if os.path.exists(f) and not os.path.islink(f):
        datestamp = datetime.now().strftime('.%Y%m%d.%H%M%S.%f')
        new_fname = f + datestamp
        try:
            os.rename(f, new_fname)
            print "Backing up %s -> %s" % (f, new_fname)
        except:
            print >> sys.stderr, "Backup of %s failed" % f

def main():
    if len(sys.argv) == 2:
        home = sys.argv[1].strip().rstrip('/')
    else:
        home = HOMEDIR
    print "Installing dotfiles to %s." % home
    if raw_input("Continue? [Y/n] ").lower().startswith('n'):
        print "kthxbai"
        exit(0)
    link_files(home)
    install_defaults(home)

def link_files(home):
    src_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'dotfiles')
    for (dirpath, dirnames, filenames) in os.walk(src_path):
        ddirpath = home + dirpath[len(src_path):]
        for d in dirnames:
            ddirname = os.path.join(ddirpath, d)
            if not os.path.exists(ddirname):
                os.mkdir(ddirname)
        for f in filenames:
            if f in IGNORE:
                continue
            dfilename = os.path.join(ddirpath, f)
            backup(dfilename)
            if not os.path.exists(dfilename):
                print "Linking %s -> %s" % (f, dfilename),
                try:
                    os.symlink(os.path.join(dirpath, f), dfilename)
                    print
                except AttributeError:
                    print "(skipped)"

def install_defaults(home):
    """Create required directories and get some initial software."""
    cfg = CP()
    cfg.read(CFGFILE)
    for dir in cfg.sections():
        fdir = os.path.join(home, dir)
        if not os.path.exists(fdir):
            os.mkdir(fdir)
        for sdir, cmd in cfg.items(dir):
            sfdir = os.path.join(fdir, sdir)
            if not os.path.exists(sfdir):
                fcmd = "cd %s && %s %s" % (fdir, cmd, sdir)
                os.system(fcmd)

if __name__ == '__main__':
    main()
    sys.exit(0)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.