182
191
class CLIUIFactory(UIFactory):
183
"""Common behaviour for command line UI factories.
185
This is suitable for dumb terminals that can't repaint existing text."""
192
"""Deprecated in favor of TextUIFactory."""
194
@deprecated_method(deprecated_in((1, 17, 0)))
187
195
def __init__(self, stdin=None, stdout=None, stderr=None):
188
196
UIFactory.__init__(self)
189
197
self.stdin = stdin or sys.stdin
190
198
self.stdout = stdout or sys.stdout
191
199
self.stderr = stderr or sys.stderr
193
def get_boolean(self, prompt):
194
# FIXME: make a regexp and handle case variations as well.
196
self.prompt(prompt + "? [y/n]: ")
197
line = self.stdin.readline()
198
if line in ('y\n', 'yes\n'):
200
if line in ('n\n', 'no\n'):
203
def get_non_echoed_password(self):
204
isatty = getattr(self.stdin, 'isatty', None)
205
if isatty is not None and isatty():
206
# getpass() ensure the password is not echoed and other
207
# cross-platform niceties
208
password = getpass.getpass('')
210
# echo doesn't make sense without a terminal
211
password = self.stdin.readline()
214
elif password[-1] == '\n':
215
password = password[:-1]
218
def get_password(self, prompt='', **kwargs):
219
"""Prompt the user for a password.
221
:param prompt: The prompt to present the user
222
:param kwargs: Arguments which will be expanded into the prompt.
223
This lets front ends display different things if
225
:return: The password string, return None if the user
226
canceled the request.
229
self.prompt(prompt, **kwargs)
230
# There's currently no way to say 'i decline to enter a password'
231
# as opposed to 'my password is empty' -- does it matter?
232
return self.get_non_echoed_password()
234
def get_username(self, prompt, **kwargs):
235
"""Prompt the user for a username.
237
:param prompt: The prompt to present the user
238
:param kwargs: Arguments which will be expanded into the prompt.
239
This lets front ends display different things if
241
:return: The username string, return None if the user
242
canceled the request.
245
self.prompt(prompt, **kwargs)
246
username = self.stdin.readline()
249
elif username[-1] == '\n':
250
username = username[:-1]
253
def prompt(self, prompt, **kwargs):
254
"""Emit prompt on the CLI.
256
:param kwargs: Dictionary of arguments to insert into the prompt,
257
to allow UIs to reformat the prompt.
260
# See <https://launchpad.net/bugs/365891>
261
prompt = prompt % kwargs
262
prompt = prompt.encode(osutils.get_terminal_encoding(), 'replace')
264
self.stderr.write(prompt)
267
"""Write an already-formatted message."""
268
self.stdout.write(msg + '\n')
271
class SilentUIFactory(CLIUIFactory):
202
class SilentUIFactory(UIFactory):
272
203
"""A UI Factory which never prints anything.
274
205
This is the default UI, if another one is never registered.
277
208
def __init__(self):
278
CLIUIFactory.__init__(self)
209
UIFactory.__init__(self)
280
211
def get_password(self, prompt='', **kwargs):
300
231
ui_factory = SilentUIFactory()
301
"""IMPORTANT: never import this symbol directly. ONLY ever access it as
232
# IMPORTANT: never import this symbol directly. ONLY ever access it as
233
# ui.ui_factory, so that you refer to the current value.
305
236
def make_ui_for_terminal(stdin, stdout, stderr):
306
237
"""Construct and return a suitable UIFactory for a text mode program.
308
If stdout is a smart terminal, this gets a smart UIFactory with
309
progress indicators, etc. If it's a dumb terminal, just plain text output.
312
isatty = getattr(stdin, 'isatty', None)
317
# The following case also handles Win32 - on that platform $TERM is
318
# typically never set, so the case None is treated as a smart terminal,
319
# not dumb. <https://bugs.launchpad.net/bugs/334808> win32 files do have
320
# isatty methods that return true.
321
elif os.environ.get('TERM') in ('dumb', ''):
322
# e.g. emacs compile window
324
# User may know better, otherwise default to TextUIFactory
325
if (os.environ.get('BZR_USE_TEXT_UI', None) is not None
327
from bzrlib.ui.text import TextUIFactory
329
return cls(stdin=stdin, stdout=stdout, stderr=stderr)
239
# this is now always TextUIFactory, which in turn decides whether it
240
# should display progress bars etc
241
from bzrlib.ui.text import TextUIFactory
242
return TextUIFactory(stdin, stdout, stderr)
332
245
class NullProgressView(object):