Skip to content

Commit

Permalink
Fix Version control backends (broken since branches merge)
Browse files Browse the repository at this point in the history
  • Loading branch information
tobami committed Jun 19, 2011
1 parent 4d7dbbc commit 6cefd8e
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 37 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ field will be shown in the Changes and Timeline views.

**Note**: Git and Mercurial need to locally clone the repository. That means that your codespeed/speedcenter/repos directory will need to be owned by the server. In the case of a typical Apache installation, you'll need to type `sudo chown www-data:www-data codespeed/speedcenter/repos`

**Note**: The Github backend is still experimental. It doesn't show all commits
since the last tested revision, but only logs for those commits present in the
Codespeed DB. It also requires the package isodat (`pip install isodate`)

# Saving data

Data is saved POSTing to `http://localhost:8000/result/add/`.
Expand Down
2 changes: 2 additions & 0 deletions speedcenter/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ def save_to_speedcenter(url=None, project=None, commitid=None, executable=None,
parser.add_option("--max", type="float")
parser.add_option("--min", type="float")
parser.add_option("--project")
parser.add_option("--branch")
parser.add_option("--result-date")
parser.add_option("--result-value", type="float")
parser.add_option("--revision_date")
Expand All @@ -106,6 +107,7 @@ def save_to_speedcenter(url=None, project=None, commitid=None, executable=None,
for k, v in options.__dict__.items():
if v is not None:
kwargs[k] = v
kwargs.setdefault('branch', 'default')

if not kwargs['url'].endswith("/result/add/"):
kwargs['url'] = urljoin(kwargs['url'], '/result/add/')
Expand Down
22 changes: 12 additions & 10 deletions speedcenter/codespeed/git.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from subprocess import Popen, PIPE
import datetime
import os
import logging

from django.conf import settings

Expand All @@ -26,20 +27,22 @@ def updaterepo(project, update=True):
cmd = ['git', 'clone', project.repo_path, repo_name]
p = Popen(cmd, stdout=PIPE, stderr=PIPE,
cwd=settings.REPOSITORY_BASE_PATH)
logging.debug('Cloning Git repo {0}for project {1}'.format(
project.repo_path, project))
stdout, stderr = p.communicate()

if p.returncode != 0:
raise RuntimeError("%s returned %s: %s" % (" ".join(cmd),
p.returncode,
stderr))
raise RuntimeError("%s returned %s: %s" % (
" ".join(cmd), p.returncode, stderr))
else:
return [{'error': False}]

def getlogs(endrev, startrev):
updaterepo(endrev.project, update=False)
updaterepo(endrev.branch.project, update=False)

# TODO: Move all of this onto the model so we can avoid needing to repeat it:
repo_name = os.path.splitext(endrev.project.repo_path.split(os.sep)[-1])[0]
repo_name = os.path.splitext(
endrev.branch.project.repo_path.split(os.sep)[-1])[0]
working_copy = os.path.join(settings.REPOSITORY_BASE_PATH, repo_name)

cmd = ["git", "log",
Expand All @@ -58,16 +61,15 @@ def getlogs(endrev, startrev):
stdout, stderr = p.communicate()

if p.returncode != 0:
raise RuntimeError("%s returned %s: %s" % (" ".join(cmd),
p.returncode,
stderr))
raise RuntimeError("%s returned %s: %s" % (
" ".join(cmd), p.returncode, stderr))
logs = []

for log in filter(None, stdout.split("\x1e")):
(short_commit_id, commit_id, date_t, author_name, author_email,
subject, body) = log.split("\x00", 7)

date = datetime.datetime.fromtimestamp(int(date_t)).strftime("%Y-%m-%d %H:%M:%S")
date = datetime.datetime.fromtimestamp(
int(date_t)).strftime("%Y-%m-%d %H:%M:%S")

logs.append({'date': date, 'message': subject, 'body': body,
'author': author_name, 'author_email': author_email,
Expand Down
20 changes: 11 additions & 9 deletions speedcenter/codespeed/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
Among other things, this means that the codespeed server doesn't need to have
git installed, the ability to write files, etc.
"""

import logging
import urllib
import re
Expand All @@ -26,31 +25,35 @@ def updaterepo(project, update=True):

def getlogs(endrev, startrev):
if endrev != startrev:
revisions = endrev.project.revisions.filter(date__lte=endrev.date,
date__gte=startrev.date)
revisions = endrev.branch.revisions.filter(
date__lte=endrev.date, date__gte=startrev.date)
else:
revisions = [i for i in (startrev, endrev) if i.commitid]

m = GITHUB_URL_RE.match(endrev.project.repo_path)
m = GITHUB_URL_RE.match(endrev.branch.project.repo_path)

if not m:
raise ValueError("Unable to parse Github URL %s" % endrev.project.repo_path)
raise ValueError(
"Unable to parse Github URL %s" % endrev.branch.project.repo_path)

username = m.group("username")
project = m.group("project")

logs = []

#TODO: get all revisions between endrev and startrev,
# not only those present in the Codespeed DB
for revision in revisions:
commit_url = 'http://github.com/api/v2/json/commits/show/%s/%s/%s' % (username, project, revision.commitid)
commit_url = 'http://github.com/api/v2/json/commits/show/%s/%s/%s' % (
username, project, revision.commitid)

commit_json = cache.get(commit_url)

if commit_json is None:
try:
commit_json = json.load(urllib.urlopen(commit_url))
except IOError, e:
logging.exception("Unable to load %s: %s", commit_url, e, exc_info=True)
logging.exception("Unable to load %s: %s",
commit_url, e, exc_info=True)
raise e

if 'error' in commit_json:
Expand Down Expand Up @@ -86,5 +89,4 @@ def getlogs(endrev, startrev):
'commitid': commit['id'],
'short_commit_id': commit['id'][0:7],
'links': {'Github': 'http://github.com%s' % commit['url']}})

return logs
7 changes: 4 additions & 3 deletions speedcenter/codespeed/mercurial.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ def updaterepo(project, update=True):

p = Popen(cmd, stdout=PIPE, stderr=PIPE,
cwd=settings.REPOSITORY_BASE_PATH)

logging.debug('Cloning Mercurial repo {0}for project {1}'.format(
project.repo_path, project))
stdout, stderr = p.communicate()

if p.returncode != 0:
Expand All @@ -37,10 +38,10 @@ def updaterepo(project, update=True):
return [{'error': False}]

def getlogs(endrev, startrev):
updaterepo(endrev.project, update=False)
updaterepo(endrev.branch.project, update=False)

# TODO: Move all of this onto the model so we can avoid needing to repeat it:
repo_name = os.path.splitext(endrev.project.repo_path.split(os.sep)[-1])[0]
repo_name = os.path.splitext(endrev.branch.project.repo_path.split(os.sep)[-1])[0]
working_copy = os.path.join(settings.REPOSITORY_BASE_PATH, repo_name)

cmd = ["hg", "log",
Expand Down
11 changes: 6 additions & 5 deletions speedcenter/codespeed/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ class Project(models.Model):
)

name = models.CharField(unique=True, max_length=30)
repo_type = models.CharField("Repository type", max_length=1, choices=REPO_TYPES, default='N')
repo_type = models.CharField(
"Repository type", max_length=1, choices=REPO_TYPES, default='N')
repo_path = models.CharField("Repository URL", blank=True, max_length=200)
repo_user = models.CharField("Repository username", blank=True, max_length=100)
repo_pass = models.CharField("Repository password", blank=True, max_length=100)
Expand All @@ -30,10 +31,10 @@ def __unicode__(self):
class Branch(models.Model):
name = models.CharField(max_length=20)
project = models.ForeignKey(Project, related_name="branches")

def __unicode__(self):
return self.project.name + ":" + self.name

class Meta:
unique_together = ("name", "project")

Expand All @@ -43,7 +44,7 @@ class Revision(models.Model):
tag = models.CharField(max_length=20, blank=True)
date = models.DateTimeField(null=True)
message = models.TextField(blank=True)
project = models.ForeignKey(Project, related_name="revisions", blank=True)
project = models.ForeignKey(Project, related_name="revisions", null=True, blank=True)
# TODO: Replace author with author name/email or just make it larger so we can do "name <email>"?
author = models.CharField(max_length=30, blank=True)
# TODO: Add committer field(s) for DVCSes which make the distinction?
Expand Down Expand Up @@ -75,7 +76,7 @@ def clean(self):
raise ValidationError("Invalid SVN commit id %s" % self.commitid)
elif self.branch.project.repo_type in ("M", "G", "H") and len(self.commitid) != 40:
raise ValidationError("Invalid %s commit hash %s" % (
self.project.get_repo_type_display(),
self.branch.project.get_repo_type_display(),
self.commitid))


Expand Down
17 changes: 9 additions & 8 deletions speedcenter/codespeed/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ def getcomparisonexes():
exekeys += executablekeys
return all_executables, exekeys


def getcomparisondata(request):
if request.method != 'GET':
return HttpResponseNotAllowed('GET')
Expand Down Expand Up @@ -615,22 +616,23 @@ def changes(request):
# belongs to another project (project changed) and then trigger the
# repopulation of the revision selection selectbox
projectmatrix = {}
for e in executables: projectmatrix[e.id] = e.project.name
for e in executables:
projectmatrix[e.id] = e.project.name
projectmatrix = json.dumps(projectmatrix)
projectlist = []
for p in Project.objects.filter(
track=True
).exclude(
id=defaultexecutable.project.id
):
id=defaultexecutable.project.id):
projectlist.append(p)
revisionboxes = { defaultexecutable.project.name: lastrevisions }
for p in projectlist:
revisionboxes[p.name] = Revision.objects.filter(
branch__project=p
).order_by('-date')[:revlimit]

return render_to_response('codespeed/changes.html', locals(), context_instance=RequestContext(request))

return render_to_response('codespeed/changes.html',
locals(), context_instance=RequestContext(request))


def reports(request):
Expand All @@ -650,9 +652,8 @@ def displaylogs(request):
error = False
try:
startrev = Revision.objects.filter(
project=rev.branch.project
branch=rev.branch.project
).filter(date__lt=rev.date).order_by('-date')[:1]

if not len(startrev):
startrev = rev
else:
Expand Down Expand Up @@ -690,7 +691,7 @@ def getcommitlogs(rev, startrev, update=False):
else:
if rev.branch.project.repo_type not in ("N", ""):
logging.warning("Don't know how to retrieve logs from %s project",
rev.branch.project.get_repo_type_display())
rev.branch.project.get_repo_type_display())
return logs

if update:
Expand Down
4 changes: 2 additions & 2 deletions speedcenter/templates/codespeed/changes_table.html
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@
<tbody>
<tr class="commit-id"><th class="infofirst">Commit</td><td>{{ rev.commitid }}</td></tr>
<tr class="date"><th class="infofirst">Date</td><td>{{ rev.date }}</td></tr>
{% ifnotequal rev.project.repo_type "N" %}
<tr class="repo-path"><th class="infofirst">Repo</th><td>{{ rev.project.repo_path }}</td></tr>
{% ifnotequal rev.branch.project.repo_type "N" %}
<tr class="repo-path"><th class="infofirst">Repo</th><td>{{ rev.branch.project.repo_path }}</td></tr>
{% endifnotequal %}
</tbody>
</table>
Expand Down

0 comments on commit 6cefd8e

Please sign in to comment.