From 47fb954133f26dcc85304cbfbac31db8a8a8e02a Mon Sep 17 00:00:00 2001 From: jakub-nt <175944085+jakub-nt@users.noreply.github.com> Date: Thu, 17 Jul 2025 16:08:54 +0200 Subject: [PATCH] Added a helper function for yes-no question user prompts Signed-off-by: jakub-nt <175944085+jakub-nt@users.noreply.github.com> --- cfbs/cfbs_config.py | 41 ++++++++++++++-------------------------- cfbs/commands.py | 46 +++++++++++++++------------------------------ cfbs/git_magic.py | 10 ++-------- cfbs/prompts.py | 15 ++++++++++++++- cfbs/updates.py | 16 ++++++---------- 5 files changed, 51 insertions(+), 77 deletions(-) diff --git a/cfbs/cfbs_config.py b/cfbs/cfbs_config.py index f5e46dc1..e38c1b88 100644 --- a/cfbs/cfbs_config.py +++ b/cfbs/cfbs_config.py @@ -37,7 +37,7 @@ from cfbs.pretty import pretty, CFBS_DEFAULT_SORTING_RULES from cfbs.cfbs_json import CFBSJson from cfbs.module import Module, is_module_added_manually -from cfbs.prompts import prompt_user, YES_NO_CHOICES +from cfbs.prompts import prompt_user, prompt_user_yesno from cfbs.validate import validate_single_module @@ -175,13 +175,10 @@ def _add_using_url( deps = "" if not deps else " (Depends on: " + ", ".join(deps) + ")" print(" - " + m["name"] + deps) if len(modules) > 1 and not self.non_interactive: - answer = prompt_user( + if not prompt_user_yesno( non_interactive=self.non_interactive, prompt="Do you want to add all %d of them?" % (len(modules)), - choices=YES_NO_CHOICES, - default="yes", - ) - if answer.lower() not in ("y", "yes"): + ): add_all = False else: missing = [k for k in to_add if k not in provides] @@ -191,14 +188,11 @@ def _add_using_url( for i, module in enumerate(modules, start=1): if not add_all: - answer = prompt_user( + if not prompt_user_yesno( non_interactive=self.non_interactive, prompt="(%d/%d) Do you want to add '%s'?" % (i, len(modules), module["name"]), - choices=YES_NO_CHOICES, - default="yes", - ) - if answer.lower() not in ("y", "yes"): + ): continue self.add_with_dependencies(module, remote_config, str_added_by=added_by) @@ -454,13 +448,12 @@ def add_command( + "Please make sure to run 'cfbs input' to re-enter input " + "before building and deploying/installing your project." ) - elif prompt_user( + elif prompt_user_yesno( self.non_interactive, "The added module '%s' accepts user input. " % name + "Do you want to add it now?", - YES_NO_CHOICES, - "no", - ).lower() in ("yes", "y"): + default="no", + ): input_data = copy.deepcopy(module["input"]) self.input_command(name, input_data) write_json(input_path, input_data) @@ -515,12 +508,9 @@ def _input_list(input_data): result = [] result.append(_input_elements(subtype)) - while prompt_user( - self.non_interactive, - input_data["while"], - choices=YES_NO_CHOICES, - default="no", - ).lower() in ("yes", "y"): + while prompt_user_yesno( + self.non_interactive, input_data["while"], default="no" + ): result.append(_input_elements(subtype)) return result @@ -532,12 +522,9 @@ def _input_list(input_data): % subtype["type"] ) result = [_input_string(subtype)] - while prompt_user( - self.non_interactive, - input_data["while"], - choices=YES_NO_CHOICES, - default="no", - ).lower() in ("yes", "y"): + while prompt_user_yesno( + self.non_interactive, input_data["while"], default="no" + ): result.append(_input_string(subtype)) return result raise CFBSExitError( diff --git a/cfbs/commands.py b/cfbs/commands.py index 154c050f..a7e80f08 100644 --- a/cfbs/commands.py +++ b/cfbs/commands.py @@ -109,7 +109,7 @@ def search_command(terms: List[str]) -> int: ls_remote, ) from cfbs.git_magic import Result, commit_after_command, git_commit_maybe_prompt -from cfbs.prompts import YES_NO_CHOICES, prompt_user +from cfbs.prompts import prompt_user, prompt_user_yesno from cfbs.module import Module, is_module_added_manually from cfbs.masterfiles.generate_release_information import generate_release_information @@ -199,20 +199,15 @@ def init_command(index=None, masterfiles=None, non_interactive=False) -> int: is_git = is_git_repo() if do_git is None: if is_git: - git_ans = prompt_user( + do_git = prompt_user_yesno( non_interactive, "This is a git repository. Do you want cfbs to make commits to it?", - choices=YES_NO_CHOICES, - default="yes", ) else: - git_ans = prompt_user( + do_git = prompt_user_yesno( non_interactive, "Do you want cfbs to initialize a git repository and make commits to it?", - choices=YES_NO_CHOICES, - default="yes", ) - do_git = git_ans.lower() in ("yes", "y") else: assert do_git in ("yes", "no") do_git = True if do_git == "yes" else False @@ -287,12 +282,10 @@ def init_command(index=None, masterfiles=None, non_interactive=False) -> int: branch = None to_add = [] if masterfiles is None: - if prompt_user( + if prompt_user_yesno( non_interactive, "Do you wish to build on top of the default policy set, masterfiles? (Recommended)", - choices=YES_NO_CHOICES, - default="yes", - ) in ("yes", "y"): + ): to_add = ["masterfiles"] else: answer = prompt_user( @@ -477,7 +470,7 @@ def _get_module_by_name(name) -> Union[dict, None]: def _remove_module_user_prompt(module): dependents = _get_dependents(module["name"]) - return prompt_user( + return prompt_user_yesno( config.non_interactive, "Do you wish to remove '%s'?" % module["name"] + ( @@ -486,8 +479,6 @@ def _remove_module_user_prompt(module): if dependents else "" ), - choices=YES_NO_CHOICES, - default="yes", ) def _get_modules_by_url(name) -> list: @@ -506,8 +497,7 @@ def _get_modules_by_url(name) -> list: if not matches: raise CFBSExitError("Could not find module with URL '%s'" % name) for module in matches: - answer = _remove_module_user_prompt(module) - if answer.lower() in ("yes", "y"): + if _remove_module_user_prompt(module): print("Removing module '%s'" % module["name"]) modules.remove(module) msg += "\n - Removed module '%s'" % module["name"] @@ -515,8 +505,7 @@ def _get_modules_by_url(name) -> list: else: module = _get_module_by_name(name) if module: - answer = _remove_module_user_prompt(module) - if answer.lower() in ("yes", "y"): + if _remove_module_user_prompt(module): print("Removing module '%s'" % name) modules.remove(module) msg += "\n - Removed module '%s'" % module["name"] @@ -524,13 +513,12 @@ def _get_modules_by_url(name) -> list: else: print("Module '%s' not found" % name) input_path = os.path.join(".", name, "input.json") - if os.path.isfile(input_path) and prompt_user( + if os.path.isfile(input_path) and prompt_user_yesno( config.non_interactive, "Module '%s' has input data '%s'. Do you want to remove it?" % (name, input_path), - choices=YES_NO_CHOICES, default="no", - ).lower() in ("yes", "y"): + ): rm(input_path) files.append(input_path) msg += "\n - Removed input data for module '%s'" % name @@ -594,13 +582,10 @@ def _someone_needs_me(this) -> bool: added_by = module["added_by"] if "added_by" in module else "" print("%s - %s - added by: %s" % (name, description, added_by)) - answer = prompt_user( + if prompt_user_yesno( config.non_interactive, "Do you wish to remove these modules?", - choices=YES_NO_CHOICES, - default="yes", - ) - if answer.lower() in ("yes", "y"): + ): for module in to_remove: modules.remove(module) config.save() @@ -1144,12 +1129,11 @@ def input_command(args, input_from="cfbs input") -> Result: input_path = os.path.join(".", module_name, "input.json") if os.path.isfile(input_path): - if prompt_user( + if not prompt_user_yesno( config.non_interactive, "Input already exists for this module, do you want to overwrite it?", - YES_NO_CHOICES, - "no", - ).lower() in ("no", "n"): + default="no", + ): continue input_data = copy.deepcopy(module["input"]) diff --git a/cfbs/git_magic.py b/cfbs/git_magic.py index 9589a96e..efb3f309 100644 --- a/cfbs/git_magic.py +++ b/cfbs/git_magic.py @@ -5,7 +5,7 @@ """ from typing import Iterable, Union -from cfbs.prompts import YES_NO_CHOICES, prompt_user +from cfbs.prompts import prompt_user_yesno from cfbs.cfbs_config import CFBSConfig, CFBSReturnWithoutCommit from cfbs.git import ( git_commit, @@ -49,13 +49,7 @@ def git_commit_maybe_prompt( prompt += "\n" if line == "" else "\t" + line + "\n" prompt += "\nEdit it?" - ans = prompt_user( - non_interactive, - prompt, - choices=YES_NO_CHOICES, - default="no", - ) - edit_commit_msg = ans.lower() in ("yes", "y") + edit_commit_msg = prompt_user_yesno(non_interactive, prompt, default="no") git_commit( commit_msg, diff --git a/cfbs/prompts.py b/cfbs/prompts.py index d4e9a031..2e780ae4 100644 --- a/cfbs/prompts.py +++ b/cfbs/prompts.py @@ -1,7 +1,7 @@ YES_NO_CHOICES = ("yes", "y", "no", "n") -def prompt_user(non_interactive, prompt, choices=None, default=None): +def prompt_user(non_interactive: bool, prompt: str, choices=None, default=None): if non_interactive: if default is None: raise ValueError( @@ -38,3 +38,16 @@ def prompt_user(non_interactive, prompt, choices=None, default=None): answer = None return answer + + +def prompt_user_yesno(non_interactive: bool, prompt: str, default="yes"): + """Returns `True` if the answer is yes, and `False` otherwise.""" + + answer = prompt_user( + non_interactive, + prompt, + choices=YES_NO_CHOICES, + default=default, + ) + + return answer.lower() in ("yes", "y") diff --git a/cfbs/updates.py b/cfbs/updates.py index 972f1167..64d66ad5 100644 --- a/cfbs/updates.py +++ b/cfbs/updates.py @@ -2,7 +2,7 @@ import os import logging as log -from cfbs.prompts import YES_NO_CHOICES, prompt_user +from cfbs.prompts import prompt_user_yesno from cfbs.utils import read_json, CFBSExitError, write_json @@ -134,16 +134,13 @@ def update_module(old_module, new_module, module_updates, update): if key == "steps": # same commit => user modifications, don't revert them if commit_differs: - ans = prompt_user( + if prompt_user_yesno( module_updates.config.non_interactive, "Module %s has different build steps now\n" % old_module["name"] + "old steps: %s\n" % old_module["steps"] + "new steps: %s\n" % new_module["steps"] + "Do you want to use the new build steps?", - choices=YES_NO_CHOICES, - default="yes", - ) - if ans.lower() in ["y", "yes"]: + ): old_module["steps"] = new_module["steps"] local_changes_made = True else: @@ -167,14 +164,13 @@ def update_module(old_module, new_module, module_updates, update): local_changes_made |= update_input_data(old_module, input_data) except InputDataUpdateFailed as e: log.warning(e) - if prompt_user( + if not prompt_user_yesno( module_updates.config.non_interactive, "Input for module '%s' has changed " % old_module["name"] + "and may no longer be compatible. " + "Do you want to re-enter input now?", - YES_NO_CHOICES, - "no", - ).lower() in ("no", "n"): + default="no", + ): continue input_data = copy.deepcopy(old_module["input"]) module_updates.config.input_command(