Random SCM and Python Fun
@ 2009-08-03 21:56:05
Filed under: Code Tech Python
The following code abstracts getting branch lists from Mercurial and Git. I may continue fleshing it out for use with the distributed SCM presence system ... or it might just be prototype code, I don't know.
The output I got from my test repos looked like this:
Enjoy, or else!!!!
digg it
seed it
del.icio.us
ma.gnolia
Log in to post comments.
Filed under: Code Tech Python
The following code abstracts getting branch lists from Mercurial and Git. I may continue fleshing it out for use with the distributed SCM presence system ... or it might just be prototype code, I don't know.
The output I got from my test repos looked like this:
['master'] ['default', 'pep8', 'package_creator', 'package_manager', 'repository']
Enjoy, or else!!!!
import os
import re
import subprocess
class SCM(object):
"""
Parent class for all SCM's.
"""
def __init__(self, bin=None):
"""
Creates the instance.
:Parameters:
- `bin`: if a binary is required it's location is here.
"""
self.__bin = bin
def _execute(self, command):
"""
Helps execute shell commands.
:Parameters:
- `command`: the command to execute.
"""
process = subprocess.Popen(command, shell=True,
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.PIPE, close_fds=True)
return process.stdout, process.stderr
def _branch_parser(self, data):
"""
Parses the branch return results. Defaults to a pass through.
:Parameters:
- `data`: the data to parse.
"""
return data
def get_branches(self, repo_path):
"""
Get a list of branches.
:Parameters:
- `repo_path`: path on the file system to the repository.
"""
raise NotImplementedError("_get_branches must be implemented")
# read-only properties
bin = property(lambda s: s.__bin)
class Git(SCM):
"""
The Git SCM.
"""
def _branch_parser(self, data):
"""
Parses the branch return results. Defaults to a pass through.
:Parameters:
- `data`: the data to parse.
"""
return re.findall("\* ([^ ]*)\n", data)
def get_branches(self, repo_path):
"""
Get a list of branches.
:Parameters:
- `repo_path`: path on the file system to the repository.
"""
out, err = self._execute("%s branch" % self.bin)
error_info = err.read()
if error_info:
raise Exception(error_info)
return self._branch_parser(out.read())
class Mercurial(SCM):
"""
The Mercurial (hg) SCM.
"""
def get_branches(self, repo_path):
"""
Get a list of branches.
:Parameters:
- `repo_path`: path on the file system to the repository.
"""
from mercurial import ui, hg
a = hg.repository(ui.ui(), path=repo_path)
return a.branchmap().keys()
class Repository(object):
"""
An SCM agnostic repository class.
"""
def __init__(self, name, location, clone_url, repo_class,
repo_args=[], repo_kwargs={}):
"""
Creates an instance of the repostory representation.
:Parameters:
- `name`: a nice name for the repository.
- `location`: location on the filesystem of the repository.
- `clone_url`: how to clone the repository.
- `repo_class`: the class to use when getting data from the repo.
- `repo_args`: non-keyword args to pass through to the repo class.
- `repo_kwargs`: keword args to pass through to the repo class.
"""
self.__name = name
self.__location = location
self.__repo_class = repo_class
self.__obj = self.__repo_class(*repo_args, **repo_kwargs)
def __repr__(self):
"""
String representation of this instance.
"""
return "<Repository %s: type='%s',class='%s'>" % (
self.name, self.location, self.__repo_class.__name__)
def _get_branches(self):
"""
Gets all branches in this instance of a repository.
"""
os.chdir(self.__location)
return self.__obj.get_branches(self.__location)
# read-only properties
name = property(lambda s: s.__name)
location = property(lambda s: s.__location)
repo_class = property(lambda s: s.__repo_class)
branches = property(lambda s: s._get_branches())
# Examples
g = Repository('pyclean', '/home/steve/Tech/pyclean/', 'http://stevemilner.org', Git, ['/usr/bin/git'])
print g.branches
m = Repository('winlibre', '/tmp/winlibre/', 'http://stevemilner.org', Mercurial)
print m.branches
digg it
seed it
del.icio.us
ma.gnolia
Log in to post comments.

