mercurial/ui.py
branchstable
changeset 25855 96a38d44ba09
parent 25660 328739ea70c3
child 25989 2cc4e8385661
--- a/mercurial/ui.py	Fri Jul 03 18:10:58 2015 +0100
+++ b/mercurial/ui.py	Sat Jul 18 17:32:38 2015 -0500
@@ -5,9 +5,10 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
+import inspect
 from i18n import _
 import errno, getpass, os, socket, sys, tempfile, traceback
-import config, scmutil, util, error, formatter
+import config, scmutil, util, error, formatter, progress
 from node import hex
 
 samplehgrcs = {
@@ -152,7 +153,7 @@
         try:
             cfg.read(filename, fp, sections=sections, remap=remap)
             fp.close()
-        except error.ConfigError, inst:
+        except error.ConfigError as inst:
             if trusted:
                 raise
             self.warn(_("ignored: %s\n") % str(inst))
@@ -584,6 +585,7 @@
         "cmdname.type" is recommended. For example, status issues
         a label of "status.modified" for modified files.
         '''
+        self._progclear()
         if self._buffers:
             self._buffers[-1].extend([str(a) for a in args])
         else:
@@ -591,6 +593,7 @@
                 self.fout.write(str(a))
 
     def write_err(self, *args, **opts):
+        self._progclear()
         try:
             if self._bufferstates and self._bufferstates[-1][0]:
                 return self.write(*args, **opts)
@@ -602,7 +605,7 @@
             # including stdout.
             if not getattr(self.ferr, 'closed', False):
                 self.ferr.flush()
-        except IOError, inst:
+        except IOError as inst:
             if inst.errno not in (errno.EPIPE, errno.EIO, errno.EBADF):
                 raise
 
@@ -842,7 +845,7 @@
         output will be redirected if fout is not stdout.
         '''
         out = self.fout
-        if util.any(s[1] for s in self._bufferstates):
+        if any(s[1] for s in self._bufferstates):
             out = self
         return util.system(cmd, environ=environ, cwd=cwd, onerr=onerr,
                            errprefix=errprefix, out=out)
@@ -867,8 +870,8 @@
                                ''.join(causetb),
                                ''.join(exconly))
             else:
-                traceback.print_exception(exc[0], exc[1], exc[2],
-                                          file=self.ferr)
+                output = traceback.format_exception(exc[0], exc[1], exc[2])
+                self.write_err(''.join(output))
         return self.tracebackflag or force
 
     def geteditor(self):
@@ -885,6 +888,22 @@
                 os.environ.get("VISUAL") or
                 os.environ.get("EDITOR", editor))
 
+    @util.propertycache
+    def _progbar(self):
+        """setup the progbar singleton to the ui object"""
+        if (self.quiet or self.debugflag
+                or self.configbool('progress', 'disable', False)
+                or not progress.shouldprint(self)):
+            return None
+        return getprogbar(self)
+
+    def _progclear(self):
+        """clear progress bar output if any. use it before any output"""
+        if '_progbar' not in vars(self): # nothing loadef yet
+            return
+        if self._progbar is not None and self._progbar.printed:
+            self._progbar.clear()
+
     def progress(self, topic, pos, item="", unit="", total=None):
         '''show a progress message
 
@@ -901,8 +920,10 @@
         All topics should be marked closed by setting pos to None at
         termination.
         '''
-
-        if pos is None or not self.debugflag:
+        if self._progbar is not None:
+            self._progbar.progress(topic, pos, item=item, unit=unit,
+                                   total=total)
+        if pos is None or not self.configbool('progress', 'debug'):
             return
 
         if unit:
@@ -938,6 +959,16 @@
         '''
         return msg
 
+    def develwarn(self, msg):
+        """issue a developer warning message"""
+        msg = 'devel-warn: ' + msg
+        if self.tracebackflag:
+            util.debugstacktrace(msg, 2)
+        else:
+            curframe = inspect.currentframe()
+            calframe = inspect.getouterframes(curframe, 2)
+            self.write_err('%s at: %s:%s (%s)\n' % ((msg,) + calframe[2][1:4]))
+
 class paths(dict):
     """Represents a collection of paths and their configs.
 
@@ -982,3 +1013,15 @@
         self.name = name
         # We'll do more intelligent things with rawloc in the future.
         self.loc = rawloc
+
+# we instantiate one globally shared progress bar to avoid
+# competing progress bars when multiple UI objects get created
+_progresssingleton = None
+
+def getprogbar(ui):
+    global _progresssingleton
+    if _progresssingleton is None:
+        # passing 'ui' object to the singleton is fishy,
+        # this is how the extension used to work but feel free to rework it.
+        _progresssingleton = progress.progbar(ui)
+    return _progresssingleton