|
13 | 13 | logger = logging.getLogger(__name__) |
14 | 14 |
|
15 | 15 |
|
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"] |
20 | 58 |
|
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) |
23 | 64 | stdout, stderr = p.communicate() |
24 | 65 |
|
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)) |
28 | 68 | 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) |
38 | 110 | stdout, stderr = p.communicate() |
39 | 111 |
|
40 | 112 | 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() |
0 commit comments