Skip to content

Commit

Permalink
Add Mercurial support
Browse files Browse the repository at this point in the history
  • Loading branch information
tobami committed Dec 24, 2010
1 parent 4746b14 commit 7b50e5a
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 76 deletions.
56 changes: 56 additions & 0 deletions speedcenter/codespeed/mercurial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import os, datetime
from subprocess import Popen, PIPE

path = os.getcwd() + '/repos/'
repodir = path + 'pypy/'

def updaterepo(repo):
if os.path.exists(repodir):
cmd = "hg up"
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, cwd=repodir)
stdout, stderr = p.communicate()
if stderr:
return [{'error': True, 'message': stderr}]
else:
return [{'error': False}]
else:
#os.mkdir(path)
cmd = "hg clone %s" % repo
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, cwd=path)
stdout, stderr = p.communicate()
if stderr:
return [{'error': True, 'message': stderr}]
else:
return [{'error': False}]

def getlogs(endrev, startrev):
if not os.path.exists(repodir):
updaterepo(endrev.project.repo_path)

cmd = "hg log -r %s:%s --template '{rev}:{node|short}\n{author|person} / {author|user}\n{date}\n{desc}\n=newlog=\n'" % (endrev.commitid, startrev.commitid)
p = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE, cwd=repodir)
stdout, stderr = p.communicate()
if stderr:
return [{'error': True, 'message': stderr}]
else:
logs = []
for log in stdout.split("=newlog=\n"):
commitid, author, date, message = ("","","","")
elements = []
elements = log.split('\n')[:-1]
if not len(elements) or len(elements) < 4:
continue
else:
commitid = elements.pop(0)
author = elements.pop(0)
date = elements.pop(0)
message = '\n'.join(elements)

# Parse date
date = date.split('-')[0]
date = datetime.datetime.fromtimestamp(float(date)).strftime("%Y-%m-%d %H:%M:%S")

# Add changeset info
logs.append({'date': date, 'author': author, 'message': message,
'commitid': commitid})
return logs
3 changes: 2 additions & 1 deletion speedcenter/codespeed/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ class Project(models.Model):
REPO_TYPES = (
('N', 'none'),
('G', 'git'),
('S', 'svn'),
('M', 'mercurial'),
('S', 'subversion'),
)

name = models.CharField(unique=True, max_length=30)
Expand Down
57 changes: 57 additions & 0 deletions speedcenter/codespeed/subversion.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# -*- coding: utf-8 -*-
'''Subversion commit logs support'''
from datetime import datetime

def getlogs(newrev, startrev):
import pysvn

logs = []
log_messages = []
loglimit = 200

def get_login(realm, username, may_save):
return True, newrev.project.repo_user, newrev.project.repo_pass, False

client = pysvn.Client()
if newrev.project.repo_user != "":
client.callback_get_login = get_login

try:
log_messages = \
client.log(
newrev.project.repo_path,
revision_start=pysvn.Revision(
pysvn.opt_revision_kind.number, startrev.commitid
),
revision_end=pysvn.Revision(
pysvn.opt_revision_kind.number, newrev.commitid
)
)
except pysvn.ClientError:
return [
{'error': True,
'message': "Could not resolve '" + newrev.project.repo_path + "'"}]
except ValueError:
return [{
'error': True,
'message': "'%s' is an invalid subversion revision number" % newrev.commitid
}]
log_messages.reverse()
s = len(log_messages)
while s > loglimit:
log_messages = log_messages[:s]
s = len(log_messages) - 1

for log in log_messages:
try:
author = log.author
except AttributeError:
author = ""
date = datetime.fromtimestamp(log.date).strftime("%Y-%m-%d %H:%M:%S")
message = log.message
# Add log unless it is the last commit log, which has already been tested
if not (startrev != newrev and log.revision.number == int(startrev.commitid)):
logs.append(
{'date': date, 'author': author, 'message': message,
'commitid': log.revision.number})
return logs
94 changes: 21 additions & 73 deletions speedcenter/codespeed/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,12 @@ def displaylogs(request):
logs.append(rev)
error = False
try:
remotelogs = getcommitlogs(rev)
startrev = Revision.objects.filter(
project=rev.project
).filter(date__lt=rev.date).order_by('-date')[:1]
if not len(startrev): startrev = rev
else: startrev = startrev[0]
remotelogs = getcommitlogs(rev, startrev)
if len(remotelogs):
try:
if remotelogs[0]['error']:
Expand All @@ -658,82 +663,25 @@ def displaylogs(request):
error = str(e)
return render_to_response('codespeed/changes_logs.html', { 'error': error, 'logs': logs })

def getlogsfromsvn(newrev, startrev):
import pysvn
logs = []
log_messages = []
loglimit = 200

def get_login(realm, username, may_save):
return True, newrev.project.repo_user, newrev.project.repo_pass, False

client = pysvn.Client()
if newrev.project.repo_user != "":
client.callback_get_login = get_login

try:
log_messages = \
client.log(
newrev.project.repo_path,
revision_start=pysvn.Revision(
pysvn.opt_revision_kind.number, startrev.commitid
),
revision_end=pysvn.Revision(
pysvn.opt_revision_kind.number, newrev.commitid
)
)
except pysvn.ClientError:
return [
{'error': True,
'message': "Could not resolve '" + newrev.project.repo_path + "'"}]
except ValueError:
return [{
'error': True,
'message': "'%s' is an invalid subversion revision number" % newrev.commitid
}]
log_messages.reverse()
s = len(log_messages)
while s > loglimit:
log_messages = log_messages[:s]
s = len(log_messages) - 1

for log in log_messages:
try:
author = log.author
except AttributeError:
author = ""
date = datetime.fromtimestamp(log.date).strftime("%Y-%m-%d %H:%M:%S")
message = log.message
# Add log unless it is the last commit log, which has already been tested
if not (startrev != newrev and log.revision.number == int(startrev.commitid)):
logs.append(
{'date': date, 'author': author, 'message': message,
'commitid': log.revision.number})
return logs

def getcommitlogs(rev):
logs = []
def getcommitlogs(rev, startrev, update=False):
logs = []
if rev.project.repo_type == 'N' or rev.project.repo_path == "":
#Don't create logs
return []

startrev = Revision.objects.filter(
project=rev.project
).filter(date__lt=rev.date).order_by('-date')[:1]
if not len(startrev): startrev = rev
else: startrev = startrev[0]

if rev.project.repo_type == 'S':
logs = getlogsfromsvn(rev, startrev)
#Don't fetch logs
pass
elif rev.project.repo_type == 'S':
from subversion import getlogs
logs = getlogs(rev, startrev)
elif rev.project.repo_type == 'M':
import mercurial
if update:
resp = mercurial.update(rev.project.repo_path)
if resp.get('error'):
return resp
logs = mercurial.getlogs(rev, startrev)
return logs

def saverevisioninfo(rev):
log = None
if rev.project.repo_type == 'N' or rev.project.repo_path == "":
#Don't create logs
return
elif rev.project.repo_type == 'S':
log = getlogsfromsvn(rev, rev)
log = getcommitlogs(rev, rev, update=True)
if len(log):
log = log[0]
rev.author = log['author']
Expand Down
3 changes: 2 additions & 1 deletion speedcenter/media/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,13 @@ table.info th, table.info td, table.revision th, table.revision td { padding: 0.
table.info tbody td.infofirst { width: 10em; text-align: left; }

tbody.commits tr td { border-bottom: 1px solid #CDCDCD; vertical-align: top; }
tbody.commits tr > td:first-child { padding-right: 20px; }
tbody.commits tr td.date, table.revision tr td.infofirst, div.author, span.note, table.info tbody td.infofirst {
font-size: 92%;
color: #666666;
}
tbody.commits tr td.date { padding-top: 0.6em; }

div > pre { margin-top: 2px; margin-bottom: 2px; white-space: pre-wrap; }

a#permalink { float: right; font-size: small; }
a#permalink:hover { text-decoration: underline; }
Expand Down
Empty file added speedcenter/repos/clonerepos
Empty file.
2 changes: 1 addition & 1 deletion speedcenter/templates/codespeed/changes_logs.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
<tr><td colspan="2">Error while retrieving logs: {{ error }}</td></tr>
{% else %}
{% for log in logs %}
<tr><td class="date">{{ log.date }}</td><td><div class="author">{{ log.author }} <strong>commited</strong> {{ log.commitid }}</div><div>{{ log.message }}</div></td></tr>{% endfor %}
<tr><td class="date">{{ log.date }}</td><td><div class="author">{{ log.author }} <strong>commited</strong> {{ log.commitid }}</div><div><pre>{{ log.message }}</pre></div></td></tr>{% endfor %}
{% endif %}
1 change: 1 addition & 0 deletions speedcenter/templates/codespeed/changes_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
<tbody>
<tr><td class="infofirst">Commit</td><td>{{ rev.commitid }}</td></tr>
<tr><td class="infofirst">Date</td><td>{{ rev.date }}</td></tr>
{% ifnotequal rev.project.repo_type "N" %}<tr><td class="infofirst">Repo</td><td>{{ rev.project.repo_path }}</td></tr>{% endifnotequal %}
</tbody>
{% ifnotequal executable.project.repo_type 'N' %}
<thead class="commits">
Expand Down

0 comments on commit 7b50e5a

Please sign in to comment.