Rev 3024: Hook in detection of TTYTaskDisplay via a class method usable(). in http://people.ubuntu.com/~robertc/baz2.0/nested-pb

Robert Collins robertc at robertcollins.net
Tue Nov 20 08:54:09 GMT 2007


At http://people.ubuntu.com/~robertc/baz2.0/nested-pb

------------------------------------------------------------
revno: 3024
revision-id:robertc at robertcollins.net-20071120085359-5zr8flo9akcq3fxi
parent: robertc at robertcollins.net-20071120083624-w3hwhg08vfshj8ld
committer: Robert Collins <robertc at robertcollins.net>
branch nick: pb.simplify
timestamp: Tue 2007-11-20 19:53:59 +1100
message:
  Hook in detection of TTYTaskDisplay via a class method usable().
modified:
  bzrlib/progress.py             progress.py-20050610070202-df9faaab791964c0
  bzrlib/tests/test_progress.py  test_progress.py-20060308160359-978c397bc79b7fda
=== modified file 'bzrlib/progress.py'
--- a/bzrlib/progress.py	2007-11-20 08:36:24 +0000
+++ b/bzrlib/progress.py	2007-11-20 08:53:59 +0000
@@ -94,6 +94,8 @@
     if to_file is None:
         # XXX: Allow gui etc probing here
         to_file = sys.stderr
+    if TTYTaskDisplay.usable(to_file):
+        return TTYTaskDisplay
     return DotsTaskDisplay
 
 
@@ -401,12 +403,29 @@
     def task_changed(self):
         pass
 
+    @classmethod
+    def usable(klass, stream):
+        """Detect if we can use pretty progress bars on the output stream.
+
+        If this returns true we expect that a human may be looking at that 
+        output, and that we can repaint a line to update it by using '\r'.
+
+        :param stream: A stream that the progress bar is to be drawn on.
+        """
+        isatty = getattr(stream, 'isatty', lambda:False)
+        if not isatty():
+            return False
+        if os.environ.get('TERM') == 'dumb':
+            # e.g. emacs compile window
+            return False
+        return True
+
 
 display_types['none'] = SilentTaskDisplay
 display_types['dummy'] = SilentTaskDisplay
 display_types['silent'] = SilentTaskDisplay
 display_types['dots'] = DotsTaskDisplay
-# display_types['tty'] = TTYTaskDisplay
+display_types['tty'] = TTYTaskDisplay
 
 
 class DotsProgressBar(_BaseProgressBar):

=== modified file 'bzrlib/tests/test_progress.py'
--- a/bzrlib/tests/test_progress.py	2007-11-20 02:04:08 +0000
+++ b/bzrlib/tests/test_progress.py	2007-11-20 08:53:59 +0000
@@ -526,16 +526,25 @@
 
     def test_construct(self):
         task = KnownLengthTask('message', 1)
-        output = StringIO()
+        output = _TTYStringIO()
         display = TTYTaskDisplay(task, output)
 
     def get_display(self):
         """Get a task, output and display to test with."""
         task = KnownLengthTask('message', 1)
-        output = StringIO()
+        output = _TTYStringIO()
         display = TTYTaskDisplay(task, output)
         return task, output, display
 
+    def test_usable(self):
+        """TTYTaskDisplay's are usable on TTY's with non-dumb terminals."""
+        self.assertTrue(TTYTaskDisplay.usable(_TTYStringIO()))
+        self.assertFalse(TTYTaskDisplay.usable(_NonTTYStringIO()))
+        self.assertFalse(TTYTaskDisplay.usable(StringIO()))
+        self.assertFalse(TTYTaskDisplay.usable(None))
+        os.environ['TERM'] = 'dumb'
+        self.assertFalse(TTYTaskDisplay.usable(_TTYStringIO()))
+
 
 class TestDisplayTypeSelection(TestCase):
 
@@ -556,3 +565,8 @@
         # the defaults.
         a_file = StringIO()
         self.assertEqual(DotsTaskDisplay, detect_display(a_file))
+
+    def test_via_tty_file(self):
+        # The same caveats apply here as for test_via_non_tty_file.
+        a_file = _TTYStringIO()
+        self.assertEqual(TTYTaskDisplay, detect_display(a_file))



More information about the bazaar-commits mailing list