Source

vimpire / vimpire.py

Full commit
#!/usr/bin/python
#-*- coding:utf-8 -*-

import re, os, sys
import subprocess as sp
import shutil as sh

# The current working directory is assumed to be the dotvim directory, if none
# is provided on the command line

vimfiles_dir = sys.argv[1] if len(sys.argv) > 1 else (os.getenv('VIMFILES') or os.getenv('DOTVIM'))
if vimfiles_dir:
    os.chdir(vimfiles_dir)

bundles_file = 'bundles.vim'
bundle_dir = 'bundle'

with open(bundles_file) as f:
    bundles_file_lines = f.read().splitlines()

def main():
    if not os.path.exists(bundle_dir):
        os.mkdir(bundle_dir)
    os.chdir(bundle_dir)

    plugin_dirs = []

    for line in bundles_file_lines:
        m = re.match(r'^\s*"\s*(bundle)(!?):\s*(.*)$', line, re.I)
        if not m: continue
        bline = BLine(*m.groups())
        bline.apply()
        if bline.name == 'bundle':
            plugin_dirs.append(bline.rman.dest_dir)

    all_dirs = os.listdir('.')
    for dirname in (d for d in os.listdir('.') if d not in plugin_dirs):
        sh.rmtree(dirname)

class BLine(object):

    def __init__(self, name, is_bang, line):
        self.name = name.lower()
        self.is_bang = is_bang
        self.line = line

    def apply(self):
        getattr(self, '_' + self.name)()

    def _bundle(self):
        url = self.line.split()[0]
        arg = self.line.lstrip(url)

        vcs_match = re.search(r'with\s+(\w+)', arg)
        vcs = vcs_match.group(1) if vcs_match else None

        dest_dir_match = re.search(r'to\s+(\w+)', arg)
        dest_dir = dest_dir_match.group(1) if dest_dir_match else None

        self.rman = RepoManager(url, vcs, dest_dir)
        if self.rman.vcs is not None:
            print '+------------'
            self.rman.reflect()

class RepoManager(object):

    def __init__(self, url, vcs=None, dest_dir=None):
        self.url = url
        self.vcs = vcs
        self.dest_dir = dest_dir

        self.check_vcs()
        self.check_dest_dir()

    def check_vcs(self):
        if self.vcs is not None:
            return
        if 'bitbucket.org' in self.url or 'googlecode.com/hg' in self.url:
            self.vcs = 'hg'
        elif self.url.startswith('git:') or 'github.com' in self.url:
            self.vcs = 'git'
        elif self.url.startswith('svn:'):
            self.vcs = 'svn'
        else:
            print 'Unable to detect vcs for', self.url

    def check_dest_dir(self):
        if self.dest_dir is not None:
            return
        self.dest_dir = self.url.split('/')[-1]
        if self.dest_dir.endswith('.' + self.vcs):
            self.dest_dir = self.dest_dir[:-(1 + len(self.vcs))]

    def reflect(self):
        getattr(self, '_' + self.vcs)()

    def _hg(self):
        if os.path.exists(self.dest_dir):
            cmd = 'cd ' + self.dest_dir + ' && hg pull'
        else:
            cmd = 'hg clone ' + self.url + ''
        print cmd
        sp.call(cmd, shell=True)

    def _git(self):
        if os.path.exists(self.dest_dir):
            cmd = 'cd ' + self.dest_dir + ' && git pull'
        else:
            cmd = 'git clone ' + self.url
        print cmd
        sp.call(cmd, shell=True)

if __name__ == '__main__':
    main()