Parent: [8e1777] (diff)

Child: [6c2607] (diff)

Download this file

hg.py    96 lines (82 with data), 3.1 kB

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import os
import shutil
import logging
from pymongo import bson
from forgescm import model as M
from .command import Command
log = logging.getLogger(__name__)
class init(Command):
base='hg init'
class clone(Command):
base='hg clone'
class scm_log(Command):
base='hg log -g -p'
class LogParser(object):
def __init__(self, repo_id):
self.repo_id = repo_id
self.result = []
def feed(self, line_iter):
cur_line = line_iter.next()
while True:
try:
if cur_line.startswith('changeset:'):
cur_line = self.parse_header(cur_line, line_iter)
elif cur_line.startswith('diff --git'):
cur_line = self.parse_diff(cur_line, line_iter)
elif cur_line.strip():
log.error('Unexpected line %r', cur_line)
cur_line = line_iter.next()
else:
cur_line = line_iter.next()
except StopIteration:
break
return self.result
def parse_header(self, cur_line, line_iter):
hash = cur_line.split(':')[2].strip()
log.debug('Parsing changeset %s', hash)
r = M.Commit.make(dict(repository_id=self.repo_id,
hash=hash))
while cur_line != '\n':
cur_line = line_iter.next()
if cur_line == '\n': break
cmd, rest = cur_line.split(':', 1)
result = self.parse_line(rest)
if cur_line.startswith('tag:'):
r.tags.append(result)
elif cur_line.startswith('parent:'):
r.parents.append(result)
elif cur_line.startswith('user:'):
r.user = result
elif cur_line.startswith('branch:'):
r.branch = result
elif cur_line.startswith('date:'):
r.date = result
elif cur_line.startswith('summary:'):
r.summary = result
elif cur_line != '\n':
assert False, 'Unknown header: %r' % cur_line
r.m.save()
if self.result and not self.result[-1].parents:
self.result[-1].parents = [ r.hash ]
self.result[-1].m.save()
self.result.append(r)
if cur_line == '\n':
cur_line = line_iter.next()
return cur_line
def parse_line(self, rest):
return rest.lstrip()
def parse_diff(self, cur_line, line_iter):
cmdline = cur_line.split(' ')
r = M.Patch.make(dict(repository_id=self.result[-1].repository_id,
commit_id=self.result[-1]._id,
filename=cmdline[2][2:]))
text_lines = []
while cur_line != '\n':
cur_line = line_iter.next()
if cur_line.startswith('diff'): break
if cur_line != '\n': text_lines.append(cur_line)
r.patch_text = bson.Binary(''.join(text_lines))
r.m.save()
if cur_line == '\n':
cur_line = line_iter.next()
return cur_line