Source

vimpire / vimpire.py

#!/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 = []
    bundles = []

    for line in bundles_file_lines:
        m = re.match(r'^\s*"\s*(\w+)(!?):(!?)\s*(.*)$', line, re.I)
        if not m: continue
        tline = TagLine(*m.groups())
        if tline.name == 'bundle':
            bundle = Bundle(tline)
            bundles.append(bundle)
            in_bundle_context = True
        elif in_bundle_context:
            bundle.add_tline(tline)
        else:
            in_bundle_context = False

    for bundle in bundles:
        bundle.apply()
        plugin_dirs.append(bundle.dest_dir)

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

class TagLine(object):

    def __init__(self, name, bang1, bang2, line):
        self.name = name.lower()
        self.is_bang = bool(bang1 or bang2)
        self.line = line


class Bundle(object):

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

        self.cmds = []

    def add_tline(self, tline):
        if tline.name in 'run command cmd'.split():
            self.cmds.append(tline.line)

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

        # Detect the vcs to use
        vcs_match = re.search(r'with\s+(\w+)', arg)
        if vcs_match:
            vcs = vcs_match.group(1)
        elif 'bitbucket.org' in url or 'googlecode.com/hg' in url:
            vcs = 'hg'
        elif url.startswith('git:') or 'github.com' in url:
            vcs = 'git'
        elif url.startswith('svn:'):
            vcs = 'svn'
        else:
            vcs = None
            print 'Unable to detect vcs for', url
        self.vcs = vcs

        # Detect the plugin directory to clone/checkout into
        dest_dir_match = re.search(r'to\s+(\w+)', arg)
        if dest_dir_match:
            dest_dir = dest_dir_match.group(1)
        else:
            dest_dir = url.split('/')[-1]
        if dest_dir.endswith('.' + vcs):
            dest_dir = dest_dir[:-(1 + len(vcs))]
        self.dest_dir = dest_dir

        if vcs is not None:
            print ('!' if self.is_bang else '-') * 20, self.dest_dir
            getattr(self, '_vcs_' + vcs)()

    def _run_cmds(self):
        previous_pwd = os.path.abspath('.')
        in_dest_dir = False
        if os.path.exists(self.dest_dir):
            os.chdir(self.dest_dir)
            in_dest_dir = True
        for cmd in self.cmds:
            print cmd
            if cmd.startswith('cd'):
                os.chdir(cmd[2:].strip(' "'))
            else:
                sp.call(cmd, shell=True)
            if not in_dest_dir and os.path.exists(self.dest_dir):
                os.chdir(self.dest_dir)
                in_dest_dir = True
        os.chdir(previous_pwd)

    def _vcs_hg(self):
        self.cmds.insert(0, 'hg ' + ('pull' if os.path.exists(self.dest_dir) else 'clone ' + self.url))
        self._run_cmds()

    def _vcs_git(self):
        self.cmds.insert(0, 'git ' + ('pull' if os.path.exists(self.dest_dir) else 'clone ' + self.url))
        self._run_cmds()

if __name__ == '__main__':
    main()
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.