##// END OF EJS Templates
cleanup monotone conversion and use commandline class
Mikkel Fahnøe Jørgensen -
r6307:6840668e default
parent child Browse files
Show More
@@ -1,214 +1,193 b''
1 1 # monotone support for the convert extension
2 2
3 import os
4 import re
5 import time
3 import os, re, time
6 4 from mercurial import util
5 from common import NoRepo, commit, converter_source, checktool, commandline
6 from mercurial.i18n import _
7 7
8 from common import NoRepo, commit, converter_source, checktool
9
10 class monotone_source(converter_source):
8 class monotone_source(converter_source, commandline):
11 9 def __init__(self, ui, path=None, rev=None):
12 10 converter_source.__init__(self, ui, path, rev)
13
11 commandline.__init__(self, ui, 'mtn')
12
14 13 self.ui = ui
15 14 self.path = path
16 15
17
18 16 # regular expressions for parsing monotone output
19
20 17 space = r'\s*'
21 18 name = r'\s+"((?:[^"]|\\")*)"\s*'
22 19 value = name
23 20 revision = r'\s+\[(\w+)\]\s*'
24 21 lines = r'(?:.|\n)+'
25
26 self.dir_re = re.compile(space + "dir" + name)
27 self.file_re = re.compile(space + "file" + name + "content" + revision)
22
23 self.dir_re = re.compile(space + "dir" + name)
24 self.file_re = re.compile(space + "file" + name + "content" + revision)
28 25 self.add_file_re = re.compile(space + "add_file" + name + "content" + revision)
29 self.patch_re = re.compile(space + "patch" + name + "from" + revision + "to" + revision)
30 self.rename_re = re.compile(space + "rename" + name + "to" + name)
31 self.tag_re = re.compile(space + "tag" + name + "revision" + revision)
26 self.patch_re = re.compile(space + "patch" + name + "from" + revision + "to" + revision)
27 self.rename_re = re.compile(space + "rename" + name + "to" + name)
28 self.tag_re = re.compile(space + "tag" + name + "revision" + revision)
32 29 self.cert_re = re.compile(lines + space + "name" + name + "value" + value)
33 30
34 31 attr = space + "file" + lines + space + "attr" + space
35 32 self.attr_execute_re = re.compile(attr + '"mtn:execute"' + space + '"true"')
36 33
37 34 # cached data
38
39 35 self.manifest_rev = None
40 36 self.manifest = None
41 self.files = None
42 self.dirs = None
43
44 norepo = NoRepo("%s does not look like a monotone repo" % path)
37 self.files = None
38 self.dirs = None
39
40 norepo = NoRepo (_("%s does not look like a monotone repo") % path)
45 41 if not os.path.exists(path):
46 42 raise norepo
47
43
48 44 checktool('mtn')
49
50 # test if there are are any revisions
45
46 # test if there are any revisions
51 47 self.rev = None
52 try :
48 try:
53 49 self.getheads()
54 except :
55 raise norepo
56
50 except:
51 raise norepo
57 52 self.rev = rev
58 53
59
60 def mtncmd(self, arg):
61 cmdline = "mtn -d %s automate %s" % (util.shellquote(self.path), arg)
62 self.ui.debug(cmdline, '\n')
63 p = util.popen(cmdline)
64 result = p.read()
65 if p.close():
66 raise IOError()
67 return result
68
54 def mtnrun(self, *args, **kwargs):
55 kwargs['d'] = self.path
56 return self.run0('automate', *args, **kwargs)
57
69 58 def mtnloadmanifest(self, rev):
70 59 if self.manifest_rev == rev:
71 60 return
61 self.manifest = self.mtnrun("get_manifest_of", rev).split("\n\n")
72 62 self.manifest_rev = rev
73 self.manifest = self.mtncmd("get_manifest_of %s" % rev).split("\n\n")
74
75 manifest = self.manifest
76 files = {}
77 dirs = {}
63 self.files = {}
64 self.dirs = {}
78 65
79 for e in manifest:
66 for e in self.manifest:
80 67 m = self.file_re.match(e)
81 if m:
68 if m:
82 69 attr = ""
83 70 name = m.group(1)
84 71 node = m.group(2)
85 72 if self.attr_execute_re.match(e):
86 73 attr += "x"
87 files[name] = (node, attr)
74 self.files[name] = (node, attr)
88 75 m = self.dir_re.match(e)
89 76 if m:
90 dirs[m.group(1)] = True
91
92 self.files = files
93 self.dirs = dirs
77 self.dirs[m.group(1)] = True
94 78
95 79 def mtnisfile(self, name, rev):
96 80 # a non-file could be a directory or a deleted or renamed file
97 81 self.mtnloadmanifest(rev)
98 try :
82 try:
99 83 self.files[name]
100 84 return True
101 85 except KeyError:
102 86 return False
103
87
104 88 def mtnisdir(self, name, rev):
105 89 self.mtnloadmanifest(rev)
106 try :
90 try:
107 91 self.dirs[name]
108 92 return True
109 93 except KeyError:
110 94 return False
111
95
112 96 def mtngetcerts(self, rev):
113 97 certs = {"author":"<missing>", "date":"<missing>",
114 98 "changelog":"<missing>", "branch":"<missing>"}
115 cert_list = self.mtncmd("certs %s" % rev).split("\n\n")
99 cert_list = self.mtnrun("certs", rev).split("\n\n")
116 100 for e in cert_list:
117 101 m = self.cert_re.match(e)
118 102 if m:
119 103 certs[m.group(1)] = m.group(2)
120 104 return certs
121
122 def mtngetparents(self, rev):
123 parents = self.mtncmd("parents %s" % rev).strip("\n").split("\n")
124 p = []
125 for x in parents:
126 if len(x) >= 40: # blank revs have been seen otherwise
127 p.append(x)
128 return p
129 105
130 106 def mtnrenamefiles(self, files, fromdir, todir):
131 107 renamed = {}
132 108 for tofile in files:
133 109 suffix = tofile.lstrip(todir)
134 110 if todir + suffix == tofile:
135 111 renamed[tofile] = (fromdir + suffix).lstrip("/")
136 112 return renamed
137 113
138
114
139 115 # implement the converter_source interface:
140
116
141 117 def getheads(self):
142 if not self.rev or self.rev == "":
143 return self.mtncmd("leaves").splitlines()
118 if not self.rev:
119 return self.mtnrun("leaves").splitlines()
144 120 else:
145 121 return [self.rev]
146 122
147 123 def getchanges(self, rev):
148 revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
124 #revision = self.mtncmd("get_revision %s" % rev).split("\n\n")
125 revision = self.mtnrun("get_revision", rev).split("\n\n")
149 126 files = {}
150 127 copies = {}
151 128 for e in revision:
152 129 m = self.add_file_re.match(e)
153 130 if m:
154 131 files[m.group(1)] = rev
155 132 m = self.patch_re.match(e)
156 133 if m:
157 134 files[m.group(1)] = rev
158 135
159 136 # Delete/rename is handled later when the convert engine
160 137 # discovers an IOError exception from getfile,
161 138 # but only if we add the "from" file to the list of changes.
162 139 m = self.rename_re.match(e)
163 140 if m:
164 141 toname = m.group(2)
165 142 fromname = m.group(1)
166 143 if self.mtnisfile(toname, rev):
167 144 copies[toname] = fromname
168 145 files[toname] = rev
169 146 files[fromname] = rev
170 147 if self.mtnisdir(toname, rev):
171 148 renamed = self.mtnrenamefiles(self.files, fromname, toname)
172 149 for tofile, fromfile in renamed.items():
173 self.ui.debug (("copying file in renamed dir from '%s' to '%s'" % (fromfile, tofile)), "\n")
150 self.ui.debug (_("copying file in renamed dir from '%s' to '%s'") % (fromfile, tofile), '\n')
174 151 files[tofile] = rev
175 152 for fromfile in renamed.values():
176 153 files[fromfile] = rev
154 return (files.items(), copies)
177 155
178 return (files.items(), copies)
179
180 156 def getmode(self, name, rev):
181 157 self.mtnloadmanifest(rev)
182 try :
158 try:
183 159 node, attr = self.files[name]
184 160 return attr
185 161 except KeyError:
186 162 return ""
187
163
188 164 def getfile(self, name, rev):
189 165 if not self.mtnisfile(name, rev):
190 166 raise IOError() # file was deleted or renamed
191 return self.mtncmd("get_file_of %s -r %s" % (util.shellquote(name), rev))
192
193 def getcommit(self, rev):
167 try:
168 return self.mtnrun("get_file_of", name, r=rev)
169 except:
170 raise IOError() # file was deleted or renamed
171
172 def getcommit(self, rev):
194 173 certs = self.mtngetcerts(rev)
195 174 return commit(
196 175 author=certs["author"],
197 176 date=util.datestr(util.strdate(certs["date"], "%Y-%m-%dT%H:%M:%S")),
198 177 desc=certs["changelog"],
199 178 rev=rev,
200 parents=self.mtngetparents(rev),
179 parents=self.mtnrun("parents", rev).splitlines(),
201 180 branch=certs["branch"])
202 181
203 182 def gettags(self):
204 183 tags = {}
205 for e in self.mtncmd("tags").split("\n\n"):
184 for e in self.mtnrun("tags").split("\n\n"):
206 185 m = self.tag_re.match(e)
207 186 if m:
208 187 tags[m.group(1)] = m.group(2)
209 188 return tags
210 189
211 190 def getchangedfiles(self, rev, i):
212 191 # This function is only needed to support --filemap
213 192 # ... and we don't support that
214 193 raise NotImplementedError()
General Comments 0
You need to be logged in to leave comments. Login now