comparison mercurial/ui.py @ 21132:350dc24a553d

ui: pushbuffer can now also capture stderr We need an easy way to capture both stderr and stdout during bundle2 processing of a remote bundle. This changeset adds simple changes to the `ui` class to make this possible. I expect the interface to change in future releases as bundle2 will probably want to distinguish stdout and stderr. The current change will, however, do for now.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 16 Apr 2014 23:36:57 -0400
parents f144928dd058
children 9336bc7dca8e
comparison
equal deleted inserted replaced
21131:b7435117d951 21132:350dc24a553d
10 import config, scmutil, util, error, formatter 10 import config, scmutil, util, error, formatter
11 from node import hex 11 from node import hex
12 12
13 class ui(object): 13 class ui(object):
14 def __init__(self, src=None): 14 def __init__(self, src=None):
15 # _buffers: used for temporary capture of output
15 self._buffers = [] 16 self._buffers = []
17 # _bufferstates: Should the temporary capture includes stderr
18 self._bufferstates = []
16 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False 19 self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
17 self._reportuntrusted = True 20 self._reportuntrusted = True
18 self._ocfg = config.config() # overlay 21 self._ocfg = config.config() # overlay
19 self._tcfg = config.config() # trusted 22 self._tcfg = config.config() # trusted
20 self._ucfg = config.config() # untrusted 23 self._ucfg = config.config() # untrusted
469 path = self.config('paths', loc) 472 path = self.config('paths', loc)
470 if not path and default is not None: 473 if not path and default is not None:
471 path = self.config('paths', default) 474 path = self.config('paths', default)
472 return path or loc 475 return path or loc
473 476
474 def pushbuffer(self): 477 def pushbuffer(self, error=False):
478 """install a buffer to capture standar output of the ui object
479
480 If error is True, the error output will be captured too."""
475 self._buffers.append([]) 481 self._buffers.append([])
482 self._bufferstates.append(error)
476 483
477 def popbuffer(self, labeled=False): 484 def popbuffer(self, labeled=False):
478 '''pop the last buffer and return the buffered output 485 '''pop the last buffer and return the buffered output
479 486
480 If labeled is True, any labels associated with buffered 487 If labeled is True, any labels associated with buffered
482 on the output returned, but extensions and GUI tools may 489 on the output returned, but extensions and GUI tools may
483 handle this argument and returned styled output. If output 490 handle this argument and returned styled output. If output
484 is being buffered so it can be captured and parsed or 491 is being buffered so it can be captured and parsed or
485 processed, labeled should not be set to True. 492 processed, labeled should not be set to True.
486 ''' 493 '''
494 self._bufferstates.pop()
487 return "".join(self._buffers.pop()) 495 return "".join(self._buffers.pop())
488 496
489 def write(self, *args, **opts): 497 def write(self, *args, **opts):
490 '''write args to output 498 '''write args to output
491 499
509 for a in args: 517 for a in args:
510 self.fout.write(str(a)) 518 self.fout.write(str(a))
511 519
512 def write_err(self, *args, **opts): 520 def write_err(self, *args, **opts):
513 try: 521 try:
522 if self._bufferstates and self._bufferstates[-1]:
523 return self.write(*args, **opts)
514 if not getattr(self.fout, 'closed', False): 524 if not getattr(self.fout, 'closed', False):
515 self.fout.flush() 525 self.fout.flush()
516 for a in args: 526 for a in args:
517 self.ferr.write(str(a)) 527 self.ferr.write(str(a))
518 # stderr may be buffered under win32 when redirected to files, 528 # stderr may be buffered under win32 when redirected to files,