Created
June 12, 2014 02:05
-
-
Save seaders/5642c04b41cc4ebbef08 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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