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"),
158
u"Stole dead lock %(lock_url)s %(other_holder_info)s."),
121
161
def __init__(self):
123
163
self.suppressed_warnings = set()
124
164
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.
126
183
def be_quiet(self, state):
127
184
"""Tell the UI to be more quiet, or not.
132
189
self._quiet = state
134
def get_password(self, prompt='', **kwargs):
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):
135
210
"""Prompt the user for a password.
137
:param prompt: The prompt to present the user
212
:param prompt: The prompt to present the user (must be unicode)
138
213
:param kwargs: Arguments which will be expanded into the prompt.
139
214
This lets front ends display different things if
158
233
version of stdout, but in a GUI it might be appropriate to send it to a
159
234
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.
236
:param encoding: Unicode encoding for output; if not specified
237
uses the configured 'output_encoding' if any; otherwise the
163
239
(See get_terminal_encoding.)
165
241
:param encoding_type: How to handle encoding errors:
168
244
# XXX: is the caller supposed to close the resulting object?
169
245
if encoding is None:
170
encoding = osutils.get_terminal_encoding()
246
from bzrlib import config
247
encoding = config.GlobalConfig().get_user_option(
250
encoding = osutils.get_terminal_encoding(trace=True)
171
251
if encoding_type is None:
172
252
encoding_type = 'replace'
173
253
out_stream = self._make_output_stream_explicit(encoding, encoding_type)
227
307
template = self._user_warning_templates[warning_id]
229
fail = "failed to format warning %r, %r" % (warning_id, message_args)
230
warnings.warn(fail) # so tests will fail etc
309
fail = "bzr warning: %r, %r" % (warning_id, message_args)
310
warnings.warn("no template for warning: " + fail) # so tests will fail etc
233
313
return template % message_args
234
314
except ValueError, e:
235
fail = "failed to format warning %r, %r: %s" % (
315
fail = "bzr unprintable warning: %r, %r, %s" % (
236
316
warning_id, message_args, e)
237
317
warnings.warn(fail) # so tests will fail etc
241
321
"""Get a boolean question answered from the user.
243
323
:param prompt: a message to prompt the user with. Should be a single
244
line without terminating \n.
324
line without terminating \\n.
245
325
:return: True or False for y/yes or n/no.
247
327
raise NotImplementedError(self.get_boolean)
250
330
"""Get an integer from the user.
252
332
:param prompt: a message to prompt the user with. Could be a multi-line
253
prompt but without a terminating \n.
333
prompt but without a terminating \\n.
255
335
:return: A signed integer.
265
345
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"
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)
283
356
def report_transport_activity(self, transport, byte_count, direction):
284
357
"""Called by transports as they do IO.
352
425
"without an upgrade path.\n" % (inter.target._format,))
356
class SilentUIFactory(UIFactory):
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):
357
439
"""A UI Factory which never prints anything.
359
441
This is the default UI, if another one is never registered by a program
394
476
def __repr__(self):
395
477
return "%s(%r)" % (self.__class__.__name__, self.responses)
479
def confirm_action(self, prompt, confirmation_id, args):
480
return self.get_boolean(prompt % args)
397
482
def get_boolean(self, prompt):
398
483
return self.responses.pop(0)
400
485
def get_integer(self, prompt):
401
486
return self.responses.pop(0)
403
def get_password(self, prompt='', **kwargs):
488
def get_password(self, prompt=u'', **kwargs):
404
489
return self.responses.pop(0)
406
491
def get_username(self, prompt, **kwargs):