~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/ui/__init__.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-04-06 06:59:03 UTC
  • mfrom: (5051.5.1 subunit)
  • Revision ID: pqm@pqm.ubuntu.com-20100406065903-y9dxgwmog1pmw7dz
Use subunit when running tests in PQM.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2011 Canonical Ltd
 
1
# Copyright (C) 2005-2010 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
42
42
"""
43
43
 
44
44
 
 
45
import os
 
46
import sys
45
47
import warnings
46
48
 
47
49
from bzrlib.lazy_import import lazy_import
48
50
lazy_import(globals(), """
 
51
import getpass
 
52
 
49
53
from bzrlib import (
 
54
    errors,
50
55
    osutils,
51
56
    progress,
52
57
    trace,
53
58
    )
54
59
""")
 
60
from bzrlib.symbol_versioning import (
 
61
    deprecated_function,
 
62
    deprecated_in,
 
63
    deprecated_method,
 
64
    )
55
65
 
56
66
 
57
67
_valid_boolean_strings = dict(yes=True, no=False,
90
100
    return val
91
101
 
92
102
 
93
 
class ConfirmationUserInterfacePolicy(object):
94
 
    """Wrapper for a UIFactory that allows or denies all confirmed actions."""
95
 
 
96
 
    def __init__(self, wrapped_ui, default_answer, specific_answers):
97
 
        """Generate a proxy UI that does no confirmations.
98
 
 
99
 
        :param wrapped_ui: Underlying UIFactory.
100
 
        :param default_answer: Bool for whether requests for
101
 
            confirmation from the user should be noninteractively accepted or
102
 
            denied.
103
 
        :param specific_answers: Map from confirmation_id to bool answer.
104
 
        """
105
 
        self.wrapped_ui = wrapped_ui
106
 
        self.default_answer = default_answer
107
 
        self.specific_answers = specific_answers
108
 
 
109
 
    def __getattr__(self, name):
110
 
        return getattr(self.wrapped_ui, name)
111
 
 
112
 
    def __repr__(self):
113
 
        return '%s(%r, %r, %r)' % (
114
 
            self.__class__.__name__,
115
 
            self.wrapped_ui,
116
 
            self.default_answer, 
117
 
            self.specific_answers)
118
 
 
119
 
    def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
120
 
        if confirmation_id in self.specific_answers:
121
 
            return self.specific_answers[confirmation_id]
122
 
        elif self.default_answer is not None:
123
 
            return self.default_answer
124
 
        else:
125
 
            return self.wrapped_ui.confirm_action(
126
 
                prompt, confirmation_id, prompt_kwargs)
127
 
 
128
 
 
129
103
class UIFactory(object):
130
104
    """UI abstraction.
131
105
 
132
106
    This tells the library how to display things to the user.  Through this
133
107
    layer different applications can choose the style of UI.
134
108
 
135
 
    UI Factories are also context managers, for some syntactic sugar some users
136
 
    need.
137
 
 
138
109
    :ivar suppressed_warnings: Identifiers for user warnings that should 
139
110
        no be emitted.
140
111
    """
144
115
            "%(from_format)s to %(to_format)s.\n"
145
116
            "This may take some time. Upgrade the repositories to the "
146
117
            "same format for better performance."
147
 
            ),
148
 
        deprecated_command=(
149
 
            "The command 'bzr %(deprecated_name)s' "
150
 
            "has been deprecated in bzr %(deprecated_in_version)s. "
151
 
            "Please use 'bzr %(recommended_name)s' instead."),
152
 
        recommend_upgrade=("%(current_format_name)s is deprecated "
153
 
            "and a better format is available.\n"
154
 
            "It is recommended that you upgrade by "
155
 
            "running the command\n"
156
 
            "  bzr upgrade %(basedir)s"),
157
 
        locks_steal_dead=(
158
 
            u"Stole dead lock %(lock_url)s %(other_holder_info)s."),
 
118
            )
159
119
        )
160
120
 
161
121
    def __init__(self):
163
123
        self.suppressed_warnings = set()
164
124
        self._quiet = False
165
125
 
166
 
    def __enter__(self):
167
 
        """Context manager entry support.
168
 
 
169
 
        Override in a concrete factory class if initialisation before use is
170
 
        needed.
171
 
        """
172
 
        return self # This is bound to the 'as' clause in a with statement.
173
 
 
174
 
    def __exit__(self, exc_type, exc_val, exc_tb):
175
 
        """Context manager exit support.
176
 
 
177
 
        Override in a concrete factory class if more cleanup than a simple
178
 
        self.clear_term() is needed when the UIFactory is finished with.
179
 
        """
180
 
        self.clear_term()
181
 
        return False # propogate exceptions.
182
 
 
183
126
    def be_quiet(self, state):
184
127
        """Tell the UI to be more quiet, or not.
185
128
 
188
131
        """
189
132
        self._quiet = state
190
133
 
191
 
    def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
192
 
        """Seek user confirmation for an action.
193
 
 
194
 
        If the UI is noninteractive, or the user does not want to be asked
195
 
        about this action, True is returned, indicating bzr should just
196
 
        proceed.
197
 
 
198
 
        The confirmation id allows the user to configure certain actions to
199
 
        always be confirmed or always denied, and for UIs to specialize the
200
 
        display of particular confirmations.
201
 
 
202
 
        :param prompt: Suggested text to display to the user.
203
 
        :param prompt_kwargs: A dictionary of arguments that can be
204
 
            string-interpolated into the prompt.
205
 
        :param confirmation_id: Unique string identifier for the confirmation.
206
 
        """
207
 
        return self.get_boolean(prompt % prompt_kwargs)
208
 
 
209
 
    def get_password(self, prompt=u'', **kwargs):
 
134
    def get_password(self, prompt='', **kwargs):
210
135
        """Prompt the user for a password.
211
136
 
212
 
        :param prompt: The prompt to present the user (must be unicode)
 
137
        :param prompt: The prompt to present the user
213
138
        :param kwargs: Arguments which will be expanded into the prompt.
214
139
                       This lets front ends display different things if
215
140
                       they so choose.
233
158
        version of stdout, but in a GUI it might be appropriate to send it to a 
234
159
        window displaying the text.
235
160
     
236
 
        :param encoding: Unicode encoding for output; if not specified 
237
 
            uses the configured 'output_encoding' if any; otherwise the 
238
 
            terminal encoding. 
 
161
        :param encoding: Unicode encoding for output; default is the 
 
162
            terminal encoding, which may be different from the user encoding.
239
163
            (See get_terminal_encoding.)
240
164
 
241
165
        :param encoding_type: How to handle encoding errors:
243
167
        """
244
168
        # XXX: is the caller supposed to close the resulting object?
245
169
        if encoding is None:
246
 
            from bzrlib import config
247
 
            encoding = config.GlobalConfig().get_user_option(
248
 
                'output_encoding')
249
 
        if encoding is None:
250
 
            encoding = osutils.get_terminal_encoding(trace=True)
 
170
            encoding = osutils.get_terminal_encoding()
251
171
        if encoding_type is None:
252
172
            encoding_type = 'replace'
253
173
        out_stream = self._make_output_stream_explicit(encoding, encoding_type)
306
226
        try:
307
227
            template = self._user_warning_templates[warning_id]
308
228
        except KeyError:
309
 
            fail = "bzr warning: %r, %r" % (warning_id, message_args)
310
 
            warnings.warn("no template for warning: " + fail)   # so tests will fail etc
 
229
            fail = "failed to format warning %r, %r" % (warning_id, message_args)
 
230
            warnings.warn(fail)   # so tests will fail etc
311
231
            return fail
312
232
        try:
313
233
            return template % message_args
314
234
        except ValueError, e:
315
 
            fail = "bzr unprintable warning: %r, %r, %s" % (
 
235
            fail = "failed to format warning %r, %r: %s" % (
316
236
                warning_id, message_args, e)
317
237
            warnings.warn(fail)   # so tests will fail etc
318
238
            return fail
321
241
        """Get a boolean question answered from the user.
322
242
 
323
243
        :param prompt: a message to prompt the user with. Should be a single
324
 
            line without terminating \\n.
 
244
        line without terminating \n.
325
245
        :return: True or False for y/yes or n/no.
326
246
        """
327
247
        raise NotImplementedError(self.get_boolean)
330
250
        """Get an integer from the user.
331
251
 
332
252
        :param prompt: a message to prompt the user with. Could be a multi-line
333
 
            prompt but without a terminating \\n.
 
253
            prompt but without a terminating \n.
334
254
 
335
255
        :return: A signed integer.
336
256
        """
344
264
        """
345
265
        return NullProgressView()
346
266
 
347
 
    def recommend_upgrade(self, current_format_name, basedir):
348
 
        """Recommend the user upgrade a control directory.
349
 
 
350
 
        :param current_format_name: Description of the current format
351
 
        :param basedir: Location of the control dir
352
 
        """
353
 
        self.show_user_warning('recommend_upgrade',
354
 
            current_format_name=current_format_name, basedir=basedir)
 
267
    def recommend_upgrade(self,
 
268
        current_format_name,
 
269
        basedir):
 
270
        # XXX: this should perhaps be in the TextUIFactory and the default can do
 
271
        # nothing
 
272
        #
 
273
        # XXX: Change to show_user_warning - that will accomplish the previous
 
274
        # xxx. -- mbp 2010-02-25
 
275
        trace.warning("%s is deprecated "
 
276
            "and a better format is available.\n"
 
277
            "It is recommended that you upgrade by "
 
278
            "running the command\n"
 
279
            "  bzr upgrade %s",
 
280
            current_format_name,
 
281
            basedir)
355
282
 
356
283
    def report_transport_activity(self, transport, byte_count, direction):
357
284
        """Called by transports as they do IO.
425
352
                "without an upgrade path.\n" % (inter.target._format,))
426
353
 
427
354
 
428
 
class NoninteractiveUIFactory(UIFactory):
429
 
    """Base class for UIs with no user."""
430
 
 
431
 
    def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
432
 
        return True
433
 
 
434
 
    def __repr__(self):
435
 
        return '%s()' % (self.__class__.__name__, )
436
 
 
437
 
 
438
 
class SilentUIFactory(NoninteractiveUIFactory):
 
355
 
 
356
class SilentUIFactory(UIFactory):
439
357
    """A UI Factory which never prints anything.
440
358
 
441
359
    This is the default UI, if another one is never registered by a program
476
394
    def __repr__(self):
477
395
        return "%s(%r)" % (self.__class__.__name__, self.responses)
478
396
 
479
 
    def confirm_action(self, prompt, confirmation_id, args):
480
 
        return self.get_boolean(prompt % args)
481
 
 
482
397
    def get_boolean(self, prompt):
483
398
        return self.responses.pop(0)
484
399
 
485
400
    def get_integer(self, prompt):
486
401
        return self.responses.pop(0)
487
402
 
488
 
    def get_password(self, prompt=u'', **kwargs):
 
403
    def get_password(self, prompt='', **kwargs):
489
404
        return self.responses.pop(0)
490
405
 
491
406
    def get_username(self, prompt, **kwargs):