Show More
@@ -19,6 +19,7 class monotone_source(converter_source, | |||||
19 |
|
19 | |||
20 | self.ui = ui |
|
20 | self.ui = ui | |
21 | self.path = path |
|
21 | self.path = path | |
|
22 | self.automatestdio = False | |||
22 |
|
23 | |||
23 | norepo = NoRepo(_("%s does not look like a monotone repository") |
|
24 | norepo = NoRepo(_("%s does not look like a monotone repository") | |
24 | % path) |
|
25 | % path) | |
@@ -73,9 +74,102 class monotone_source(converter_source, | |||||
73 | self.rev = rev |
|
74 | self.rev = rev | |
74 |
|
75 | |||
75 | def mtnrun(self, *args, **kwargs): |
|
76 | def mtnrun(self, *args, **kwargs): | |
|
77 | if self.automatestdio: | |||
|
78 | return self.mtnrunstdio(*args, **kwargs) | |||
|
79 | else: | |||
|
80 | return self.mtnrunsingle(*args, **kwargs) | |||
|
81 | ||||
|
82 | def mtnrunsingle(self, *args, **kwargs): | |||
76 | kwargs['d'] = self.path |
|
83 | kwargs['d'] = self.path | |
77 | return self.run0('automate', *args, **kwargs) |
|
84 | return self.run0('automate', *args, **kwargs) | |
78 |
|
85 | |||
|
86 | def mtnrunstdio(self, *args, **kwargs): | |||
|
87 | # Prepare the command in automate stdio format | |||
|
88 | command = [] | |||
|
89 | for k, v in kwargs.iteritems(): | |||
|
90 | command.append("%s:%s" % (len(k), k)) | |||
|
91 | if v: | |||
|
92 | command.append("%s:%s" % (len(v), v)) | |||
|
93 | if command: | |||
|
94 | command.insert(0, 'o') | |||
|
95 | command.append('e') | |||
|
96 | ||||
|
97 | command.append('l') | |||
|
98 | for arg in args: | |||
|
99 | command += "%s:%s" % (len(arg), arg) | |||
|
100 | command.append('e') | |||
|
101 | command = ''.join(command) | |||
|
102 | ||||
|
103 | self.ui.debug("mtn: sending '%s'\n" % command) | |||
|
104 | self.mtnwritefp.write(command) | |||
|
105 | self.mtnwritefp.flush() | |||
|
106 | ||||
|
107 | return self.mtnstdioreadcommandoutput(command) | |||
|
108 | ||||
|
109 | def mtnstdioreadpacket(self): | |||
|
110 | read = None | |||
|
111 | commandnbr = '' | |||
|
112 | while read != ':': | |||
|
113 | read = self.mtnreadfp.read(1) | |||
|
114 | if not read: | |||
|
115 | raise util.Abort(_('bad mtn packet - no end of commandnbr')) | |||
|
116 | commandnbr += read | |||
|
117 | commandnbr = commandnbr[:-1] | |||
|
118 | ||||
|
119 | stream = self.mtnreadfp.read(1) | |||
|
120 | if stream not in 'mewptl': | |||
|
121 | raise util.Abort(_('bad mtn packet - bad stream type %s' % stream)) | |||
|
122 | ||||
|
123 | read = self.mtnreadfp.read(1) | |||
|
124 | if read != ':': | |||
|
125 | raise util.Abort(_('bad mtn packet - no divider before size')) | |||
|
126 | ||||
|
127 | read = None | |||
|
128 | lengthstr = '' | |||
|
129 | while read != ':': | |||
|
130 | read = self.mtnreadfp.read(1) | |||
|
131 | if not read: | |||
|
132 | raise util.Abort(_('bad mtn packet - no end of packet size')) | |||
|
133 | lengthstr += read | |||
|
134 | try: | |||
|
135 | length = long(lengthstr[:-1]) | |||
|
136 | except TypeError: | |||
|
137 | raise util.Abort(_('bad mtn packet - bad packet size %s') | |||
|
138 | % lengthstr) | |||
|
139 | ||||
|
140 | read = self.mtnreadfp.read(length) | |||
|
141 | if len(read) != length: | |||
|
142 | raise util.Abort(_("bad mtn packet - unable to read full packet " | |||
|
143 | "read %s of %s") % (len(read), length)) | |||
|
144 | ||||
|
145 | return (commandnbr, stream, length, read) | |||
|
146 | ||||
|
147 | def mtnstdioreadcommandoutput(self, command): | |||
|
148 | retval = '' | |||
|
149 | while True: | |||
|
150 | commandnbr, stream, length, output = self.mtnstdioreadpacket() | |||
|
151 | self.ui.debug('mtn: read packet %s:%s:%s\n' % | |||
|
152 | (commandnbr, stream, length)) | |||
|
153 | ||||
|
154 | if stream == 'l': | |||
|
155 | # End of command | |||
|
156 | if output != '0': | |||
|
157 | raise util.Abort(_("mtn command '%s' returned %s") % | |||
|
158 | (command, output)) | |||
|
159 | break | |||
|
160 | elif stream in 'ew': | |||
|
161 | # Error, warning output | |||
|
162 | self.ui.warn(_('%s error:\n') % self.command) | |||
|
163 | self.ui.warn(output) | |||
|
164 | elif stream == 'p': | |||
|
165 | # Progress messages | |||
|
166 | self.ui.debug('mtn: ' + output) | |||
|
167 | elif stream == 'm': | |||
|
168 | # Main stream - command output | |||
|
169 | retval = output | |||
|
170 | ||||
|
171 | return retval | |||
|
172 | ||||
79 | def mtnloadmanifest(self, rev): |
|
173 | def mtnloadmanifest(self, rev): | |
80 | if self.manifest_rev == rev: |
|
174 | if self.manifest_rev == rev: | |
81 | return |
|
175 | return | |
@@ -225,3 +319,43 class monotone_source(converter_source, | |||||
225 | # This function is only needed to support --filemap |
|
319 | # This function is only needed to support --filemap | |
226 | # ... and we don't support that |
|
320 | # ... and we don't support that | |
227 | raise NotImplementedError() |
|
321 | raise NotImplementedError() | |
|
322 | ||||
|
323 | def before(self): | |||
|
324 | # Check if we have a new enough version to use automate stdio | |||
|
325 | version = 0.0 | |||
|
326 | try: | |||
|
327 | versionstr = self.mtnrunsingle("interface_version") | |||
|
328 | version = float(versionstr) | |||
|
329 | except Exception: | |||
|
330 | raise util.Abort(_("unable to determine mtn automate interface " | |||
|
331 | "version")) | |||
|
332 | ||||
|
333 | if version >= 12.0: | |||
|
334 | self.automatestdio = True | |||
|
335 | self.ui.debug("mtn automate version %s - using automate stdio\n" % | |||
|
336 | version) | |||
|
337 | ||||
|
338 | # launch the long-running automate stdio process | |||
|
339 | self.mtnwritefp, self.mtnreadfp = self._run2('automate', 'stdio', | |||
|
340 | '-d', self.path) | |||
|
341 | # read the headers | |||
|
342 | read = self.mtnreadfp.readline() | |||
|
343 | if read != 'format-version: 2\n': | |||
|
344 | raise util.Abort(_('mtn automate stdio header unexpected: %s') | |||
|
345 | % read) | |||
|
346 | while read != '\n': | |||
|
347 | read = self.mtnreadfp.readline() | |||
|
348 | if not read: | |||
|
349 | raise util.Abort(_("failed to reach end of mtn automate " | |||
|
350 | "stdio headers")) | |||
|
351 | else: | |||
|
352 | self.ui.debug("mtn automate version %s - not using automate stdio " | |||
|
353 | "(automate >= 12.0 - mtn >= 0.46 is needed)\n" % version) | |||
|
354 | ||||
|
355 | def after(self): | |||
|
356 | if self.automatestdio: | |||
|
357 | self.mtnwritefp.close() | |||
|
358 | self.mtnwritefp = None | |||
|
359 | self.mtnreadfp.close() | |||
|
360 | self.mtnreadfp = None | |||
|
361 |
General Comments 0
You need to be logged in to leave comments.
Login now