ui: allow capture of subprocess output stable
authorPierre-Yves David <pierre-yves.david@fb.com>
Thu, 23 Apr 2015 14:57:39 +0100
branchstable
changeset 24848 2f88821856eb
parent 24847 b705e5ab3b07
child 24849 aff2aca3420e
ui: allow capture of subprocess output We want to capture hooks output during bundle2 processing. For this purpose we introduce a new 'subproc' argument to 'ui.pushbuffer'. When set, the output of sub process created through 'ui.system' will be captured in the buffer too. This will be used in the next changeset.
hgext/color.py
mercurial/ui.py
--- a/hgext/color.py	Thu Apr 23 14:20:36 2015 +0100
+++ b/hgext/color.py	Thu Apr 23 14:57:39 2015 +0100
@@ -445,7 +445,7 @@
             return super(colorui, self).write_err(*args, **opts)
 
         label = opts.get('label', '')
-        if self._bufferstates and self._bufferstates[-1]:
+        if self._bufferstates and self._bufferstates[-1][0]:
             return self.write(*args, **opts)
         if self._colormode == 'win32':
             for a in args:
--- a/mercurial/ui.py	Thu Apr 23 14:20:36 2015 +0100
+++ b/mercurial/ui.py	Thu Apr 23 14:57:39 2015 +0100
@@ -76,7 +76,8 @@
     def __init__(self, src=None):
         # _buffers: used for temporary capture of output
         self._buffers = []
-        # _bufferstates: Should the temporary capture includes stderr
+        # _bufferstates:
+        #   should the temporary capture include stderr and subprocess output
         self._bufferstates = []
         self.quiet = self.verbose = self.debugflag = self.tracebackflag = False
         self._reportuntrusted = True
@@ -540,12 +541,15 @@
     def paths(self):
         return paths(self)
 
-    def pushbuffer(self, error=False):
+    def pushbuffer(self, error=False, subproc=False):
         """install a buffer to capture standard output of the ui object
 
-        If error is True, the error output will be captured too."""
+        If error is True, the error output will be captured too.
+
+        If subproc is True, output from subprocesses (typically hooks) will be
+        captured too."""
         self._buffers.append([])
-        self._bufferstates.append(error)
+        self._bufferstates.append((error, subproc))
 
     def popbuffer(self, labeled=False):
         '''pop the last buffer and return the buffered output
@@ -585,7 +589,7 @@
 
     def write_err(self, *args, **opts):
         try:
-            if self._bufferstates and self._bufferstates[-1]:
+            if self._bufferstates and self._bufferstates[-1][0]:
                 return self.write(*args, **opts)
             if not getattr(self.fout, 'closed', False):
                 self.fout.flush()
@@ -834,8 +838,11 @@
         '''execute shell command with appropriate output stream. command
         output will be redirected if fout is not stdout.
         '''
+        out = self.fout
+        if util.any(s[1] for s in self._bufferstates):
+            out = self
         return util.system(cmd, environ=environ, cwd=cwd, onerr=onerr,
-                           errprefix=errprefix, out=self.fout)
+                           errprefix=errprefix, out=out)
 
     def traceback(self, exc=None, force=False):
         '''print exception traceback if traceback printing enabled or forced.