Skip to content

Commit 91bba13

Browse files
committed
Git python3 refactor
1 parent f679d55 commit 91bba13

File tree

3 files changed

+78
-24
lines changed

3 files changed

+78
-24
lines changed

codespeed/commits/git.py

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,39 @@
11
import datetime
22
import logging
33
import os
4-
from string import strip
5-
from subprocess import Popen, PIPE
64

5+
from subprocess import Popen, PIPE
76
from django.conf import settings
8-
97
from .exceptions import CommitLogError
108

119
logger = logging.getLogger(__name__)
1210

1311

12+
def execute_command(cmd, cwd):
13+
p = Popen(cmd, stdout=PIPE, stderr=PIPE, cwd=cwd)
14+
stdout, stderr = p.communicate()
15+
stdout = stdout.decode('utf8') if stdout is not None else stdout
16+
stderr = stderr.decode('utf8') if stderr is not None else stderr
17+
return (p, stdout, stderr)
18+
19+
1420
def updaterepo(project, update=True):
1521
if os.path.exists(project.working_copy):
1622
if not update:
1723
return
1824

19-
p = Popen(['git', 'pull'], stdout=PIPE, stderr=PIPE,
20-
cwd=project.working_copy)
25+
p, _, stderr = execute_command(['git', 'pull'], cwd=project.working_copy)
2126

22-
stdout, stderr = p.communicate()
2327
if p.returncode != 0:
2428
raise CommitLogError("git pull returned %s: %s" % (p.returncode,
2529
stderr))
2630
else:
2731
return [{'error': False}]
2832
else:
2933
cmd = ['git', 'clone', project.repo_path, project.repo_name]
30-
p = Popen(cmd, stdout=PIPE, stderr=PIPE,
31-
cwd=settings.REPOSITORY_BASE_PATH)
34+
p, stdout, stderr = execute_command(cmd, settings.REPOSITORY_BASE_PATH)
3235
logger.debug('Cloning Git repo {0} for project {1}'.format(
3336
project.repo_path, project))
34-
stdout, stderr = p.communicate()
3537

3638
if p.returncode != 0:
3739
raise CommitLogError("%s returned %s: %s" % (
@@ -59,32 +61,24 @@ def getlogs(endrev, startrev):
5961
cmd.append(endrev.commitid)
6062

6163
working_copy = endrev.branch.project.working_copy
62-
p = Popen(cmd, stdout=PIPE, stderr=PIPE, cwd=working_copy)
63-
64-
stdout, stderr = p.communicate()
64+
p, stdout, stderr = execute_command(cmd, working_copy)
6565

6666
if p.returncode != 0:
6767
raise CommitLogError("%s returned %s: %s" % (
6868
" ".join(cmd), p.returncode, stderr))
6969
logs = []
70-
for log in filter(None, stdout.split(b'\x1e')):
70+
for log in filter(None, stdout.split('\x1e')):
7171
(short_commit_id, commit_id, date_t, author_name, author_email,
72-
subject, body) = map(strip, log.split(b'\x00', 7))
73-
74-
tag = ""
72+
subject, body) = map(lambda s: s.strip(), log.split('\x00', 7))
7573

7674
cmd = ["git", "tag", "--points-at", commit_id]
77-
proc = Popen(cmd, stdout=PIPE, stderr=PIPE, cwd=working_copy)
7875

7976
try:
80-
stdout, stderr = proc.communicate()
81-
except ValueError:
82-
stdout = b''
83-
stderr = b''
84-
85-
if proc.returncode == 0:
86-
tag = stdout.strip()
77+
p, stdout, stderr = execute_command(cmd, working_copy)
78+
except Exception:
79+
logger.debug('Failed to get tag', exc_info=True)
8780

81+
tag = stdout.strip() if p.returncode == 0 else ""
8882
date = datetime.datetime.fromtimestamp(
8983
int(date_t)).strftime("%Y-%m-%d %H:%M:%S")
9084

codespeed/commits/tests/__init__.py

Whitespace-only changes.
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from datetime import datetime
2+
from django.test import TestCase, override_settings
3+
from mock import Mock, patch
4+
5+
from codespeed.commits.git import getlogs
6+
from codespeed.models import Project, Revision, Branch, Environment
7+
8+
9+
@override_settings(ALLOW_ANONYMOUS_POST=True)
10+
class GitTest(TestCase):
11+
def setUp(self):
12+
self.env = Environment.objects.create(name='env')
13+
self.project = Project.objects.create(name='project',
14+
repo_path='path',
15+
repo_type=Project.GIT)
16+
self.branch = Branch.objects.create(name='default',
17+
project_id=self.project.id)
18+
self.revision = Revision.objects.create(
19+
**{
20+
'commitid': 'id1',
21+
'date': datetime.now(),
22+
'project_id': self.project.id,
23+
'branch_id': self.branch.id,
24+
}
25+
)
26+
27+
@patch("codespeed.commits.git.Popen")
28+
def test_git_output_parsing(self, popen):
29+
# given
30+
outputs = {
31+
"log": b"id\x00long_id\x001583489681\x00author\x00email\x00msg\x00\x1e",
32+
"tag": b'tag',
33+
}
34+
35+
def side_effect(cmd, *args, **kwargs):
36+
ret = Mock()
37+
ret.returncode = 0
38+
git_command = cmd[1] if len(cmd) > 0 else None
39+
output = outputs.get(git_command, b'')
40+
ret.communicate.return_value = (output, b'')
41+
return ret
42+
43+
popen.side_effect = side_effect
44+
45+
# when
46+
# revision doesn't matter here, git commands are mocked
47+
logs = getlogs(self.revision, self.revision)
48+
49+
# then
50+
expected = {
51+
'date': '2020-03-06 04:14:41',
52+
'message': 'msg',
53+
'commitid': 'long_id',
54+
'author': 'author',
55+
'author_email': 'email',
56+
'body': '',
57+
'short_commit_id': 'id',
58+
'tag': 'tag',
59+
}
60+
self.assertEquals([expected], logs)

0 commit comments

Comments
 (0)