/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/ui/text.py

  • Committer: John Arbash Meinel
  • Date: 2009-12-22 16:28:47 UTC
  • mto: This revision was merged to the branch mainline in revision 4922.
  • Revision ID: john@arbash-meinel.com-20091222162847-tvnsc69to4l4uf5r
Implement a permute_for_extension helper.

Use it for all of the 'simple' extension permutations.
It basically permutes all tests in the current module, by setting TestCase.module.
Which works well for most of our extension tests. Some had more advanced
handling of permutations (extra permutations, custom vars, etc.)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
32
32
    progress,
33
33
    osutils,
34
34
    symbol_versioning,
35
 
    trace,
36
35
    )
37
36
 
38
37
""")
39
38
 
40
 
from bzrlib.osutils import watch_sigwinch
41
 
 
42
39
from bzrlib.ui import (
43
40
    UIFactory,
44
41
    NullProgressView,
62
59
        self.stderr = stderr
63
60
        # paints progress, network activity, etc
64
61
        self._progress_view = self.make_progress_view()
65
 
        # hook up the signals to watch for terminal size changes
66
 
        watch_sigwinch()
67
 
 
68
 
    def be_quiet(self, state):
69
 
        if state and not self._quiet:
70
 
            self.clear_term()
71
 
        UIFactory.be_quiet(self, state)
72
 
        self._progress_view = self.make_progress_view()
73
 
 
 
62
        
74
63
    def clear_term(self):
75
64
        """Prepare the terminal for output.
76
65
 
156
145
    def make_progress_view(self):
157
146
        """Construct and return a new ProgressView subclass for this UI.
158
147
        """
159
 
        # with --quiet, never any progress view
160
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/320035>.  Otherwise if the
161
 
        # user specifically requests either text or no progress bars, always
162
 
        # do that.  otherwise, guess based on $TERM and tty presence.
163
 
        if self.is_quiet():
164
 
            return NullProgressView()
165
 
        elif os.environ.get('BZR_PROGRESS_BAR') == 'text':
 
148
        # if the user specifically requests either text or no progress bars,
 
149
        # always do that.  otherwise, guess based on $TERM and tty presence.
 
150
        if os.environ.get('BZR_PROGRESS_BAR') == 'text':
166
151
            return TextProgressView(self.stderr)
167
152
        elif os.environ.get('BZR_PROGRESS_BAR') == 'none':
168
153
            return NullProgressView()
218
203
        self._progress_view.show_transport_activity(transport,
219
204
            direction, byte_count)
220
205
 
221
 
    def log_transport_activity(self, display=False):
222
 
        """See UIFactory.log_transport_activity()"""
223
 
        log = getattr(self._progress_view, 'log_transport_activity', None)
224
 
        if log is not None:
225
 
            log(display=display)
226
 
 
227
206
    def show_error(self, msg):
228
207
        self.clear_term()
229
208
        self.stderr.write("bzr: error: %s\n" % msg)
242
221
            warnings.warn("%r updated but no tasks are active" %
243
222
                (task,))
244
223
        elif task != self._task_stack[-1]:
245
 
            # We used to check it was the top task, but it's hard to always
246
 
            # get this right and it's not necessarily useful: any actual
247
 
            # problems will be evident in use
248
 
            #warnings.warn("%r is not the top progress task %r" %
249
 
            #     (task, self._task_stack[-1]))
250
 
            pass
 
224
            warnings.warn("%r is not the top progress task %r" %
 
225
                (task, self._task_stack[-1]))
251
226
        self._progress_view.show_progress(task)
252
227
 
253
228
    def _progress_all_finished(self):
254
229
        self._progress_view.clear()
255
230
 
256
 
    def show_user_warning(self, warning_id, **message_args):
257
 
        """Show a text message to the user.
258
 
 
259
 
        Explicitly not for warnings about bzr apis, deprecations or internals.
260
 
        """
261
 
        # eventually trace.warning should migrate here, to avoid logging and
262
 
        # be easier to test; that has a lot of test fallout so for now just
263
 
        # new code can call this
264
 
        if warning_id not in self.suppressed_warnings:
265
 
            self.stderr.write(self.format_user_warning(warning_id, message_args) +
266
 
                '\n')
267
 
 
268
231
 
269
232
class TextProgressView(object):
270
233
    """Display of progress bar and other information on a tty.
294
257
        self._last_task = None
295
258
        self._total_byte_count = 0
296
259
        self._bytes_since_update = 0
297
 
        self._bytes_by_direction = {'unknown': 0, 'read': 0, 'write': 0}
298
 
        self._first_byte_time = None
299
260
        self._fraction = 0
300
261
        # force the progress bar to be off, as at the moment it doesn't 
301
262
        # correspond reliably to overall command progress
340
301
            markers = int(round(float(cols) * completion_fraction)) - 1
341
302
            bar_str = '[' + ('#' * markers + spin_str).ljust(cols) + '] '
342
303
            return bar_str
343
 
        elif (self._last_task is None) or self._last_task.show_spinner:
 
304
        elif self._last_task.show_spinner:
344
305
            # The last task wanted just a spinner, no bar
345
306
            spin_str =  r'/-\|'[self._spin_pos % 4]
346
307
            self._spin_pos += 1
408
369
        This may update a progress bar, spinner, or similar display.
409
370
        By default it does nothing.
410
371
        """
411
 
        # XXX: there should be a transport activity model, and that too should
412
 
        #      be seen by the progress view, rather than being poked in here.
 
372
        # XXX: Probably there should be a transport activity model, and that
 
373
        # too should be seen by the progress view, rather than being poked in
 
374
        # here.
 
375
        if not self._have_output:
 
376
            # As a workaround for <https://launchpad.net/bugs/321935> we only
 
377
            # show transport activity when there's already a progress bar
 
378
            # shown, which time the application code is expected to know to
 
379
            # clear off the progress bar when it's going to send some other
 
380
            # output.  Eventually it would be nice to have that automatically
 
381
            # synchronized.
 
382
            return
413
383
        self._total_byte_count += byte_count
414
384
        self._bytes_since_update += byte_count
415
 
        if self._first_byte_time is None:
416
 
            # Note that this isn't great, as technically it should be the time
417
 
            # when the bytes started transferring, not when they completed.
418
 
            # However, we usually start with a small request anyway.
419
 
            self._first_byte_time = time.time()
420
 
        if direction in self._bytes_by_direction:
421
 
            self._bytes_by_direction[direction] += byte_count
422
 
        else:
423
 
            self._bytes_by_direction['unknown'] += byte_count
424
 
        if 'no_activity' in debug.debug_flags:
425
 
            # Can be used as a workaround if
426
 
            # <https://launchpad.net/bugs/321935> reappears and transport
427
 
            # activity is cluttering other output.  However, thanks to
428
 
            # TextUIOutputStream this shouldn't be a problem any more.
429
 
            return
430
385
        now = time.time()
431
386
        if self._total_byte_count < 2000:
432
387
            # a little resistance at first, so it doesn't stay stuck at 0
437
392
        elif now >= (self._transport_update_time + 0.5):
438
393
            # guard against clock stepping backwards, and don't update too
439
394
            # often
440
 
            rate = (self._bytes_since_update
441
 
                    / (now - self._transport_update_time))
442
 
            # using base-10 units (see HACKING.txt).
443
 
            msg = ("%6dkB %5dkB/s" %
444
 
                    (self._total_byte_count / 1000, int(rate) / 1000,))
 
395
            rate = self._bytes_since_update / (now - self._transport_update_time)
 
396
            msg = ("%6dKB %5dKB/s" %
 
397
                    (self._total_byte_count>>10, int(rate)>>10,))
445
398
            self._transport_update_time = now
446
399
            self._last_repaint = now
447
400
            self._bytes_since_update = 0
448
401
            self._last_transport_msg = msg
449
402
            self._repaint()
450
403
 
451
 
    def _format_bytes_by_direction(self):
452
 
        if self._first_byte_time is None:
453
 
            bps = 0.0
454
 
        else:
455
 
            transfer_time = time.time() - self._first_byte_time
456
 
            if transfer_time < 0.001:
457
 
                transfer_time = 0.001
458
 
            bps = self._total_byte_count / transfer_time
459
 
 
460
 
        # using base-10 units (see HACKING.txt).
461
 
        msg = ('Transferred: %.0fkB'
462
 
               ' (%.1fkB/s r:%.0fkB w:%.0fkB'
463
 
               % (self._total_byte_count / 1000.,
464
 
                  bps / 1000.,
465
 
                  self._bytes_by_direction['read'] / 1000.,
466
 
                  self._bytes_by_direction['write'] / 1000.,
467
 
                 ))
468
 
        if self._bytes_by_direction['unknown'] > 0:
469
 
            msg += ' u:%.0fkB)' % (
470
 
                self._bytes_by_direction['unknown'] / 1000.
471
 
                )
472
 
        else:
473
 
            msg += ')'
474
 
        return msg
475
 
 
476
 
    def log_transport_activity(self, display=False):
477
 
        msg = self._format_bytes_by_direction()
478
 
        trace.mutter(msg)
479
 
        if display and self._total_byte_count > 0:
480
 
            self.clear()
481
 
            self._term_file.write(msg + '\n')
482
 
 
483
404
 
484
405
class TextUIOutputStream(object):
485
406
    """Decorates an output stream so that the terminal is cleared before writing.