1
# Copyright (C) 2005-2010 Canonical Ltd
1
# Copyright (C) 2005-2011 Canonical Ltd
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
49
47
from bzrlib.lazy_import import lazy_import
50
48
lazy_import(globals(), """
53
49
from bzrlib import (
60
from bzrlib.symbol_versioning import (
67
57
_valid_boolean_strings = dict(yes=True, no=False,
93
class ConfirmationUserInterfacePolicy(object):
94
"""Wrapper for a UIFactory that allows or denies all confirmed actions."""
96
def __init__(self, wrapped_ui, default_answer, specific_answers):
97
"""Generate a proxy UI that does no confirmations.
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
103
:param specific_answers: Map from confirmation_id to bool answer.
105
self.wrapped_ui = wrapped_ui
106
self.default_answer = default_answer
107
self.specific_answers = specific_answers
109
def __getattr__(self, name):
110
return getattr(self.wrapped_ui, name)
113
return '%s(%r, %r, %r)' % (
114
self.__class__.__name__,
117
self.specific_answers)
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
125
return self.wrapped_ui.confirm_action(
126
prompt, confirmation_id, prompt_kwargs)
103
129
class UIFactory(object):
104
130
"""UI abstraction.
106
132
This tells the library how to display things to the user. Through this
107
133
layer different applications can choose the style of UI.
135
UI Factories are also context managers, for some syntactic sugar some users
109
138
:ivar suppressed_warnings: Identifiers for user warnings that should
115
144
"%(from_format)s to %(to_format)s.\n"
116
145
"This may take some time. Upgrade the repositories to the "
117
146
"same format for better performance."
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"),
121
159
def __init__(self):
123
161
self.suppressed_warnings = set()
124
162
self._quiet = False
165
"""Context manager entry support.
167
Override in a concrete factory class if initialisation before use is
170
return self # This is bound to the 'as' clause in a with statement.
172
def __exit__(self, exc_type, exc_val, exc_tb):
173
"""Context manager exit support.
175
Override in a concrete factory class if more cleanup than a simple
176
self.clear_term() is needed when the UIFactory is finished with.
179
return False # propogate exceptions.
126
181
def be_quiet(self, state):
127
182
"""Tell the UI to be more quiet, or not.
132
187
self._quiet = state
189
def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
190
"""Seek user confirmation for an action.
192
If the UI is noninteractive, or the user does not want to be asked
193
about this action, True is returned, indicating bzr should just
196
The confirmation id allows the user to configure certain actions to
197
always be confirmed or always denied, and for UIs to specialize the
198
display of particular confirmations.
200
:param prompt: Suggested text to display to the user.
201
:param prompt_kwargs: A dictionary of arguments that can be
202
string-interpolated into the prompt.
203
:param confirmation_id: Unique string identifier for the confirmation.
205
return self.get_boolean(prompt % prompt_kwargs)
134
207
def get_password(self, prompt='', **kwargs):
135
208
"""Prompt the user for a password.
158
231
version of stdout, but in a GUI it might be appropriate to send it to a
159
232
window displaying the text.
161
:param encoding: Unicode encoding for output; default is the
162
terminal encoding, which may be different from the user encoding.
234
:param encoding: Unicode encoding for output; if not specified
235
uses the configured 'output_encoding' if any; otherwise the
163
237
(See get_terminal_encoding.)
165
239
:param encoding_type: How to handle encoding errors:
168
242
# XXX: is the caller supposed to close the resulting object?
169
243
if encoding is None:
170
encoding = osutils.get_terminal_encoding()
244
from bzrlib import config
245
encoding = config.GlobalConfig().get_user_option(
248
encoding = osutils.get_terminal_encoding(trace=True)
171
249
if encoding_type is None:
172
250
encoding_type = 'replace'
173
251
out_stream = self._make_output_stream_explicit(encoding, encoding_type)
241
319
"""Get a boolean question answered from the user.
243
321
:param prompt: a message to prompt the user with. Should be a single
244
line without terminating \n.
322
line without terminating \\n.
245
323
:return: True or False for y/yes or n/no.
247
325
raise NotImplementedError(self.get_boolean)
250
328
"""Get an integer from the user.
252
330
:param prompt: a message to prompt the user with. Could be a multi-line
253
prompt but without a terminating \n.
331
prompt but without a terminating \\n.
255
333
:return: A signed integer.
265
343
return NullProgressView()
267
def recommend_upgrade(self,
270
# XXX: this should perhaps be in the TextUIFactory and the default can do
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"
345
def recommend_upgrade(self, current_format_name, basedir):
346
"""Recommend the user upgrade a control directory.
348
:param current_format_name: Description of the current format
349
:param basedir: Location of the control dir
351
self.show_user_warning('recommend_upgrade',
352
current_format_name=current_format_name, basedir=basedir)
283
354
def report_transport_activity(self, transport, byte_count, direction):
284
355
"""Called by transports as they do IO.
352
423
"without an upgrade path.\n" % (inter.target._format,))
356
class SilentUIFactory(UIFactory):
426
class NoninteractiveUIFactory(UIFactory):
427
"""Base class for UIs with no user."""
429
def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
433
return '%s()' % (self.__class__.__name__, )
436
class SilentUIFactory(NoninteractiveUIFactory):
357
437
"""A UI Factory which never prints anything.
359
439
This is the default UI, if another one is never registered by a program
394
474
def __repr__(self):
395
475
return "%s(%r)" % (self.__class__.__name__, self.responses)
477
def confirm_action(self, prompt, confirmation_id, args):
478
return self.get_boolean(prompt % args)
397
480
def get_boolean(self, prompt):
398
481
return self.responses.pop(0)