diff --git a/git b/git new file mode 100755 index 00000000000..9d85eba2994 --- /dev/null +++ b/git @@ -0,0 +1,124 @@ +#!/usr/bin/python + +# I wanted to keep this simple at first, so for now this checks out +# from the MASTER branch of a repo at a particular SHA or +# tag. Latest is not supported, you should not be doing +# that. Branch checkouts are not supported. Contribs +# welcome! -- MPD + +try: + import json +except ImportError: + import simplejson as json +import os +import sys +import shlex +import subprocess + +# =========================================== +# convert arguments of form ensure=running name=foo +# to a dictionary +# FIXME: make more idiomatic + +args = " ".join(sys.argv[1:]) +items = shlex.split(args) +params = {} +for x in items: + (k, v) = x.split("=") + params[k] = v + +dest = params['dest'] +repo = params['repo'] +version = params['version'] + +# =========================================== + +def get_version(dest): + ''' samples the version of the git repo ''' + os.chdir(dest) + cmd = "git show --abbrev-commit" + sha = os.popen(cmd).read().split("\n") + sha = sha[0].split()[1] + return sha + +def clone(repo, dest): + ''' makes a new git repo if it does not already exist ''' + try: + os.makedirs(dest) + except: + pass + cmd = "git clone %s %s" % (repo, dest) + cmd = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return cmd.communicate() + +def pull(repo, dest): + ''' updates repo from remote sources ''' + os.chdir(dest) + cmd = "git pull -u origin" + cmd = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + return cmd.communicate() + +def switchver(version, dest): + ''' once pulled, switch to a particular SHA or tag ''' + os.chdir(dest) + if version != 'HEAD': + cmd = "git checkout %s --force" % version + else: + # is there a better way to do this? + cmd = "git rebase origin" + cmd = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + (out, err) = cmd.communicate() + return (out, err) + + +gitconfig = os.path.join(dest, '.git', 'config') + +out, err, status = (None, None, None) + +# if there is no git configuration, do a clone operation +# else pull and switch the version + +before = None +if not os.path.exists(gitconfig): + (out, err) = clone(repo, dest) +else: + # else do a pull + before = get_version(dest) + (out, err) = pull(repo, dest) + +# handle errors from clone or pull + +if out.find('error') != -1: + print json.dumps({ + "failed" : True, + "out" : out, + "err" : err + }) + sys.exit(1) + +# switch to version specified regardless of whether +# we cloned or pulled + +(out, err) = switchver(version, dest) +if err.find('error') != -1: + print json.dumps({ + "failed" : True, + "out" : out, + "err" : err + }) + sys.exit(1) + +# determine if we changed anything + +after = get_version(dest) +changed = False + +if before != after: + changed = True + +print json.dumps({ + "changed" : changed, + "before" : before, + "after" : after +}) +