1
# Copyright (C) 2005-2011 Canonical Ltd
1
# Copyright (C) 2005-2010 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
47
49
from bzrlib.lazy_import import lazy_import
48
50
lazy_import(globals(), """
49
53
from bzrlib import (
60
from bzrlib.symbol_versioning import (
57
67
_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)
129
103
class UIFactory(object):
130
104
"""UI abstraction.
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.
135
UI Factories are also context managers, for some syntactic sugar some users
138
109
:ivar suppressed_warnings: Identifiers for user warnings that should
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."
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"),
158
u"Stole dead lock %(lock_url)s %(other_holder_info)s."),
161
121
def __init__(self):
163
123
self.suppressed_warnings = set()
164
124
self._quiet = False
167
"""Context manager entry support.
169
Override in a concrete factory class if initialisation before use is
172
return self # This is bound to the 'as' clause in a with statement.
174
def __exit__(self, exc_type, exc_val, exc_tb):
175
"""Context manager exit support.
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.
181
return False # propogate exceptions.
183
126
def be_quiet(self, state):
184
127
"""Tell the UI to be more quiet, or not.
189
132
self._quiet = state
191
def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
192
"""Seek user confirmation for an action.
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
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.
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.
207
return self.get_boolean(prompt % prompt_kwargs)
209
def get_password(self, prompt=u'', **kwargs):
134
def get_password(self, prompt='', **kwargs):
210
135
"""Prompt the user for a password.
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
233
158
version of stdout, but in a GUI it might be appropriate to send it to a
234
159
window displaying the text.
236
:param encoding: Unicode encoding for output; if not specified
237
uses the configured 'output_encoding' if any; otherwise the
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.)
241
165
:param encoding_type: How to handle encoding errors:
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(
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)
307
227
template = self._user_warning_templates[warning_id]
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
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
321
241
"""Get a boolean question answered from the user.
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.
327
247
raise NotImplementedError(self.get_boolean)
330
250
"""Get an integer from the user.
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.
335
255
:return: A signed integer.
345
265
return NullProgressView()
347
def recommend_upgrade(self, current_format_name, basedir):
348
"""Recommend the user upgrade a control directory.
350
:param current_format_name: Description of the current format
351
:param basedir: Location of the control dir
353
self.show_user_warning('recommend_upgrade',
354
current_format_name=current_format_name, basedir=basedir)
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"
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,))
428
class NoninteractiveUIFactory(UIFactory):
429
"""Base class for UIs with no user."""
431
def confirm_action(self, prompt, confirmation_id, prompt_kwargs):
435
return '%s()' % (self.__class__.__name__, )
438
class SilentUIFactory(NoninteractiveUIFactory):
356
class SilentUIFactory(UIFactory):
439
357
"""A UI Factory which never prints anything.
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)
479
def confirm_action(self, prompt, confirmation_id, args):
480
return self.get_boolean(prompt % args)
482
397
def get_boolean(self, prompt):
483
398
return self.responses.pop(0)
485
400
def get_integer(self, prompt):
486
401
return self.responses.pop(0)
488
def get_password(self, prompt=u'', **kwargs):
403
def get_password(self, prompt='', **kwargs):
489
404
return self.responses.pop(0)
491
406
def get_username(self, prompt, **kwargs):