1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-14 17:46:17 +01:00

New get_user_input() function for consistent handling of user input.

The available answers are provided in a dictionary and the prompt is
generated from them.
Also, answers are higlighted if the terminal supports it.
This commit is contained in:
Daniel Mach 2024-02-08 09:52:12 +01:00
parent 9070d03cb6
commit 52d014d24d
2 changed files with 52 additions and 0 deletions

View File

@ -1,4 +1,5 @@
from .key_value_table import KeyValueTable
from .input import get_user_input
from .tty import colorize
from .widechar import wc_ljust
from .widechar import wc_width

51
osc/output/input.py Normal file
View File

@ -0,0 +1,51 @@
import sys
import textwrap
from typing import Dict
from typing import Optional
from .. import oscerr
from .tty import colorize
def get_user_input(question: str, answers: Dict[str, str], default_answer: Optional[str] = None) -> str:
"""
Ask user a question and wait for reply.
:param question: The question. The text gets automatically dedented and stripped.
:param answers: A dictionary with answers. Keys are the expected replies and values are their descriptions.
:param default_answer: The default answer. Must be ``None`` or match an ``answers`` entry.
"""
if default_answer and default_answer not in answers:
raise ValueError(f"Default answer doesn't match any answer: {default_answer}")
question = textwrap.dedent(question)
question = question.strip()
prompt = []
for key, value in answers.items():
value = f"{colorize(key, 'bold')}){value}"
prompt.append(value)
prompt_str = " / ".join(prompt)
if default_answer:
prompt_str += f" (default={colorize(default_answer, 'bold')})"
prompt_str += ": "
print(question, file=sys.stderr)
while True:
try:
reply = input(prompt_str)
except EOFError:
# interpret ctrl-d as user abort
raise oscerr.UserAbort() # pylint: disable=raise-missing-from
if reply in answers:
return reply
if reply.strip() in answers:
return reply.strip()
if not reply.strip():
return default_answer
print(f"Invalid reply: {colorize(reply, 'bold,red')}", file=sys.stderr)