Skip to content

Commit 1bdc67a

Browse files
committed
Get commit date
1 parent 4efd1cc commit 1bdc67a

File tree

4 files changed

+131
-80
lines changed

4 files changed

+131
-80
lines changed

codespeed/commits/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from .logs import get_logs
1+
from .logs import get_logs, get_commit_date

codespeed/commits/logs.py

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,62 @@
11
# -*- coding: utf-8 -*-
22
from __future__ import absolute_import, unicode_literals
33

4+
import datetime
45
import logging
56

67
logger = logging.getLogger(__name__)
78

89

9-
def get_logs(rev, startrev, update=False):
10-
logs = []
11-
project = rev.branch.project
10+
def get_scm(project):
1211
if project.repo_type == project.SUBVERSION:
1312
from .subversion import getlogs, updaterepo
1413
elif project.repo_type == project.MERCURIAL:
15-
from .mercurial import getlogs, updaterepo
14+
from .mercurial import Mercurial
15+
return Mercurial(project)
1616
elif project.repo_type == project.GIT:
1717
from .git import getlogs, updaterepo
1818
elif project.repo_type == project.GITHUB:
1919
from .github import getlogs, updaterepo
2020
else:
21+
return None
22+
23+
24+
def get_logs(rev, startrev, update=False):
25+
logs = []
26+
project = rev.branch.project
27+
28+
scm = get_scm(project)
29+
if scm is None:
2130
if project.repo_type not in (project.NO_LOGS, ""):
2231
logger.warning("Don't know how to retrieve logs from %s project",
2332
project.get_repo_type_display())
2433
return logs
2534

2635
if update:
27-
updaterepo(rev.branch.project)
36+
scm.update_repo(project)
2837

29-
logs = getlogs(rev, startrev)
38+
logs = scm.get_logs(rev, startrev)
3039

3140
# Remove last log because the startrev log shouldn't be shown
3241
if len(logs) > 1 and logs[-1].get('commitid') == startrev.commitid:
3342
logs.pop()
3443

3544
return logs
45+
46+
47+
def _get_commit_date(project, commit_id):
48+
scm = get_scm(project)
49+
if scm is None:
50+
return None
51+
52+
return scm.get_commit_date(commit_id)
53+
54+
def get_commit_date(project, commit_id):
55+
date = _get_commit_date(project, commit_id)
56+
if date is not None:
57+
return date
58+
59+
if project.repo_type not in (project.NO_LOGS, ""):
60+
logger.warning("Failed to get the date of the commit %r of project %s",
61+
commit_id, project.get_repo_type_display())
62+
return datetime.datetime.today()

codespeed/commits/mercurial.py

Lines changed: 93 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -13,80 +13,103 @@
1313
logger = logging.getLogger(__name__)
1414

1515

16-
def updaterepo(project, update=True):
17-
if os.path.exists(project.working_copy):
18-
if not update:
19-
return
16+
class Mercurial:
17+
def __init__(self, project):
18+
self.project = project
19+
20+
def update_repo(self, update=True):
21+
project = self.project
22+
if os.path.exists(project.working_copy):
23+
if not update:
24+
return
25+
26+
p = Popen(['hg', 'pull', '-u'], stdout=PIPE, stderr=PIPE,
27+
cwd=project.working_copy)
28+
stdout, stderr = p.communicate()
29+
30+
if p.returncode != 0 or stderr:
31+
raise CommitLogError("hg pull returned %s: %s" % (p.returncode,
32+
stderr))
33+
else:
34+
return [{'error': False}]
35+
else:
36+
# Clone repo
37+
cmd = ['hg', 'clone', project.repo_path, project.repo_name]
38+
39+
p = Popen(cmd, stdout=PIPE, stderr=PIPE,
40+
cwd=settings.REPOSITORY_BASE_PATH)
41+
logger.debug('Cloning Mercurial repo {0} for project {1}'.format(
42+
project.repo_path, project))
43+
stdout, stderr = p.communicate()
44+
45+
if p.returncode != 0:
46+
raise CommitLogError("%s returned %s: %s" % (" ".join(cmd),
47+
p.returncode,
48+
stderr))
49+
else:
50+
return [{'error': False}]
51+
52+
def get_logs(self, endrev, startrev):
53+
self.update_repo(update=False)
54+
55+
cmd = ["hg", "log",
56+
"-r", "%s::%s" % (startrev.commitid, endrev.commitid),
57+
"--template", "{rev}:{node|short}\n{node}\n{author|user}\n{author|email}\n{date}\n{desc}\n=newlog=\n"]
2058

21-
p = Popen(['hg', 'pull', '-u'], stdout=PIPE, stderr=PIPE,
22-
cwd=project.working_copy)
59+
working_copy = self.project.working_copy
60+
p = Popen(cmd,
61+
stdout=PIPE, stderr=PIPE,
62+
universal_newlines=True,
63+
cwd=working_copy)
2364
stdout, stderr = p.communicate()
2465

25-
if p.returncode != 0 or stderr:
26-
raise CommitLogError("hg pull returned %s: %s" % (p.returncode,
27-
stderr))
66+
if p.returncode != 0:
67+
raise CommitLogError(str(stderr))
2868
else:
29-
return [{'error': False}]
30-
else:
31-
# Clone repo
32-
cmd = ['hg', 'clone', project.repo_path, project.repo_name]
33-
34-
p = Popen(cmd, stdout=PIPE, stderr=PIPE,
35-
cwd=settings.REPOSITORY_BASE_PATH)
36-
logger.debug('Cloning Mercurial repo {0} for project {1}'.format(
37-
project.repo_path, project))
69+
stdout = stdout.rstrip('\n') # Remove last newline
70+
logs = []
71+
for log in stdout.split("=newlog=\n"):
72+
elements = []
73+
elements = log.split('\n')[:-1]
74+
if len(elements) < 6:
75+
# "Malformed" log
76+
logs.append(
77+
{'date': '-', 'message': 'error parsing log', 'commitid': '-'})
78+
else:
79+
short_commit_id = elements.pop(0)
80+
commit_id = elements.pop(0)
81+
author_name = elements.pop(0)
82+
author_email = elements.pop(0)
83+
date = elements.pop(0)
84+
# All other newlines should belong to the description text. Join.
85+
message = '\n'.join(elements)
86+
87+
# Parse date
88+
date = date.split('-')[0]
89+
date = datetime.datetime.fromtimestamp(float(date)).strftime("%Y-%m-%d %H:%M:%S")
90+
91+
# Add changeset info
92+
logs.append({
93+
'date': date, 'author': author_name,
94+
'author_email': author_email, 'message': message,
95+
'short_commit_id': short_commit_id, 'commitid': commit_id})
96+
# Remove last log here because mercurial saves the short hast as commitid now
97+
if len(logs) > 1 and logs[-1].get('short_commit_id') == startrev.commitid:
98+
logs.pop()
99+
return logs
100+
101+
def get_commit_date(self, commit_id):
102+
self.update_repo(update=False)
103+
104+
cmd = ["hg", "log", "-r", commit_id, "--template", "{date|rfc3339date}\n"]
105+
106+
p = Popen(cmd,
107+
stdout=PIPE, stderr=PIPE,
108+
universal_newlines=True,
109+
cwd=self.project.working_copy)
38110
stdout, stderr = p.communicate()
39111

40112
if p.returncode != 0:
41-
raise CommitLogError("%s returned %s: %s" % (" ".join(cmd),
42-
p.returncode,
43-
stderr))
44-
else:
45-
return [{'error': False}]
46-
47-
48-
def getlogs(endrev, startrev):
49-
updaterepo(endrev.branch.project, update=False)
50-
51-
cmd = ["hg", "log",
52-
"-r", "%s::%s" % (startrev.commitid, endrev.commitid),
53-
"--template", "{rev}:{node|short}\n{node}\n{author|user}\n{author|email}\n{date}\n{desc}\n=newlog=\n"]
54-
55-
working_copy = endrev.branch.project.working_copy
56-
p = Popen(cmd, stdout=PIPE, stderr=PIPE, cwd=working_copy)
57-
stdout, stderr = p.communicate()
58-
59-
if p.returncode != 0:
60-
raise CommitLogError(str(stderr))
61-
else:
62-
stdout = stdout.rstrip('\n') # Remove last newline
63-
logs = []
64-
for log in stdout.split("=newlog=\n"):
65-
elements = []
66-
elements = log.split('\n')[:-1]
67-
if len(elements) < 6:
68-
# "Malformed" log
69-
logs.append(
70-
{'date': '-', 'message': 'error parsing log', 'commitid': '-'})
71-
else:
72-
short_commit_id = elements.pop(0)
73-
commit_id = elements.pop(0)
74-
author_name = elements.pop(0)
75-
author_email = elements.pop(0)
76-
date = elements.pop(0)
77-
# All other newlines should belong to the description text. Join.
78-
message = '\n'.join(elements)
79-
80-
# Parse date
81-
date = date.split('-')[0]
82-
date = datetime.datetime.fromtimestamp(float(date)).strftime("%Y-%m-%d %H:%M:%S")
83-
84-
# Add changeset info
85-
logs.append({
86-
'date': date, 'author': author_name,
87-
'author_email': author_email, 'message': message,
88-
'short_commit_id': short_commit_id, 'commitid': commit_id})
89-
# Remove last log here because mercurial saves the short hast as commitid now
90-
if len(logs) > 1 and logs[-1].get('short_commit_id') == startrev.commitid:
91-
logs.pop()
92-
return logs
113+
raise CommitLogError(str(stderr))
114+
115+
return stdout.rstrip()

codespeed/results.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,15 @@ def save_result(data):
7272
b.full_clean()
7373
b.save()
7474

75+
commit_id = data['commitid']
7576
try:
76-
rev = branch.revisions.get(commitid=data['commitid'])
77+
rev = branch.revisions.get(commitid=commit_id)
7778
except Revision.DoesNotExist:
7879
rev_date = data.get("revision_date")
7980
# "None" (as string) can happen when we urlencode the POST data
8081
if not rev_date or rev_date in ["", "None"]:
81-
rev_date = datetime.today()
82-
rev = Revision(branch=branch, project=p, commitid=data['commitid'],
82+
rev_date = commits.get_commit_date(p, commit_id)
83+
rev = Revision(branch=branch, project=p, commitid=commit_id,
8384
date=rev_date)
8485
try:
8586
rev.full_clean()

0 commit comments

Comments
 (0)