From e492aff4f708524a56f60f5ca200c8a97e2d3b4c Mon Sep 17 00:00:00 2001 From: "Adam J. Stewart" Date: Fri, 17 Feb 2017 15:45:02 -0600 Subject: [PATCH] More consistent yes/no prompts (#3174) * More consistent yes/no prompts * Add ==> prefix to yes/no and number prompts --- lib/spack/docs/tutorial_sc16_modules.rst | 6 ++-- lib/spack/docs/tutorial_sc16_spack_basics.rst | 9 ++--- lib/spack/llnl/util/tty/__init__.py | 16 ++++++--- lib/spack/spack/cmd/__init__.py | 11 ------ lib/spack/spack/cmd/module.py | 28 ++++++++------- lib/spack/spack/cmd/uninstall.py | 35 ++++++++++--------- 6 files changed, 51 insertions(+), 54 deletions(-) diff --git a/lib/spack/docs/tutorial_sc16_modules.rst b/lib/spack/docs/tutorial_sc16_modules.rst index 0a79d943f9..00b42251db 100644 --- a/lib/spack/docs/tutorial_sc16_modules.rst +++ b/lib/spack/docs/tutorial_sc16_modules.rst @@ -178,8 +178,7 @@ Next you should regenerate all the module files: ... - ==> Do you want to proceed ? [y/n] - y + ==> Do you want to proceed? [y/n] y ==> Regenerating tcl module files If you take a look now at the module for ``gcc`` you'll see that the unwanted @@ -242,8 +241,7 @@ and regenerate the module files: 3cfh3hi gmp@6.1.1 3k4ykbe libxml2@2.9.4 7tb426s ncurses@6.0 djdthlh nettle@3.2 i3rpk4e py-numpy@1.11.1 t5lk6in xz@5.2.2 3ostwel hwloc@1.11.4 cagoem4 lz4@131 mirer2l netlib-lapack@3.6.1 js33umc openblas@0.2.19 e6uljfi py-scipy@0.18.1 asydrba zlib@1.2.8 - ==> Do you want to proceed ? [y/n] - y + ==> Do you want to proceed? [y/n] y $ module avail diff --git a/lib/spack/docs/tutorial_sc16_spack_basics.rst b/lib/spack/docs/tutorial_sc16_spack_basics.rst index 9511907ceb..ed58c7c5cf 100644 --- a/lib/spack/docs/tutorial_sc16_spack_basics.rst +++ b/lib/spack/docs/tutorial_sc16_spack_basics.rst @@ -1006,8 +1006,7 @@ We can uninstall packages by spec using the same syntax as install. w33hrej libelf@0.8.13%intel - ==> Do you want to proceed ? [y/n] - y + ==> Do you want to proceed? [y/n] y ==> Successfully uninstalled libelf@0.8.13%intel@15.0.4 arch=linux-redhat6-x86_64-w33hrej @@ -1054,8 +1053,7 @@ remove packages that are required by another installed package. 4blbe3q libelf@0.8.12%intel - ==> Do you want to proceed ? [y/n] - y + ==> Do you want to proceed? [y/n] y ==> Successfully uninstalled libdwarf@20160507%intel@16.0.3 arch=linux-redhat6-x86_64-csruprg ==> Successfully uninstalled libelf@0.8.12%intel@16.0.3 arch=linux-redhat6-x86_64-4blbe3q @@ -1088,8 +1086,7 @@ packages at once. ffwrpxn trilinos@12.8.1%gcc+boost~debug+hdf5+hypre+metis+mumps~python+shared+suite-sparse+superlu-dist - ==> Do you want to proceed ? [y/n] - y + ==> Do you want to proceed? [y/n] y ==> Successfully uninstalled trilinos@12.8.1%gcc@4.4.7+boost~debug+hdf5+hypre+metis+mumps~python+shared+suite-sparse+superlu-dist arch=linux-redhat6-x86_64-ffwrpxn ----------------------------- diff --git a/lib/spack/llnl/util/tty/__init__.py b/lib/spack/llnl/util/tty/__init__.py index 1381bb2f7d..f73d96a4e4 100644 --- a/lib/spack/llnl/util/tty/__init__.py +++ b/lib/spack/llnl/util/tty/__init__.py @@ -59,7 +59,7 @@ def set_debug(flag): def set_verbose(flag): global _verbose _verbose = flag - + def set_stacktrace(flag): global _stacktrace @@ -83,11 +83,15 @@ def process_stacktrace(countback): return st_text -def msg(message, *args): +def msg(message, *args, **kwargs): + newline = kwargs.get('newline', True) st_text = "" if _stacktrace: st_text = process_stacktrace(2) - cprint("@*b{%s==>} %s" % (st_text, cescape(message))) + if newline: + cprint("@*b{%s==>} %s" % (st_text, cescape(message))) + else: + cwrite("@*b{%s==>} %s" % (st_text, cescape(message))) for arg in args: print indent + str(arg) @@ -159,7 +163,8 @@ def get_number(prompt, **kwargs): number = None while number is None: - ans = raw_input(prompt) + msg(prompt, newline=False) + ans = raw_input() if ans == str(abort): return None @@ -191,7 +196,8 @@ def get_yes_or_no(prompt, **kwargs): result = None while result is None: - ans = raw_input(prompt).lower() + msg(prompt, newline=False) + ans = raw_input().lower() if not ans: result = default_value if result is None: diff --git a/lib/spack/spack/cmd/__init__.py b/lib/spack/spack/cmd/__init__.py index 764b6fffcf..3a42510245 100644 --- a/lib/spack/spack/cmd/__init__.py +++ b/lib/spack/spack/cmd/__init__.py @@ -159,17 +159,6 @@ def disambiguate_spec(spec): return matching_specs[0] -def ask_for_confirmation(message): - while True: - tty.msg(message + '[y/n]') - choice = raw_input().lower() - if choice == 'y': - break - elif choice == 'n': - raise SystemExit('Operation aborted') - tty.warn('Please reply either "y" or "n"') - - def gray_hash(spec, length): return colorize('@K{%s}' % spec.dag_hash(length)) diff --git a/lib/spack/spack/cmd/module.py b/lib/spack/spack/cmd/module.py index a924c5f912..37c79a358b 100644 --- a/lib/spack/spack/cmd/module.py +++ b/lib/spack/spack/cmd/module.py @@ -29,10 +29,10 @@ import shutil import sys -import llnl.util.filesystem as filesystem -import llnl.util.tty as tty import spack.cmd -import spack.cmd.common.arguments as arguments + +from llnl.util import filesystem, tty +from spack.cmd.common import arguments from spack.modules import module_types description = "manipulate module files" @@ -168,7 +168,7 @@ def find(mtype, specs, args): spec = specs.pop() mod = module_types[mtype](spec) if not os.path.isfile(mod.file_name): - tty.die("No %s module is installed for %s" % (mtype, spec)) + tty.die('No {0} module is installed for {1}'.format(mtype, spec)) print(mod.use_name) @@ -191,7 +191,9 @@ def rm(mtype, specs, args): .format(mtype)) spack.cmd.display_specs(specs_with_modules, long=True) print('') - spack.cmd.ask_for_confirmation('Do you want to proceed ? ') + answer = tty.get_yes_or_no('Do you want to proceed?') + if not answer: + tty.die('Will not remove any module files') # Remove the module files for s in modules: @@ -212,7 +214,9 @@ def refresh(mtype, specs, args): .format(name=mtype)) spack.cmd.display_specs(specs, long=True) print('') - spack.cmd.ask_for_confirmation('Do you want to proceed ? ') + answer = tty.get_yes_or_no('Do you want to proceed?') + if not answer: + tty.die('Will not regenerate any module files') cls = module_types[mtype] @@ -227,9 +231,9 @@ def refresh(mtype, specs, args): message = 'Name clashes detected in module files:\n' for filename, writer_list in file2writer.items(): if len(writer_list) > 1: - message += '\nfile : {0}\n'.format(filename) + message += '\nfile: {0}\n'.format(filename) for x in writer_list: - message += 'spec : {0}\n'.format(x.spec.format(color=True)) + message += 'spec: {0}\n'.format(x.spec.format(color=True)) tty.error(message) tty.error('Operation aborted') raise SystemExit(1) @@ -258,13 +262,13 @@ def module(parser, args): try: callbacks[args.subparser_name](module_type, specs, args) except MultipleMatches: - message = ('the constraint \'{query}\' matches multiple packages, ' - 'and this is not allowed in this context') + message = ("the constraint '{query}' matches multiple packages, " + "and this is not allowed in this context") tty.error(message.format(query=constraint)) for s in specs: sys.stderr.write(s.format(color=True) + '\n') raise SystemExit(1) except NoMatch: - message = ('the constraint \'{query}\' match no package, ' - 'and this is not allowed in this context') + message = ("the constraint '{query}' matches no package, " + "and this is not allowed in this context") tty.die(message.format(query=constraint)) diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py index 5c33a4d648..e0b40e0627 100644 --- a/lib/spack/spack/cmd/uninstall.py +++ b/lib/spack/spack/cmd/uninstall.py @@ -26,17 +26,18 @@ import argparse -import llnl.util.tty as tty import spack import spack.cmd import spack.store import spack.repository +from llnl.util import tty + description = "remove an installed package" error_message = """You can either: - a) Use a more specific spec, or - b) use spack uninstall -a to uninstall ALL matching specs. + a) use a more specific spec, or + b) use `spack uninstall --all` to uninstall ALL matching specs. """ # Arguments for display_specs when we find ambiguity @@ -94,7 +95,7 @@ def concretize_specs(specs, allow_multiple_matches=False, force=False): # For each spec provided, make sure it refers to only one package. # Fail and ask user to be unambiguous if it doesn't if not allow_multiple_matches and len(matching) > 1: - tty.error("%s matches multiple packages:" % spec) + tty.error('{0} matches multiple packages:'.format(spec)) print() spack.cmd.display_specs(matching, **display_args) print() @@ -102,7 +103,8 @@ def concretize_specs(specs, allow_multiple_matches=False, force=False): # No installed package matches the query if len(matching) == 0 and spec is not any: - tty.error("%s does not match any installed packages." % spec) + tty.error('{0} does not match any installed packages.'.format( + spec)) has_errors = True specs_from_cli.extend(matching) @@ -176,10 +178,10 @@ def get_uninstall_list(args): has_error = False if dependent_list and not args.dependents and not args.force: for spec, lst in dependent_list.items(): - tty.error("Will not uninstall %s" % - spec.format("$_$@$%@$/", color=True)) + tty.error('Will not uninstall {0}'.format( + spec.format("$_$@$%@$/", color=True))) print('') - print("The following packages depend on it:") + print('The following packages depend on it:') spack.cmd.display_specs(lst, **display_args) print('') has_error = True @@ -188,28 +190,29 @@ def get_uninstall_list(args): uninstall_list.extend(lst) uninstall_list = list(set(uninstall_list)) if has_error: - tty.die('You can use spack uninstall --dependents ' - 'to uninstall these dependencies as well') + tty.die('Use `spack uninstall --dependents` ' + 'to uninstall these dependencies as well.') return uninstall_list def uninstall(parser, args): if not args.packages and not args.all: - tty.die("uninstall requires at least one package argument.") + tty.die('uninstall requires at least one package argument.', + ' Use `spack uninstall --all` to uninstall ALL packages.') uninstall_list = get_uninstall_list(args) if not uninstall_list: - tty.msg("There are no package to uninstall.") + tty.warn('There are no package to uninstall.') return if not args.yes_to_all: - tty.msg("The following packages will be uninstalled : ") - print('') + tty.msg('The following packages will be uninstalled:\n') spack.cmd.display_specs(uninstall_list, **display_args) - print('') - spack.cmd.ask_for_confirmation('Do you want to proceed ? ') + answer = tty.get_yes_or_no('Do you want to proceed?', default=False) + if not answer: + tty.die('Will not uninstall any packages.') # Uninstall everything on the list do_uninstall(uninstall_list, args.force)