Support suppress meta option on Prompt to suppress user input.

- Resolves Issue #621
This commit is contained in:
BJ Dierkes 2022-08-17 20:03:10 -05:00
parent 7415de149a
commit c4db3a3578
3 changed files with 31 additions and 4 deletions

View File

@ -18,7 +18,8 @@ Bugs:
Features:
- None
- `[utils.shell]` Support `suppress` meta option on `Prompt` to suppress user input.
- [Issue #621](https://github.com/datafolklabs/cement/issues/621)
Refactoring:

View File

@ -1,6 +1,8 @@
"""Common Shell Utilities."""
import os
import builtins
from getpass import getpass
from subprocess import Popen, PIPE
from multiprocessing import Process
from threading import Thread
@ -388,9 +390,13 @@ class Prompt(MetaMixin):
max_attempts = 10
#: Raise an exception when max_attempts is hit? If not, Prompt
#: passes the input through as `None`.
#: passes the input through as ``None``.
max_attempts_exception = True
#: Suppress user input (use ``getpass.getpass`` instead of
#: ``builtins.input``. Default: ``False``.
suppress = False
def __init__(self, text=None, *args, **kw):
if text is not None:
kw['text'] = text
@ -400,6 +406,18 @@ class Prompt(MetaMixin):
if self._meta.auto:
self.prompt()
def _get_suppressed_input(self, text):
return getpass(text) # pragma: nocover
def _get_unsuppressed_input(self, text):
return builtins.input(text) # pragma: nocover
def _get_input(self, text):
if self._meta.suppress is True:
return self._get_suppressed_input(text) # pragma: nocover
else:
return self._get_unsuppressed_input(text) # pragma: nocover
def _prompt(self):
if self._meta.clear:
os.system(self._meta.clear_command)
@ -421,7 +439,8 @@ class Prompt(MetaMixin):
else:
text = self._meta.text
self.input = input("%s " % text)
self.input = self._get_input("%s " % text)
# self.input = input("%s " % text)
if self.input == '' and self._meta.default is not None:
self.input = self._meta.default
elif self.input == '':

View File

@ -6,7 +6,8 @@ from pytest import raises
from cement.utils import shell
from cement.core.exc import FrameworkError
INPUT = 'builtins.input'
# INPUT = 'builtins.input'
INPUT = 'cement.utils.shell.Prompt._get_input'
def add(a, b):
@ -209,3 +210,9 @@ def test_prompt_case_sensitive():
max_attempts_exception=False,
)
assert p.input is None
def test_prompt_suppress_user_input():
with mock.patch(INPUT, return_value='UBER_SECURE_PASSWORD'):
p = shell.Prompt("Input password", suppress=True)
assert p.input == 'UBER_SECURE_PASSWORD'