Skip to content

Instantly share code, notes, and snippets.

@seaders
Created June 12, 2014 02:05
Show Gist options
  • Save seaders/5642c04b41cc4ebbef08 to your computer and use it in GitHub Desktop.
Save seaders/5642c04b41cc4ebbef08 to your computer and use it in GitHub Desktop.
import sh
class CommandWrapper(sh.Command):
'''
Here's the 'secret sauce' class, where we can wrap whatever we want for
python usage.
'''
def __init__(self, baseObject):
self.__class__ = type(baseObject.__class__.__name__,
(self.__class__, baseObject.__class__),
{})
self.__dict__ = baseObject.__dict__
'''
A checker function to handle errors, and always return a unicode str.
'''
def _custom_check(self, f, *args, **kwargs):
retval = getattr(sh.Command, f)(self, *args, **kwargs)
if isinstance(retval, sh.Command):
retval = CommandWrapper(retval)
return retval
elif isinstance(retval, sh.RunningCommand):
try:
return unicode(retval).strip()
except Exception as e:
import traceback
import sys
print e
print ''.join(traceback.format_exception(*sys.exc_info()))
return ''
else:
return retval
'''
Make sure that everything goes through the checker function.
'''
def __call__(self, *args, **kwargs):
return self._custom_check('__call__', *args, **kwargs)
class _git(object):
''' Our main underlying git class, where we'd put any custom commands. '''
'''
Pass the working repository directory in on initialisation.
'''
def __init__(self, repo_dir):
self._wrapped_git = CommandWrapper(getattr(sh, 'git').
bake(_cwd=repo_dir))
'''
Default git checkout to always checkout the 'master' branch.
'''
def checkout(self, branch='master', *args):
return self._wrapped_git.checkout(branch, *args)
'''
Add a custom 'addAll' command, a shortcut to 'git add -A'
'''
def addAll(self):
return self._wrapped_git.add('-A')
# The actual class we create. We inherit from _git for type completion and
# such, but never actuall work with that.
class Git(_git):
'''
Create a internal object that we proxy everything to.
'''
def __init__(self, *args, **kwargs):
self._obj = _git(*args, **kwargs)
def __getattribute__(self, name):
# We can only access _obj with this special python call. Calling
# self._obj would just call this again, and end up in a recursion
# error.
obj = object.__getattribute__(self, '_obj')
try:
# Check to see if we've made a custom function in the _git class
# above.
f = getattr(obj, name)
except AttributeError:
# If it doesn't exist there, call the CommandWrapper _wrapped_git
# of our internal object.
f = getattr(obj._wrapped_git, name)
'''
This next part's optional, but I prefer it. Wrap the returned function
in a try/except block and return a '1' (non-zero / error return value).
'''
def wrapper(*args, **kwargs):
try:
return f(*args, **kwargs)
except getattr(sh, 'ErrorReturnCode_1') as e:
print e
return 1
return wrapper
if '__main__' == __name__:
# Set your base repository location
git = Git('/Developer/repos/git/frameworks')
# Call our custom function, calls the function from _git
git.checkout()
# Call directly to the bash git command.
print git.describe()
#
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment