diff options
author | Adam J. Stewart <ajstewart426@gmail.com> | 2020-01-05 23:35:23 -0800 |
---|---|---|
committer | Todd Gamblin <tgamblin@llnl.gov> | 2020-01-22 21:31:12 -0800 |
commit | 11f2b612612748ee57728693c7745e3af92e9d54 (patch) | |
tree | 656c2ba1de69064c62af1fbd4f43469f7c36cac9 /share | |
parent | 8011fedd9ca47578e8da37a9060407c6784d7015 (diff) | |
download | spack-11f2b612612748ee57728693c7745e3af92e9d54.tar.gz spack-11f2b612612748ee57728693c7745e3af92e9d54.tar.bz2 spack-11f2b612612748ee57728693c7745e3af92e9d54.tar.xz spack-11f2b612612748ee57728693c7745e3af92e9d54.zip |
Use `spack commands --format=bash` to generate shell completion (#14393)
This PR adds a `--format=bash` option to `spack commands` to
auto-generate the Bash programmable tab completion script. It can be
extended to work for other shells.
Progress:
- [x] Fix bug in superclass initialization in `ArgparseWriter`
- [x] Refactor `ArgparseWriter` (see below)
- [x] Ensure that output of old `--format` options remains the same
- [x] Add `ArgparseCompletionWriter` and `BashCompletionWriter`
- [x] Add `--aliases` option to add command aliases
- [x] Standardize positional argument names
- [x] Tests for `spack commands --format=bash` coverage
- [x] Tests to make sure `spack-completion.bash` stays up-to-date
- [x] Tests for `spack-completion.bash` coverage
- [x] Speed up `spack-completion.bash` by caching subroutine calls
This PR also necessitates a significant refactoring of
`ArgparseWriter`. Previously, `ArgparseWriter` was mostly a single
`_write` method which handled everything from extracting the information
we care about from the parser to formatting the output. Now, `_write`
only handles recursion, while the information extraction is split into a
separate `parse` method, and the formatting is handled by `format`. This
allows subclasses to completely redefine how the format will appear
without overriding all of `_write`.
Co-Authored-by: Todd Gamblin <tgamblin@llnl.gov>
Diffstat (limited to 'share')
-rwxr-xr-x | share/spack/bash/spack-completion.in | 309 | ||||
-rwxr-xr-x | share/spack/qa/completion-test.sh | 89 | ||||
-rwxr-xr-x | share/spack/qa/run-unit-tests | 17 | ||||
-rwxr-xr-x | share/spack/qa/setup-env-test.sh | 195 | ||||
-rwxr-xr-x | share/spack/qa/test-framework.sh | 195 | ||||
-rwxr-xr-x | share/spack/qa/update-completion-scripts.sh | 23 | ||||
-rwxr-xr-x | share/spack/spack-completion.bash | 1284 |
7 files changed, 1403 insertions, 709 deletions
diff --git a/share/spack/bash/spack-completion.in b/share/spack/bash/spack-completion.in new file mode 100755 index 0000000000..2ab39a57a3 --- /dev/null +++ b/share/spack/bash/spack-completion.in @@ -0,0 +1,309 @@ +# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + + +# NOTE: spack-completion.bash is auto-generated by: +# +# $ spack commands --aliases --format=bash +# --header=bash/spack-completion.in --update=spack-completion.bash +# +# Please do not manually modify this file. + + +# The following global variables are set by Bash programmable completion: +# +# COMP_CWORD: An index into ${COMP_WORDS} of the word containing the +# current cursor position +# COMP_KEY: The key (or final key of a key sequence) used to invoke +# the current completion function +# COMP_LINE: The current command line +# COMP_POINT: The index of the current cursor position relative to the +# beginning of the current command +# COMP_TYPE: Set to an integer value corresponding to the type of +# completion attempted that caused a completion function +# to be called +# COMP_WORDBREAKS: The set of characters that the readline library treats +# as word separators when performing word completion +# COMP_WORDS: An array variable consisting of the individual words in +# the current command line +# +# The following global variable is used by Bash programmable completion: +# +# COMPREPLY: An array variable from which bash reads the possible +# completions generated by a shell function invoked by the +# programmable completion facility +# +# See `man bash` for more details. + +# Bash programmable completion for Spack +_bash_completion_spack() { + # In all following examples, let the cursor be denoted by brackets, i.e. [] + + # For our purposes, flags should not affect tab completion. For instance, + # `spack install []` and `spack -d install --jobs 8 []` should both give the same + # possible completions. Therefore, we need to ignore any flags in COMP_WORDS. + local COMP_WORDS_NO_FLAGS=() + local index=0 + while [[ "$index" -lt "$COMP_CWORD" ]] + do + if [[ "${COMP_WORDS[$index]}" == [a-z]* ]] + then + COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$index]}") + fi + let index++ + done + + # Options will be listed by a subfunction named after non-flag arguments. + # For example, `spack -d install []` will call _spack_install + # and `spack compiler add []` will call _spack_compiler_add + local subfunction=$(IFS='_'; echo "_${COMP_WORDS_NO_FLAGS[*]}") + + # Translate dashes to underscores, as dashes are not permitted in + # compatibility mode. See https://github.com/spack/spack/pull/4079 + subfunction=${subfunction//-/_} + + # However, the word containing the current cursor position needs to be + # added regardless of whether or not it is a flag. This allows us to + # complete something like `spack install --keep-st[]` + COMP_WORDS_NO_FLAGS+=("${COMP_WORDS[$COMP_CWORD]}") + + # Since we have removed all words after COMP_CWORD, we can safely assume + # that COMP_CWORD_NO_FLAGS is simply the index of the last element + local COMP_CWORD_NO_FLAGS=$((${#COMP_WORDS_NO_FLAGS[@]} - 1)) + + # There is no guarantee that the cursor is at the end of the command line + # when tab completion is envoked. For example, in the following situation: + # `spack -d [] install` + # if the user presses the TAB key, a list of valid flags should be listed. + # Note that we cannot simply ignore everything after the cursor. In the + # previous scenario, the user should expect to see a list of flags, but + # not of other subcommands. Obviously, `spack -d list install` would be + # invalid syntax. To accomplish this, we use the variable list_options + # which is true if the current word starts with '-' or if the cursor is + # not at the end of the line. + local list_options=false + if [[ "${COMP_WORDS[$COMP_CWORD]}" == -* || "$COMP_POINT" -ne "${#COMP_LINE}" ]] + then + list_options=true + fi + + # In general, when envoking tab completion, the user is not expecting to + # see optional flags mixed in with subcommands or package names. Tab + # completion is used by those who are either lazy or just bad at spelling. + # If someone doesn't remember what flag to use, seeing single letter flags + # in their results won't help them, and they should instead consult the + # documentation. However, if the user explicitly declares that they are + # looking for a flag, we can certainly help them out. + # `spack install -[]` + # and + # `spack install --[]` + # should list all flags and long flags, respectively. Furthermore, if a + # subcommand has no non-flag completions, such as `spack arch []`, it + # should list flag completions. + + local cur=${COMP_WORDS_NO_FLAGS[$COMP_CWORD_NO_FLAGS]} + + # If the cursor is in the middle of the line, like: + # `spack -d [] install` + # COMP_WORDS will not contain the empty character, so we have to add it. + if [[ "${COMP_LINE:$COMP_POINT:1}" == " " ]] + then + cur="" + fi + + # Uncomment this line to enable logging + #_test_vars >> temp + + # Make sure function exists before calling it + if [[ "$(type -t $subfunction)" == "function" ]] + then + $subfunction + COMPREPLY=($(compgen -W "$SPACK_COMPREPLY" -- "$cur")) + fi +} + +# Helper functions for subcommands +# Results of each query are cached via environment variables + +_subcommands() { + if [[ -z "${SPACK_SUBCOMMANDS:-}" ]] + then + SPACK_SUBCOMMANDS="$(spack commands)" + fi + SPACK_COMPREPLY="$SPACK_SUBCOMMANDS" +} + +_all_packages() { + if [[ -z "${SPACK_ALL_PACKAGES:-}" ]] + then + SPACK_ALL_PACKAGES="$(spack list)" + fi + SPACK_COMPREPLY="$SPACK_ALL_PACKAGES" +} + +_all_resource_hashes() { + if [[ -z "${SPACK_ALL_RESOURCES_HASHES:-}" ]] + then + SPACK_ALL_RESOURCE_HASHES="$(spack resource list --only-hashes)" + fi + SPACK_COMPREPLY="$SPACK_ALL_RESOURCE_HASHES" +} + +_installed_packages() { + if [[ -z "${SPACK_INSTALLED_PACKAGES:-}" ]] + then + SPACK_INSTALLED_PACKAGES="$(spack --color=never find --no-groups)" + fi + SPACK_COMPREPLY="$SPACK_INSTALLED_PACKAGES" +} + +_installed_compilers() { + if [[ -z "${SPACK_INSTALLED_COMPILERS:-}" ]] + then + SPACK_INSTALLED_COMPILERS="$(spack compilers | egrep -v "^(-|=)")" + fi + SPACK_COMPREPLY="$SPACK_INSTALLED_COMPILERS" +} + +_providers() { + if [[ -z "${SPACK_PROVIDERS:-}" ]] + then + SPACK_PROVIDERS="$(spack providers)" + fi + SPACK_COMPREPLY="$SPACK_PROVIDERS" +} + +_mirrors() { + if [[ -z "${SPACK_MIRRORS:-}" ]] + then + SPACK_MIRRORS="$(spack mirror list | awk '{print $1}')" + fi + SPACK_COMPREPLY="$SPACK_MIRRORS" +} + +_repos() { + if [[ -z "${SPACK_REPOS:-}" ]] + then + SPACK_REPOS="$(spack repo list | awk '{print $1}')" + fi + SPACK_COMPREPLY="$SPACK_REPOS" +} + +_tests() { + if [[ -z "${SPACK_TESTS:-}" ]] + then + SPACK_TESTS="$(spack test -l)" + fi + SPACK_COMPREPLY="$SPACK_TESTS" +} + +_environments() { + if [[ -z "${SPACK_ENVIRONMENTS:-}" ]] + then + SPACK_ENVIRONMENTS="$(spack env list)" + fi + SPACK_COMPREPLY="$SPACK_ENVIRONMENTS" +} + +_keys() { + if [[ -z "${SPACK_KEYS:-}" ]] + then + SPACK_KEYS="$(spack gpg list)" + fi + SPACK_COMPREPLY="$SPACK_KEYS" +} + +_config_sections() { + if [[ -z "${SPACK_CONFIG_SECTIONS:-}" ]] + then + SPACK_CONFIG_SECTIONS="compilers mirrors repos packages modules config upstreams" + fi + SPACK_COMPREPLY="$SPACK_CONFIG_SECTIONS" +} + +_extensions() { + if [[ -z "${SPACK_EXTENSIONS:-}" ]] + then + SPACK_EXTENSIONS="aspell go-bootstrap go icedtea jdk kim-api lua matlab mofem-cephas octave openjdk perl python r ruby rust tcl yorick" + fi + SPACK_COMPREPLY="$SPACK_EXTENSIONS" +} + +# Testing functions + +# Function for unit testing tab completion +# Syntax: _spack_completions spack install py- +_spack_completions() { + local COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMP_TYPE COMP_WORDS COMPREPLY + + # Set each variable the way bash would + COMP_LINE="$*" + COMP_POINT=${#COMP_LINE} + COMP_WORDS=("$@") + if [[ ${COMP_LINE: -1} == ' ' ]] + then + COMP_WORDS+=('') + fi + COMP_CWORD=$((${#COMP_WORDS[@]} - 1)) + COMP_KEY=9 # ASCII 09: Horizontal Tab + COMP_TYPE=64 # ASCII 64: '@', to list completions if the word is not unmodified + + # Run Spack's tab completion function + _bash_completion_spack + + # Return the result + echo "${COMPREPLY[@]:-}" +} + +# Log the environment variables used +# Syntax: _test_vars >> temp +_test_vars() { + echo "-----------------------------------------------------" + echo "Variables set by bash:" + echo + echo "COMP_LINE: '$COMP_LINE'" + echo "# COMP_LINE: '${#COMP_LINE}'" + echo "COMP_WORDS: $(_pretty_print COMP_WORDS[@])" + echo "# COMP_WORDS: '${#COMP_WORDS[@]}'" + echo "COMP_CWORD: '$COMP_CWORD'" + echo "COMP_KEY: '$COMP_KEY'" + echo "COMP_POINT: '$COMP_POINT'" + echo "COMP_TYPE: '$COMP_TYPE'" + echo "COMP_WORDBREAKS: '$COMP_WORDBREAKS'" + echo + echo "Intermediate variables:" + echo + echo "COMP_WORDS_NO_FLAGS: $(_pretty_print COMP_WORDS_NO_FLAGS[@])" + echo "# COMP_WORDS_NO_FLAGS: '${#COMP_WORDS_NO_FLAGS[@]}'" + echo "COMP_CWORD_NO_FLAGS: '$COMP_CWORD_NO_FLAGS'" + echo + echo "Subfunction: '$subfunction'" + if $list_options + then + echo "List options: 'True'" + else + echo "List options: 'False'" + fi + echo "Current word: '$cur'" +} + +# Pretty-prints one or more arrays +# Syntax: _pretty_print array1[@] ... +_pretty_print() { + for arg in $@ + do + local array=("${!arg}") + printf "$arg: [" + printf "'%s'" "${array[0]}" + printf ", '%s'" "${array[@]:1}" + echo "]" + done +} + +complete -o bashdefault -o default -F _bash_completion_spack spack + +# Spack commands +# +# Everything below here is auto-generated. diff --git a/share/spack/qa/completion-test.sh b/share/spack/qa/completion-test.sh new file mode 100755 index 0000000000..5b326b4a6d --- /dev/null +++ b/share/spack/qa/completion-test.sh @@ -0,0 +1,89 @@ +#!/bin/sh +# +# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +# +# This script tests that Spack's tab completion scripts work. +# +# The tests are portable to bash, zsh, and bourne shell, and can be run +# in any of these shells. +# + +export QA_DIR=$(dirname "$0") +export SHARE_DIR=$(cd "$QA_DIR/.." && pwd) +export SPACK_ROOT=$(cd "$QA_DIR/../../.." && pwd) + +. "$QA_DIR/test-framework.sh" + +# Fail on undefined variables +set -u + +# Source setup-env.sh before tests +. "$SHARE_DIR/setup-env.sh" +. "$SHARE_DIR/spack-completion.$_sp_shell" + +title "Testing spack-completion.$_sp_shell with $_sp_shell" + +# Spack command is now available +succeeds which spack + +title 'Testing all subcommands' +while IFS= read -r line +do + # Test that completion with no args works + succeeds _spack_completions ${line[*]} '' + + # Test that completion with flags works + contains '-h --help' _spack_completions ${line[*]} - +done <<- EOF + $(spack commands --aliases --format=subcommands) +EOF + +title 'Testing for correct output' +contains 'compiler' _spack_completions spack '' +contains 'install' _spack_completions spack inst +contains 'find' _spack_completions spack help '' +contains 'hdf5' _spack_completions spack list '' +contains 'py-numpy' _spack_completions spack list py- +contains 'mpi' _spack_completions spack providers '' +contains 'builtin' _spack_completions spack repo remove '' +contains 'packages' _spack_completions spack config edit '' +contains 'python' _spack_completions spack extensions '' +contains 'hdf5' _spack_completions spack -d install --jobs 8 '' +contains 'hdf5' _spack_completions spack install -v '' + +# XFAIL: Fails for Python 2.6 because pkg_resources not found? +#contains 'compilers.py' _spack_completions spack test '' + +title 'Testing debugging functions' + +# This is a particularly tricky case that involves the following situation: +# `spack -d [] install ` +# Here, [] represents the cursor, which is in the middle of the line. +# We should tab-complete optional flags for `spack`, not optional flags for +# `spack install` or package names. +COMP_LINE='spack -d install ' +COMP_POINT=9 +COMP_WORDS=(spack -d install) +COMP_CWORD=2 +COMP_KEY=9 +COMP_TYPE=64 + +_bash_completion_spack +contains "--all-help" echo "${COMPREPLY[@]}" + +contains "['spack', '-d', 'install', '']" _pretty_print COMP_WORDS[@] + +# Set the rest of the intermediate variables manually +COMP_WORDS_NO_FLAGS=(spack install) +COMP_CWORD_NO_FLAGS=1 +subfunction=_spack +cur= + +list_options=true +contains "'True'" _test_vars +list_options=false +contains "'False'" _test_vars diff --git a/share/spack/qa/run-unit-tests b/share/spack/qa/run-unit-tests index 8ba6eed350..52748dacdf 100755 --- a/share/spack/qa/run-unit-tests +++ b/share/spack/qa/run-unit-tests @@ -23,7 +23,7 @@ ORIGINAL_PATH="$PATH" . "$(dirname $0)/setup.sh" -check_dependencies ${coverage} git hg svn +check_dependencies $coverage git hg svn # Move to root directory of Spack # Allows script to be run from anywhere @@ -46,7 +46,7 @@ extra_args="" if [[ -n "$@" ]]; then extra_args="-k $@" fi -${coverage_run} bin/spack test -x --verbose "$extra_args" +$coverage_run bin/spack test -x --verbose "$extra_args" #----------------------------------------------------------- # Run tests for setup-env.sh @@ -57,15 +57,18 @@ export PATH="$ORIGINAL_PATH" unset spack # start in the spack root directory -cd $SPACK_ROOT +cd "$SPACK_ROOT" # Run bash tests with coverage enabled, but pipe output to /dev/null # because it seems that kcov seems to undo the script's redirection if [ "$BASH_COVERAGE" = true ]; then - ${QA_DIR}/bashcov ${QA_DIR}/setup-env-test.sh &> /dev/null + "$QA_DIR/bashcov" "$QA_DIR/setup-env-test.sh" &> /dev/null + "$QA_DIR/bashcov" "$QA_DIR/completion-test.sh" &> /dev/null fi # run the test scripts for their output (these will print nicely) -bash ${QA_DIR}/setup-env-test.sh -zsh ${QA_DIR}/setup-env-test.sh -dash ${QA_DIR}/setup-env-test.sh +bash "$QA_DIR/setup-env-test.sh" +zsh "$QA_DIR/setup-env-test.sh" +dash "$QA_DIR/setup-env-test.sh" + +bash "$QA_DIR/completion-test.sh" diff --git a/share/spack/qa/setup-env-test.sh b/share/spack/qa/setup-env-test.sh index 7613637984..66284d1a96 100755 --- a/share/spack/qa/setup-env-test.sh +++ b/share/spack/qa/setup-env-test.sh @@ -12,159 +12,11 @@ # in any of these shells. # -# ------------------------------------------------------------------------ -# Functions for color output. -# ------------------------------------------------------------------------ - -# Colors for output -red='\033[1;31m' -cyan='\033[1;36m' -green='\033[1;32m' -reset='\033[0m' - -echo_red() { - printf "${red}$*${reset}\n" -} - -echo_green() { - printf "${green}$*${reset}\n" -} - -echo_msg() { - printf "${cyan}$*${reset}\n" -} - -# ------------------------------------------------------------------------ -# Generic functions for testing shell code. -# ------------------------------------------------------------------------ - -# counts of test successes and failures. -success=0 -errors=0 - -# Print out a header for a group of tests. -title() { - echo - echo_msg "$@" - echo_msg "---------------------------------" -} - -# echo FAIL in red text; increment failures -fail() { - echo_red FAIL - errors=$((errors+1)) -} - -# -# Echo SUCCESS in green; increment successes -# -pass() { - echo_green SUCCESS - success=$((success+1)) -} - -# -# Run a command and suppress output unless it fails. -# On failure, echo the exit code and output. -# -succeeds() { - printf "'%s' succeeds ... " "$*" - output=$($* 2>&1) - err="$?" - - if [ "$err" != 0 ]; then - fail - echo_red "Command failed with error $err." - if [ -n "$output" ]; then - echo_msg "Output:" - echo "$output" - else - echo_msg "No output." - fi - else - pass - fi -} - -# -# Run a command and suppress output unless it succeeds. -# If the command succeeds, echo the output. -# -fails() { - printf "'%s' fails ... " "$*" - output=$("$@" 2>&1) - err="$?" - - if [ "$err" = 0 ]; then - fail - echo_red "Command failed with error $err." - if [ -n "$output" ]; then - echo_msg "Output:" - echo "$output" - else - echo_msg "No output." - fi - else - pass - fi -} - -# -# Ensure that a string is in the output of a command. -# Suppresses output on success. -# On failure, echo the exit code and output. -# -contains() { - string="$1" - shift - - printf "'%s' output contains '$string' ... " "$*" - output=$("$@" 2>&1) - err="$?" - - if [ "${output#*$string}" = "${output}" ]; then - fail - echo_red "Command exited with error $err." - echo_red "'$string' was not in output." - if [ -n "$output" ]; then - echo_msg "Output:" - echo "$output" - else - echo_msg "No output." - fi - else - pass - fi -} - -# -# Ensure that a variable is set. -# -is_set() { - printf "'%s' is set ... " "$1" - if eval "[ -z \${${1:-}+x} ]"; then - fail - echo_msg "$1 was not set!" - else - pass - fi -} - -# -# Ensure that a variable is not set. -# Fails and prints the value of the variable if it is set. -# -is_not_set() { - printf "'%s' is not set ... " "$1" - if eval "[ ! -z \${${1:-}+x} ]"; then - fail - echo_msg "$1 was set:" - echo " $1" - else - pass - fi -} +export QA_DIR=$(dirname "$0") +export SHARE_DIR=$(cd "$QA_DIR/.." && pwd) +export SPACK_ROOT=$(cd "$QA_DIR/../../.." && pwd) +. "$QA_DIR/test-framework.sh" # ----------------------------------------------------------------------- # Instead of invoking the module commands, we print the @@ -184,28 +36,28 @@ module() { # Make sure no environment is active unset SPACK_ENV -# fail on undefined variables +# Fail on undefined variables set -u # Source setup-env.sh before tests -. share/spack/setup-env.sh +. "$SHARE_DIR/setup-env.sh" -# bash should expand aliases even when non-interactive +# Bash should expand aliases even when non-interactive if [ -n "${BASH:-}" ]; then shopt -s expand_aliases fi title "Testing setup-env.sh with $_sp_shell" -# spack command is now avaialble +# Spack command is now available succeeds which spack -# mock cd command (intentionally define only AFTER setup-env.sh) +# Mock cd command (intentionally define only AFTER setup-env.sh) cd() { echo cd "$@" } -# create a fake mock package install and store its location for later +# Create a fake mock package install and store its location for later title "Setup" echo "Creating a mock package installation" spack -m install --fake a @@ -215,19 +67,13 @@ a_module=$(spack -m module tcl find a) b_install=$(spack location -i b) b_module=$(spack -m module tcl find b) -# create a test environment for tesitng environment commands +# Create a test environment for testing environment commands echo "Creating a mock environment" spack env create spack_test_env test_env_location=$(spack location -e spack_test_env) -# ensure that we uninstall b on exit +# Ensure that we uninstall b on exit cleanup() { - if [ "$?" != 0 ]; then - trapped_error=true - else - trapped_error=false - fi - echo "Removing test environment before exiting." spack env deactivate 2>&1 > /dev/null spack env rm -y spack_test_env @@ -235,24 +81,7 @@ cleanup() { title "Cleanup" echo "Removing test packages before exiting." spack -m uninstall -yf b a - - echo - echo "$success tests succeeded." - echo "$errors tests failed." - - if [ "$trapped_error" = true ]; then - echo "Exited due to an error." - fi - - if [ "$errors" = 0 ] && [ "$trapped_error" = false ]; then - pass - exit 0 - else - fail - exit 1 - fi } -trap cleanup EXIT # ----------------------------------------------------------------------- # Test all spack commands with special env support diff --git a/share/spack/qa/test-framework.sh b/share/spack/qa/test-framework.sh new file mode 100755 index 0000000000..14b58bbecf --- /dev/null +++ b/share/spack/qa/test-framework.sh @@ -0,0 +1,195 @@ +# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +# +# A testing framework for any POSIX-compatible shell. +# + +# ------------------------------------------------------------------------ +# Functions for color output. +# ------------------------------------------------------------------------ + +# Colors for output +red='\033[1;31m' +cyan='\033[1;36m' +green='\033[1;32m' +reset='\033[0m' + +echo_red() { + printf "${red}$*${reset}\n" +} + +echo_green() { + printf "${green}$*${reset}\n" +} + +echo_msg() { + printf "${cyan}$*${reset}\n" +} + +# ------------------------------------------------------------------------ +# Generic functions for testing shell code. +# ------------------------------------------------------------------------ + +# counts of test successes and failures. +success=0 +errors=0 + +# Print out a header for a group of tests. +title() { + echo + echo_msg "$@" + echo_msg "---------------------------------" +} + +# echo FAIL in red text; increment failures +fail() { + echo_red FAIL + errors=$((errors+1)) +} + +# +# Echo SUCCESS in green; increment successes +# +pass() { + echo_green SUCCESS + success=$((success+1)) +} + +# +# Run a command and suppress output unless it fails. +# On failure, echo the exit code and output. +# +succeeds() { + printf "'%s' succeeds ... " "$*" + output=$("$@" 2>&1) + err="$?" + + if [ "$err" != 0 ]; then + fail + echo_red "Command failed with error $err." + if [ -n "$output" ]; then + echo_msg "Output:" + echo "$output" + else + echo_msg "No output." + fi + else + pass + fi +} + +# +# Run a command and suppress output unless it succeeds. +# If the command succeeds, echo the output. +# +fails() { + printf "'%s' fails ... " "$*" + output=$("$@" 2>&1) + err="$?" + + if [ "$err" = 0 ]; then + fail + echo_red "Command failed with error $err." + if [ -n "$output" ]; then + echo_msg "Output:" + echo "$output" + else + echo_msg "No output." + fi + else + pass + fi +} + +# +# Ensure that a string is in the output of a command. +# Suppresses output on success. +# On failure, echo the exit code and output. +# +contains() { + string="$1" + shift + + printf "'%s' output contains '$string' ... " "$*" + output=$("$@" 2>&1) + err="$?" + + if [ "${output#*$string}" = "${output}" ]; then + fail + echo_red "Command exited with error $err." + echo_red "'$string' was not in output." + if [ -n "$output" ]; then + echo_msg "Output:" + echo "$output" + else + echo_msg "No output." + fi + else + pass + fi +} + +# +# Ensure that a variable is set. +# +is_set() { + printf "'%s' is set ... " "$1" + if eval "[ -z \${${1:-}+x} ]"; then + fail + echo_msg "$1 was not set!" + else + pass + fi +} + +# +# Ensure that a variable is not set. +# Fails and prints the value of the variable if it is set. +# +is_not_set() { + printf "'%s' is not set ... " "$1" + if eval "[ ! -z \${${1:-}+x} ]"; then + fail + echo_msg "$1 was set:" + echo " $1" + else + pass + fi +} + +# +# Report the number of tests that succeeded and failed on exit. +# +teardown() { + if [ "$?" != 0 ]; then + trapped_error=true + else + trapped_error=false + fi + + if type cleanup &> /dev/null + then + cleanup + fi + + echo + echo "$success tests succeeded." + echo "$errors tests failed." + + if [ "$trapped_error" = true ]; then + echo "Exited due to an error." + fi + + if [ "$errors" = 0 ] && [ "$trapped_error" = false ]; then + pass + exit 0 + else + fail + exit 1 + fi +} + +trap teardown EXIT diff --git a/share/spack/qa/update-completion-scripts.sh b/share/spack/qa/update-completion-scripts.sh new file mode 100755 index 0000000000..8fcd321457 --- /dev/null +++ b/share/spack/qa/update-completion-scripts.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +# +# Copyright 2013-2020 Lawrence Livermore National Security, LLC and other +# Spack Project Developers. See the top-level COPYRIGHT file for details. +# +# SPDX-License-Identifier: (Apache-2.0 OR MIT) + +# Updates Spack's shell tab completion scripts + +# Switch to parent directory +QA_DIR="$(dirname "${BASH_SOURCE[0]}")" +cd "$QA_DIR/.." + +# Update each shell +for shell in bash # zsh fish +do + header=$shell/spack-completion.in + script=spack-completion.$shell + + rm -f $script + spack commands --aliases --format=$shell --header=$header --update=$script + chmod +x $script +done diff --git a/share/spack/spack-completion.bash b/share/spack/spack-completion.bash index a8dcbff5c0..0284e81113 100755 --- a/share/spack/spack-completion.bash +++ b/share/spack/spack-completion.bash @@ -4,16 +4,41 @@ # SPDX-License-Identifier: (Apache-2.0 OR MIT) -# The following global variables are used/set by Bash programmable completion -# COMP_CWORD: An index into ${COMP_WORDS} of the word containing the -# current cursor position -# COMP_LINE: The current command line -# COMP_WORDS: an array containing individual command arguments typed so far -# COMPREPLY: an array containing possible completions as a result of your -# function +# NOTE: spack-completion.bash is auto-generated by: +# +# $ spack commands --aliases --format=bash +# --header=bash/spack-completion.in --update=spack-completion.bash +# +# Please do not manually modify this file. + + +# The following global variables are set by Bash programmable completion: +# +# COMP_CWORD: An index into ${COMP_WORDS} of the word containing the +# current cursor position +# COMP_KEY: The key (or final key of a key sequence) used to invoke +# the current completion function +# COMP_LINE: The current command line +# COMP_POINT: The index of the current cursor position relative to the +# beginning of the current command +# COMP_TYPE: Set to an integer value corresponding to the type of +# completion attempted that caused a completion function +# to be called +# COMP_WORDBREAKS: The set of characters that the readline library treats +# as word separators when performing word completion +# COMP_WORDS: An array variable consisting of the individual words in +# the current command line +# +# The following global variable is used by Bash programmable completion: +# +# COMPREPLY: An array variable from which bash reads the possible +# completions generated by a shell function invoked by the +# programmable completion facility +# +# See `man bash` for more details. # Bash programmable completion for Spack -_bash_completion_spack () { +_bash_completion_spack() { # In all following examples, let the cursor be denoted by brackets, i.e. [] # For our purposes, flags should not affect tab completion. For instance, @@ -46,7 +71,7 @@ _bash_completion_spack () { # Since we have removed all words after COMP_CWORD, we can safely assume # that COMP_CWORD_NO_FLAGS is simply the index of the last element - local COMP_CWORD_NO_FLAGS=$(( ${#COMP_WORDS_NO_FLAGS[@]} - 1 )) + local COMP_CWORD_NO_FLAGS=$((${#COMP_WORDS_NO_FLAGS[@]} - 1)) # There is no guarantee that the cursor is at the end of the command line # when tab completion is envoked. For example, in the following situation: @@ -59,8 +84,7 @@ _bash_completion_spack () { # which is true if the current word starts with '-' or if the cursor is # not at the end of the line. local list_options=false - if [[ "${COMP_WORDS[$COMP_CWORD]}" == -* || \ - "$COMP_CWORD" -ne "${#COMP_WORDS[@]}-1" ]] + if [[ "${COMP_WORDS[$COMP_CWORD]}" == -* || "$COMP_POINT" -ne "${#COMP_LINE}" ]] then list_options=true fi @@ -80,1266 +104,1488 @@ _bash_completion_spack () { # should list flag completions. local cur=${COMP_WORDS_NO_FLAGS[$COMP_CWORD_NO_FLAGS]} - local prev=${COMP_WORDS_NO_FLAGS[$COMP_CWORD_NO_FLAGS-1]} - #_test_vars + # If the cursor is in the middle of the line, like: + # `spack -d [] install` + # COMP_WORDS will not contain the empty character, so we have to add it. + if [[ "${COMP_LINE:$COMP_POINT:1}" == " " ]] + then + cur="" + fi + + # Uncomment this line to enable logging + #_test_vars >> temp # Make sure function exists before calling it if [[ "$(type -t $subfunction)" == "function" ]] then - COMPREPLY=($($subfunction)) + $subfunction + COMPREPLY=($(compgen -W "$SPACK_COMPREPLY" -- "$cur")) + fi +} + +# Helper functions for subcommands +# Results of each query are cached via environment variables + +_subcommands() { + if [[ -z "${SPACK_SUBCOMMANDS:-}" ]] + then + SPACK_SUBCOMMANDS="$(spack commands)" + fi + SPACK_COMPREPLY="$SPACK_SUBCOMMANDS" +} + +_all_packages() { + if [[ -z "${SPACK_ALL_PACKAGES:-}" ]] + then + SPACK_ALL_PACKAGES="$(spack list)" + fi + SPACK_COMPREPLY="$SPACK_ALL_PACKAGES" +} + +_all_resource_hashes() { + if [[ -z "${SPACK_ALL_RESOURCES_HASHES:-}" ]] + then + SPACK_ALL_RESOURCE_HASHES="$(spack resource list --only-hashes)" + fi + SPACK_COMPREPLY="$SPACK_ALL_RESOURCE_HASHES" +} + +_installed_packages() { + if [[ -z "${SPACK_INSTALLED_PACKAGES:-}" ]] + then + SPACK_INSTALLED_PACKAGES="$(spack --color=never find --no-groups)" + fi + SPACK_COMPREPLY="$SPACK_INSTALLED_PACKAGES" +} + +_installed_compilers() { + if [[ -z "${SPACK_INSTALLED_COMPILERS:-}" ]] + then + SPACK_INSTALLED_COMPILERS="$(spack compilers | egrep -v "^(-|=)")" + fi + SPACK_COMPREPLY="$SPACK_INSTALLED_COMPILERS" +} + +_providers() { + if [[ -z "${SPACK_PROVIDERS:-}" ]] + then + SPACK_PROVIDERS="$(spack providers)" + fi + SPACK_COMPREPLY="$SPACK_PROVIDERS" +} + +_mirrors() { + if [[ -z "${SPACK_MIRRORS:-}" ]] + then + SPACK_MIRRORS="$(spack mirror list | awk '{print $1}')" + fi + SPACK_COMPREPLY="$SPACK_MIRRORS" +} + +_repos() { + if [[ -z "${SPACK_REPOS:-}" ]] + then + SPACK_REPOS="$(spack repo list | awk '{print $1}')" + fi + SPACK_COMPREPLY="$SPACK_REPOS" +} + +_tests() { + if [[ -z "${SPACK_TESTS:-}" ]] + then + SPACK_TESTS="$(spack test -l)" + fi + SPACK_COMPREPLY="$SPACK_TESTS" +} + +_environments() { + if [[ -z "${SPACK_ENVIRONMENTS:-}" ]] + then + SPACK_ENVIRONMENTS="$(spack env list)" + fi + SPACK_COMPREPLY="$SPACK_ENVIRONMENTS" +} + +_keys() { + if [[ -z "${SPACK_KEYS:-}" ]] + then + SPACK_KEYS="$(spack gpg list)" + fi + SPACK_COMPREPLY="$SPACK_KEYS" +} + +_config_sections() { + if [[ -z "${SPACK_CONFIG_SECTIONS:-}" ]] + then + SPACK_CONFIG_SECTIONS="compilers mirrors repos packages modules config upstreams" + fi + SPACK_COMPREPLY="$SPACK_CONFIG_SECTIONS" +} + +_extensions() { + if [[ -z "${SPACK_EXTENSIONS:-}" ]] + then + SPACK_EXTENSIONS="aspell go-bootstrap go icedtea jdk kim-api lua matlab mofem-cephas octave openjdk perl python r ruby rust tcl yorick" + fi + SPACK_COMPREPLY="$SPACK_EXTENSIONS" +} + +# Testing functions + +# Function for unit testing tab completion +# Syntax: _spack_completions spack install py- +_spack_completions() { + local COMP_CWORD COMP_KEY COMP_LINE COMP_POINT COMP_TYPE COMP_WORDS COMPREPLY + + # Set each variable the way bash would + COMP_LINE="$*" + COMP_POINT=${#COMP_LINE} + COMP_WORDS=("$@") + if [[ ${COMP_LINE: -1} == ' ' ]] + then + COMP_WORDS+=('') + fi + COMP_CWORD=$((${#COMP_WORDS[@]} - 1)) + COMP_KEY=9 # ASCII 09: Horizontal Tab + COMP_TYPE=64 # ASCII 64: '@', to list completions if the word is not unmodified + + # Run Spack's tab completion function + _bash_completion_spack + + # Return the result + echo "${COMPREPLY[@]:-}" +} + +# Log the environment variables used +# Syntax: _test_vars >> temp +_test_vars() { + echo "-----------------------------------------------------" + echo "Variables set by bash:" + echo + echo "COMP_LINE: '$COMP_LINE'" + echo "# COMP_LINE: '${#COMP_LINE}'" + echo "COMP_WORDS: $(_pretty_print COMP_WORDS[@])" + echo "# COMP_WORDS: '${#COMP_WORDS[@]}'" + echo "COMP_CWORD: '$COMP_CWORD'" + echo "COMP_KEY: '$COMP_KEY'" + echo "COMP_POINT: '$COMP_POINT'" + echo "COMP_TYPE: '$COMP_TYPE'" + echo "COMP_WORDBREAKS: '$COMP_WORDBREAKS'" + echo + echo "Intermediate variables:" + echo + echo "COMP_WORDS_NO_FLAGS: $(_pretty_print COMP_WORDS_NO_FLAGS[@])" + echo "# COMP_WORDS_NO_FLAGS: '${#COMP_WORDS_NO_FLAGS[@]}'" + echo "COMP_CWORD_NO_FLAGS: '$COMP_CWORD_NO_FLAGS'" + echo + echo "Subfunction: '$subfunction'" + if $list_options + then + echo "List options: 'True'" + else + echo "List options: 'False'" fi + echo "Current word: '$cur'" } +# Pretty-prints one or more arrays +# Syntax: _pretty_print array1[@] ... +_pretty_print() { + for arg in $@ + do + local array=("${!arg}") + printf "$arg: [" + printf "'%s'" "${array[0]}" + printf ", '%s'" "${array[@]:1}" + echo "]" + done +} + +complete -o bashdefault -o default -F _bash_completion_spack spack + # Spack commands +# +# Everything below here is auto-generated. -_spack () { +_spack() { if $list_options then - compgen -W "-h --help -H --all-help --color -C --config-scope -d --debug --timestamp --pdb -e --env -D --env-dir -E --no-env --use-env-repo -k --insecure -l --enable-locks -L --disable-locks -m --mock -p --profile --sorted-profile --lines -v --verbose --stacktrace -V --version --print-shell-vars" -- "$cur" + SPACK_COMPREPLY="-h --help -H --all-help --color -C --config-scope -d --debug --timestamp --pdb -e --env -D --env-dir -E --no-env --use-env-repo -k --insecure -l --enable-locks -L --disable-locks -m --mock -p --profile --sorted-profile --lines -v --verbose --stacktrace -V --version --print-shell-vars" else - compgen -W "$(_subcommands)" -- "$cur" + SPACK_COMPREPLY="activate add arch blame bootstrap build build-env buildcache cd checksum ci clean clone commands compiler compilers concretize config configure create deactivate debug dependencies dependents deprecate dev-build diy docs edit env extensions fetch find flake8 gc gpg graph help info install license list load location log-parse maintainers mirror module patch pkg providers pydoc python reindex remove rm repo resource restage setup spec stage test uninstall unload upload-s3 url verify versions view" fi } -_spack_activate () { +_spack_activate() { if $list_options then - compgen -W "-h --help -f --force -v --view" -- "$cur" + SPACK_COMPREPLY="-h --help -f --force -v --view" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_add () { +_spack_add() { if $list_options then - compgen -W "-h --help -l --list-name" -- "$cur" + SPACK_COMPREPLY="-h --help -l --list-name" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_arch () { - compgen -W "-h --help --known-targets -p --platform -o --operating-system -t --target -f --frontend -b --backend" -- "$cur" +_spack_arch() { + SPACK_COMPREPLY="-h --help --known-targets -p --platform -o --operating-system -t --target -f --frontend -b --backend" } -_spack_blame () { +_spack_blame() { if $list_options then - compgen -W "-h --help -t --time -p --percent -g --git" -- "$cur" + SPACK_COMPREPLY="-h --help -t --time -p --percent -g --git" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_bootstrap () { - compgen -W "-h --help -j --jobs --keep-prefix --keep-stage -n --no-checksum -v --verbose --use-cache --no-cache --cache-only --clean --dirty" -- "$cur" +_spack_bootstrap() { + SPACK_COMPREPLY="-h --help -j --jobs --keep-prefix --keep-stage -n --no-checksum -v --verbose --use-cache --no-cache --cache-only --clean --dirty" } -_spack_build () { +_spack_build() { if $list_options then - compgen -W "-h --help -v --verbose" -- "$cur" + SPACK_COMPREPLY="-h --help -v --verbose" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_build_env () { +_spack_build_env() { if $list_options then - compgen -W "-h --help --clean --dirty --dump --pickle" -- "$cur" + SPACK_COMPREPLY="-h --help --clean --dirty --dump --pickle" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_buildcache () { +_spack_buildcache() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "create install list keys preview check download get-buildcache-name save-yaml copy update-index" -- "$cur" + SPACK_COMPREPLY="create install list keys preview check download get-buildcache-name save-yaml copy update-index" fi } -_spack_buildcache_create () { +_spack_buildcache_create() { if $list_options then - compgen -W "-h --help -r --rel -f --force -u --unsigned -a --allow-root -k --key -d --directory --no-rebuild-index -y --spec-yaml --no-deps" -- "$cur" + SPACK_COMPREPLY="-h --help -r --rel -f --force -u --unsigned -a --allow-root -k --key -d --directory --no-rebuild-index -y --spec-yaml --no-deps" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_buildcache_install () { +_spack_buildcache_install() { if $list_options then - compgen -W "-h --help -f --force -m --multiple -a --allow-root -u --unsigned" -- "$cur" + SPACK_COMPREPLY="-h --help -f --force -m --multiple -a --allow-root -u --unsigned" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_buildcache_list () { +_spack_buildcache_list() { if $list_options then - compgen -W "-h --help -l --long -L --very-long -v --variants -f --force" -- "$cur" + SPACK_COMPREPLY="-h --help -l --long -L --very-long -v --variants -f --force" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_buildcache_keys () { - compgen -W "-h --help -i --install -t --trust -f --force" -- "$cur" +_spack_buildcache_keys() { + SPACK_COMPREPLY="-h --help -i --install -t --trust -f --force" } -_spack_buildcache_preview () { +_spack_buildcache_preview() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_buildcache_check () { - compgen -W "-h --help -m --mirror-url -o --output-file --scope -s --spec -y --spec-yaml --rebuild-on-error" -- "$cur" +_spack_buildcache_check() { + SPACK_COMPREPLY="-h --help -m --mirror-url -o --output-file --scope -s --spec -y --spec-yaml --rebuild-on-error" } -_spack_buildcache_download () { - compgen -W "-h --help -s --spec -y --spec-yaml -p --path -c --require-cdashid" -- "$cur" +_spack_buildcache_download() { + SPACK_COMPREPLY="-h --help -s --spec -y --spec-yaml -p --path -c --require-cdashid" } -_spack_buildcache_get_buildcache_name () { - compgen -W "-h --help -s --spec -y --spec-yaml" -- "$cur" +_spack_buildcache_get_buildcache_name() { + SPACK_COMPREPLY="-h --help -s --spec -y --spec-yaml" } -_spack_buildcache_save_yaml () { - compgen -W "-h --help --root-spec --root-spec-yaml -s --specs -y --yaml-dir" -- "$cur" +_spack_buildcache_save_yaml() { + SPACK_COMPREPLY="-h --help --root-spec --root-spec-yaml -s --specs -y --yaml-dir" } -_spack_buildcache_copy () { - compgen -W "-h --help --base-dir --spec-yaml --destination-url" -- "$cur" +_spack_buildcache_copy() { + SPACK_COMPREPLY="-h --help --base-dir --spec-yaml --destination-url" } -_spack_buildcache_update_index () { - compgen -W "-h --help -d --mirror-url" -- "$cur" +_spack_buildcache_update_index() { + SPACK_COMPREPLY="-h --help -d --mirror-url" } -_spack_cd () { +_spack_cd() { if $list_options then - compgen -W "-h --help -m --module-dir -r --spack-root -i --install-dir -p --package-dir -P --packages -s --stage-dir -S --stages -b --build-dir -e --env" -- "$cur" + SPACK_COMPREPLY="-h --help -m --module-dir -r --spack-root -i --install-dir -p --package-dir -P --packages -s --stage-dir -S --stages -b --build-dir -e --env" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_checksum () { +_spack_checksum() { if $list_options then - compgen -W "-h --help --keep-stage" -- "$cur" + SPACK_COMPREPLY="-h --help --keep-stage" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_clean () { +_spack_ci() { if $list_options then - compgen -W "-h --help -s --stage -d --downloads -m --misc-cache -p --python-cache -a --all" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_all_packages)" -- "$cur" + SPACK_COMPREPLY="start generate pushyaml rebuild" fi } -_spack_clone () { +_spack_ci_start() { + SPACK_COMPREPLY="-h --help --output-file --copy-to --spack-repo --spack-ref --downstream-repo --branch-name --commit-sha" +} + +_spack_ci_generate() { + SPACK_COMPREPLY="-h --help --output-file --copy-to --spack-repo --spack-ref" +} + +_spack_ci_pushyaml() { + SPACK_COMPREPLY="-h --help --downstream-repo --branch-name --commit-sha" +} + +_spack_ci_rebuild() { + SPACK_COMPREPLY="-h --help" +} + +_spack_clean() { if $list_options then - compgen -W "-h --help -r --remote" -- "$cur" + SPACK_COMPREPLY="-h --help -s --stage -d --downloads -m --misc-cache -p --python-cache -a --all" + else + _all_packages fi } -_spack_commands () { +_spack_clone() { if $list_options then - compgen -W "-h --help --format --header --update" -- "$cur" + SPACK_COMPREPLY="-h --help -r --remote" + else + SPACK_COMPREPLY="" fi } -_spack_compiler () { +_spack_commands() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help -a --aliases --format --header --update" else - compgen -W "find add remove rm list info" -- "$cur" + SPACK_COMPREPLY="" fi } -_spack_compiler_find () { +_spack_compiler() { if $list_options then - compgen -W "-h --help --scope" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + SPACK_COMPREPLY="find add remove rm list info" fi } -_spack_compiler_add () { - # Alias to `spack compiler find` - _spack_compiler_find +_spack_compiler_find() { + if $list_options + then + SPACK_COMPREPLY="-h --help --scope" + else + SPACK_COMPREPLY="" + fi } -_spack_compiler_remove () { +_spack_compiler_add() { if $list_options then - compgen -W "-h --help -a --all --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --scope" else - compgen -W "$(_installed_compilers)" -- "$cur" + SPACK_COMPREPLY="" fi } -_spack_compiler_rm () { - # Alias to `spack compiler remove` - _spack_compiler_remove +_spack_compiler_remove() { + if $list_options + then + SPACK_COMPREPLY="-h --help -a --all --scope" + else + _installed_compilers + fi +} + +_spack_compiler_rm() { + if $list_options + then + SPACK_COMPREPLY="-h --help -a --all --scope" + else + _installed_compilers + fi } -_spack_compiler_list () { - compgen -W "-h --help --scope" -- "$cur" +_spack_compiler_list() { + SPACK_COMPREPLY="-h --help --scope" } -_spack_compiler_info () { +_spack_compiler_info() { if $list_options then - compgen -W "-h --help --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --scope" else - compgen -W "$(_installed_compilers)" -- "$cur" + _installed_compilers fi } -_spack_compilers () { - # Alias to `spack compiler list` - _spack_compiler_list +_spack_compilers() { + SPACK_COMPREPLY="-h --help --scope" } -_spack_concretize () { - compgen -W "-h --help -f --force" -- "$cur" +_spack_concretize() { + SPACK_COMPREPLY="-h --help -f --force" } -_spack_config () { +_spack_config() { if $list_options then - compgen -W "-h --help --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --scope" else - compgen -W "get blame edit" -- "$cur" + SPACK_COMPREPLY="get blame edit" fi } -_spack_config_get () { +_spack_config_get() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "compilers mirrors repos packages modules config upstreams" -- "$cur" + _config_sections fi } -_spack_config_blame () { +_spack_config_blame() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "compilers mirrors repos packages modules config upstreams" -- "$cur" + _config_sections fi } -_spack_config_edit () { +_spack_config_edit() { if $list_options then - compgen -W "-h --help --print-file" -- "$cur" + SPACK_COMPREPLY="-h --help --print-file" else - compgen -W "compilers mirrors repos packages modules config upstreams" -- "$cur" + _config_sections fi } -_spack_configure () { +_spack_configure() { if $list_options then - compgen -W "-h --help -v --verbose" -- "$cur" + SPACK_COMPREPLY="-h --help -v --verbose" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_create () { +_spack_create() { if $list_options then - compgen -W "-h --help --keep-stage -n --name -t --template -r --repo -N --namespace -f --force --skip-editor" -- "$cur" + SPACK_COMPREPLY="-h --help --keep-stage -n --name -t --template -r --repo -N --namespace -f --force --skip-editor" + else + SPACK_COMPREPLY="" fi } -_spack_deactivate () { +_spack_deactivate() { if $list_options then - compgen -W "-h --help -f --force -v --view -a --all" -- "$cur" + SPACK_COMPREPLY="-h --help -f --force -v --view -a --all" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_debug () { +_spack_debug() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "create-db-tarball" -- "$cur" + SPACK_COMPREPLY="create-db-tarball" fi } -_spack_debug_create_db_tarball () { - compgen -W "-h --help" -- "$cur" +_spack_debug_create_db_tarball() { + SPACK_COMPREPLY="-h --help" } -_spack_dependencies () { +_spack_dependencies() { if $list_options then - compgen -W "-h --help -i --installed -t --transitive --deptype -V --no-expand-virtuals" -- "$cur" + SPACK_COMPREPLY="-h --help -i --installed -t --transitive --deptype -V --no-expand-virtuals" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_dependents () { +_spack_dependents() { if $list_options then - compgen -W "-h --help -i --installed -t --transitive" -- "$cur" + SPACK_COMPREPLY="-h --help -i --installed -t --transitive" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_deprecate () { +_spack_deprecate() { if $list_options then - compgen -W "-h --help -y --yes-to-all -d --dependencies -D --no-dependencies -i --install-deprecator -I --no-install-deprecator -l --link-type" -- "$cur" + SPACK_COMPREPLY="-h --help -y --yes-to-all -d --dependencies -D --no-dependencies -i --install-deprecator -I --no-install-deprecator -l --link-type" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_dev_build () { +_spack_dev_build() { if $list_options then - compgen -W "-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -u --until --clean --dirty" -- "$cur" + SPACK_COMPREPLY="-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -u --until --clean --dirty" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_diy () { +_spack_diy() { if $list_options then - compgen -W "-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -u --until --clean --dirty" -- "$cur" + SPACK_COMPREPLY="-h --help -j --jobs -d --source-path -i --ignore-dependencies -n --no-checksum --keep-prefix --skip-patch -q --quiet -u --until --clean --dirty" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_docs () { - compgen -W "-h --help" -- "$cur" +_spack_docs() { + SPACK_COMPREPLY="-h --help" } -_spack_edit () { +_spack_edit() { if $list_options then - compgen -W "-h --help -b --build-system -c --command -d --docs -t --test -m --module -r --repo -N --namespace" -- "$cur" + SPACK_COMPREPLY="-h --help -b --build-system -c --command -d --docs -t --test -m --module -r --repo -N --namespace" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_env () { +_spack_env() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "activate deactivate create remove rm list ls status st loads view" -- "$cur" + SPACK_COMPREPLY="activate deactivate create remove rm list ls status st loads view" fi } -_spack_env_activate () { +_spack_env_activate() { if $list_options then - compgen -W "-h --help --sh --csh -v --with-view -V --without-view -d --dir -p --prompt" -- "$cur" + SPACK_COMPREPLY="-h --help --sh --csh -v --with-view -V --without-view -d --dir -p --prompt" else - compgen -W "$(_environments)" -- "$cur" + _environments fi } -_spack_env_deactivate () { - compgen -W "-h --help --sh --csh" -- "$cur" +_spack_env_deactivate() { + SPACK_COMPREPLY="-h --help --sh --csh" } -_spack_env_create () { +_spack_env_create() { if $list_options then - compgen -W "-h --help -d --dir --without-view --with-view" -- "$cur" + SPACK_COMPREPLY="-h --help -d --dir --without-view --with-view" + else + _environments fi } -_spack_env_remove () { +_spack_env_remove() { if $list_options then - compgen -W "-h --help -y --yes-to-all" -- "$cur" + SPACK_COMPREPLY="-h --help -y --yes-to-all" else - compgen -W "$(_environments)" -- "$cur" + _environments fi } -_spack_env_rm () { - # Alias to `spack env remove` - _spack_env_remove +_spack_env_rm() { + if $list_options + then + SPACK_COMPREPLY="-h --help -y --yes-to-all" + else + _environments + fi } -_spack_env_list () { - compgen -W "-h --help" -- "$cur" +_spack_env_list() { + SPACK_COMPREPLY="-h --help" } -_spack_env_ls () { - # Alias to `spack env list` - _spack_env_list +_spack_env_ls() { + SPACK_COMPREPLY="-h --help" } -_spack_env_status () { - compgen -W "-h --help" -- "$cur" +_spack_env_status() { + SPACK_COMPREPLY="-h --help" } -_spack_env_st () { - # Alias to `spack env status` - _spack_env_status +_spack_env_st() { + SPACK_COMPREPLY="-h --help" } -_spack_env_loads () { +_spack_env_loads() { if $list_options then - compgen -W "-h --help -m --module-type --input-only -p --prefix -x --exclude -r --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help -m --module-type --input-only -p --prefix -x --exclude -r --dependencies" else - compgen -W "$(_environments)" -- "$cur" + _environments fi } -_spack_env_view () { +_spack_env_view() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "regenerate enable disable" -- "$cur" + SPACK_COMPREPLY="" fi } -_spack_extensions () { +_spack_extensions() { if $list_options then - compgen -W "-h --help -l --long -L --very-long -d --deps -p --paths -s --show -v --view" -- "$cur" + SPACK_COMPREPLY="-h --help -l --long -L --very-long -d --deps -p --paths -s --show -v --view" else - compgen -W "aspell go-bootstrap go icedtea jdk kim-api lua matlab mofem-cephas octave openjdk perl python r ruby rust tcl yorick" -- "$cur" + _extensions fi } -_spack_fetch () { +_spack_fetch() { if $list_options then - compgen -W "-h --help -n --no-checksum -m --missing -D --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help -n --no-checksum -m --missing -D --dependencies" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_find () { +_spack_find() { if $list_options then - compgen -W "-h --help --format --json -d --deps -p --paths --groups --no-groups -l --long -L --very-long -t --tags -c --show-concretized -f --show-flags --show-full-compiler -x --explicit -X --implicit -u --unknown -m --missing -v --variants -M --only-missing --deprecated --only-deprecated -N --namespace --start-date --end-date" -- "$cur" + SPACK_COMPREPLY="-h --help --format --json -d --deps -p --paths --groups --no-groups -l --long -L --very-long -t --tags -c --show-concretized -f --show-flags --show-full-compiler -x --explicit -X --implicit -u --unknown -m --missing -v --variants -M --only-missing --deprecated --only-deprecated -N --namespace --start-date --end-date" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_flake8 () { +_spack_flake8() { if $list_options then - compgen -W "-h --help -b --base -k --keep-temp -a --all -o --output -r --root-relative -U --no-untracked" -- "$cur" + SPACK_COMPREPLY="-h --help -b --base -k --keep-temp -a --all -o --output -r --root-relative -U --no-untracked" + else + SPACK_COMPREPLY="" fi } -_spack_gpg () { +_spack_gc() { + SPACK_COMPREPLY="-h --help -y --yes-to-all" +} + +_spack_gpg() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "verify trust untrust sign create list init export" -- "$cur" + SPACK_COMPREPLY="verify trust untrust sign create list init export" fi } -_spack_gpg_verify () { +_spack_gpg_verify() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(installed_packages)" -- "$cur" + _installed_packages fi } -_spack_gpg_trust () { +_spack_gpg_trust() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + SPACK_COMPREPLY="" fi } -_spack_gpg_untrust () { +_spack_gpg_untrust() { if $list_options then - compgen -W "-h --help --signing" -- "$cur" + SPACK_COMPREPLY="-h --help --signing" else - compgen -W "$(_keys)" -- "$cur" + _keys fi } -_spack_gpg_sign () { +_spack_gpg_sign() { if $list_options then - compgen -W "-h --help --output --key --clearsign" -- "$cur" + SPACK_COMPREPLY="-h --help --output --key --clearsign" else - compgen -W "$(installed_packages)" -- "$cur" + _installed_packages fi } -_spack_gpg_create () { +_spack_gpg_create() { if $list_options then - compgen -W "-h --help --comment --expires --export" -- "$cur" + SPACK_COMPREPLY="-h --help --comment --expires --export" + else + SPACK_COMPREPLY="" fi } -_spack_gpg_list () { - compgen -W "-h --help --trusted --signing" -- "$cur" +_spack_gpg_list() { + SPACK_COMPREPLY="-h --help --trusted --signing" } -_spack_gpg_init () { - compgen -W "-h --help" -- "$cur" +_spack_gpg_init() { + SPACK_COMPREPLY="-h --help --from" } -_spack_gpg_export () { +_spack_gpg_export() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_keys)" -- "$cur" + _keys fi } -_spack_graph () { +_spack_graph() { if $list_options then - compgen -W "-h --help -a --ascii -d --dot -s --static -i --installed --deptype" -- "$cur" + SPACK_COMPREPLY="-h --help -a --ascii -d --dot -s --static -i --installed --deptype" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_help () { +_spack_help() { if $list_options then - compgen -W "-h --help -a --all --spec" -- "$cur" + SPACK_COMPREPLY="-h --help -a --all --spec" else - compgen -W "$(_subcommands)" -- "$cur" + _subcommands fi } -_spack_info () { +_spack_info() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_install () { +_spack_install() { if $list_options then - compgen -W "-h --help --only -u --until -j --jobs --overwrite --keep-prefix --keep-stage --dont-restage --use-cache --no-cache --cache-only --show-log-on-error --source -n --no-checksum -v --verbose --fake --only-concrete -f --file --clean --dirty --test --run-tests --log-format --log-file --help-cdash -y --yes-to-all --cdash-upload-url --cdash-build --cdash-site --cdash-track --cdash-buildstamp" -- "$cur" + SPACK_COMPREPLY="-h --help --only -u --until -j --jobs --overwrite --keep-prefix --keep-stage --dont-restage --use-cache --no-cache --cache-only --show-log-on-error --source -n --no-checksum -v --verbose --fake --only-concrete -f --file --clean --dirty --test --run-tests --log-format --log-file --help-cdash --cdash-upload-url --cdash-build --cdash-site --cdash-track --cdash-buildstamp -y --yes-to-all" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_license () { +_spack_license() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "list-files verify" -- "$cur" + SPACK_COMPREPLY="list-files verify" fi } -_spack_license_list_files () { - compgen -W "-h --help" -- "$cur" +_spack_license_list_files() { + SPACK_COMPREPLY="-h --help" } -_spack_license_verify () { - compgen -W "-h --help --root" -- "$cur" +_spack_license_verify() { + SPACK_COMPREPLY="-h --help --root" } -_spack_list () { +_spack_list() { if $list_options then - compgen -W "-h --help -d --search-description --format --update -t --tags" -- "$cur" + SPACK_COMPREPLY="-h --help -d --search-description --format --update -t --tags" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_load () { +_spack_load() { if $list_options then - compgen -W "-h --help -r --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help -r --dependencies" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_location () { +_spack_location() { if $list_options then - compgen -W "-h --help -m --module-dir -r --spack-root -i --install-dir -p --package-dir -P --packages -s --stage-dir -S --stages -b --build-dir -e --env" -- "$cur" + SPACK_COMPREPLY="-h --help -m --module-dir -r --spack-root -i --install-dir -p --package-dir -P --packages -s --stage-dir -S --stages -b --build-dir -e --env" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_log_parse () { +_spack_log_parse() { if $list_options then - compgen -W "-h --help --show -c --context -p --profile -w --width -j --jobs" -- "$cur" + SPACK_COMPREPLY="-h --help --show -c --context -p --profile -w --width -j --jobs" + else + SPACK_COMPREPLY="" fi } -_spack_maintainers () { +_spack_maintainers() { if $list_options then - compgen -W "-h --help --maintained --unmaintained -a --all --by-user" -- "$cur" + SPACK_COMPREPLY="-h --help --maintained --unmaintained -a --all --by-user" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_mirror () { +_spack_mirror() { if $list_options then - compgen -W "-h --help -n --no-checksum" -- "$cur" + SPACK_COMPREPLY="-h --help -n --no-checksum" else - compgen -W "create add remove rm set-url list" -- "$cur" + SPACK_COMPREPLY="create add remove rm set-url list" fi } -_spack_mirror_create () { +_spack_mirror_create() { if $list_options then - compgen -W "-h --help -d --directory -a --all -f --file -D --dependencies -n --versions-per-spec" -- "$cur" + SPACK_COMPREPLY="-h --help -d --directory -a --all -f --file -D --dependencies -n --versions-per-spec" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_mirror_add () { +_spack_mirror_add() { if $list_options then - compgen -W "-h --help --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --scope" + else + _mirrors fi } -_spack_mirror_remove () { +_spack_mirror_remove() { if $list_options then - compgen -W "-h --help --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --scope" else - compgen -W "$(_mirrors)" -- "$cur" + _mirrors fi } -_spack_mirror_rm () { - # Alias to `spack mirror remove` - _spack_mirror_remove +_spack_mirror_rm() { + if $list_options + then + SPACK_COMPREPLY="-h --help --scope" + else + _mirrors + fi } -_spack_mirror_set_url () { +_spack_mirror_set_url() { if $list_options then - compgen -W "-h --help --push --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --push --scope" else - compgen -W "$(_mirrors)" -- "$cur" + _mirrors fi } -_spack_mirror_list () { - compgen -W "-h --help --scope" -- "$cur" +_spack_mirror_list() { + SPACK_COMPREPLY="-h --help --scope" } -_spack_module () { +_spack_module() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "lmod tcl" -- "$cur" + SPACK_COMPREPLY="lmod tcl" fi } -_spack_module_lmod () { +_spack_module_lmod() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "refresh find rm loads setdefault" -- "$cur" + SPACK_COMPREPLY="refresh find rm loads setdefault" fi } -_spack_module_lmod_refresh () { +_spack_module_lmod_refresh() { if $list_options then - compgen -W "-h --help --delete-tree --upstream-modules -y --yes-to-all" -- "$cur" + SPACK_COMPREPLY="-h --help --delete-tree --upstream-modules -y --yes-to-all" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_module_lmod_find () { +_spack_module_lmod_find() { if $list_options then - compgen -W "-h --help --full-path -r --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help --full-path -r --dependencies" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_module_lmod_rm () { +_spack_module_lmod_rm() { if $list_options then - compgen -W "-h --help -y --yes-to-all" -- "$cur" + SPACK_COMPREPLY="-h --help -y --yes-to-all" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_module_lmod_loads () { +_spack_module_lmod_loads() { if $list_options then - compgen -W "-h --help --input-only -p --prefix -x --exclude -r --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help --input-only -p --prefix -x --exclude -r --dependencies" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi - } -_spack_module_lmod_setdefault () { +_spack_module_lmod_setdefault() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_module_tcl () { +_spack_module_tcl() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "refresh find rm loads" -- "$cur" + SPACK_COMPREPLY="refresh find rm loads" fi } -_spack_module_tcl_refresh () { +_spack_module_tcl_refresh() { if $list_options then - compgen -W "-h --help --delete-tree --upstream-modules -y --yes-to-all" -- "$cur" + SPACK_COMPREPLY="-h --help --delete-tree --upstream-modules -y --yes-to-all" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_module_tcl_find () { +_spack_module_tcl_find() { if $list_options then - compgen -W "-h --help --full-path -r --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help --full-path -r --dependencies" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_module_tcl_rm () { +_spack_module_tcl_rm() { if $list_options then - compgen -W "-h --help -y --yes-to-all" -- "$cur" + SPACK_COMPREPLY="-h --help -y --yes-to-all" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_module_tcl_loads () { +_spack_module_tcl_loads() { if $list_options then - compgen -W "-h --help --input-only -p --prefix -x --exclude -r --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help --input-only -p --prefix -x --exclude -r --dependencies" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_patch () { +_spack_patch() { if $list_options then - compgen -W "-h --help -n --no-checksum" -- "$cur" + SPACK_COMPREPLY="-h --help -n --no-checksum" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_pkg () { +_spack_pkg() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "add list diff added changed removed" -- "$cur" + SPACK_COMPREPLY="add list diff added changed removed" fi } -_spack_pkg_add () { +_spack_pkg_add() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_pkg_list () { - # FIXME: How to list git revisions? +_spack_pkg_list() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + SPACK_COMPREPLY="" fi } -_spack_pkg_diff () { - # FIXME: How to list git revisions? +_spack_pkg_diff() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + SPACK_COMPREPLY="" fi } -_spack_pkg_added () { - # FIXME: How to list git revisions? +_spack_pkg_added() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + SPACK_COMPREPLY="" fi } -_spack_pkg_changed () { - # FIXME: How to list git revisions? +_spack_pkg_changed() { if $list_options then - compgen -W "-h --help -t --type" -- "$cur" + SPACK_COMPREPLY="-h --help -t --type" + else + SPACK_COMPREPLY="" fi } -_spack_pkg_removed () { - # FIXME: How to list git revisions? +_spack_pkg_removed() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + SPACK_COMPREPLY="" fi } -_spack_providers () { +_spack_providers() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_providers)" -- "$cur" + _providers fi } -_spack_pydoc () { +_spack_pydoc() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + SPACK_COMPREPLY="" fi } -_spack_python () { +_spack_python() { if $list_options then - compgen -W "-h --help -c" -- "$cur" + SPACK_COMPREPLY="-h --help -c" + else + SPACK_COMPREPLY="" fi } -_spack_reindex () { - compgen -W "-h --help" -- "$cur" +_spack_reindex() { + SPACK_COMPREPLY="-h --help" } -_spack_release_jobs () { - compgen -W "-h --help -o --output-file -p --print-summary --cdash-credentials" -- "$cur" +_spack_remove() { + if $list_options + then + SPACK_COMPREPLY="-h --help -a --all -l --list-name -f --force" + else + _all_packages + fi } -_spack_remove () { +_spack_rm() { if $list_options then - compgen -W "-h --help -a --all -l --list-name -f --force" -- "$cur" + SPACK_COMPREPLY="-h --help -a --all -l --list-name -f --force" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_repo () { +_spack_repo() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "create list add remove rm" -- "$cur" + SPACK_COMPREPLY="create list add remove rm" fi } -_spack_repo_create () { +_spack_repo_create() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" + else + _repos fi } -_spack_repo_list () { - compgen -W "-h --help --scope" -- "$cur" +_spack_repo_list() { + SPACK_COMPREPLY="-h --help --scope" } -_spack_repo_add () { +_spack_repo_add() { if $list_options then - compgen -W "-h --help --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --scope" + else + SPACK_COMPREPLY="" fi } -_spack_repo_remove () { +_spack_repo_remove() { if $list_options then - compgen -W "-h --help --scope" -- "$cur" + SPACK_COMPREPLY="-h --help --scope" else - compgen -W "$(_repos)" -- "$cur" + _repos fi } -_spack_repo_rm () { - # Alias to `spack repo remove` - _spack_repo_remove +_spack_repo_rm() { + if $list_options + then + SPACK_COMPREPLY="-h --help --scope" + else + _repos + fi } -_spack_resource () { +_spack_resource() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "list show" -- "$cur" + SPACK_COMPREPLY="list show" fi } -_spack_resource_list () { - compgen -W "-h --help --only-hashes" -- "$cur" +_spack_resource_list() { + SPACK_COMPREPLY="-h --help --only-hashes" } -_spack_resource_show () { +_spack_resource_show() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_all_resource_hashes)" -- "$cur" + _all_resource_hashes fi } -_spack_restage () { +_spack_restage() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_setup () { +_spack_setup() { if $list_options then - compgen -W "-h --help -i --ignore-dependencies -n --no-checksum -v --verbose --clean --dirty" -- "$cur" + SPACK_COMPREPLY="-h --help -i --ignore-dependencies -n --no-checksum -v --verbose --clean --dirty" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_spec () { +_spack_spec() { if $list_options then - compgen -W "-h --help -l --long -L --very-long -I --install-status -y --yaml -j --json -c --cover -N --namespaces -t --types" -- "$cur" + SPACK_COMPREPLY="-h --help -l --long -L --very-long -I --install-status -y --yaml -j --json -c --cover -N --namespaces -t --types" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_stage () { +_spack_stage() { if $list_options then - compgen -W "-h --help -n --no-checksum -p --path" -- "$cur" + SPACK_COMPREPLY="-h --help -n --no-checksum -p --path" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_test () { +_spack_test() { if $list_options then - compgen -W "-h --help -H --pytest-help --extension -l --list -L --list-long -N --list-names -s -k --showlocals" -- "$cur" + SPACK_COMPREPLY="-h --help -H --pytest-help -l --list -L --list-long -N --list-names --extension -s -k --showlocals" else - compgen -W "$(_tests)" -- "$cur" + _tests fi } -_spack_uninstall () { +_spack_uninstall() { if $list_options then - compgen -W "-h --help -f --force -R --dependents -y --yes-to-all -a --all" -- "$cur" + SPACK_COMPREPLY="-h --help -f --force -R --dependents -y --yes-to-all -a --all" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_unload () { +_spack_unload() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "$(_installed_packages)" -- "$cur" + _installed_packages fi } -_spack_upload_s3 () { +_spack_upload_s3() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "spec index" -- "$cur" + SPACK_COMPREPLY="spec index" fi } -_spack_upload_s3_spec () { - compgen -W "-h --help -s --spec -y --spec-yaml -b --base-dir -e --endpoint-url" -- "$cur" +_spack_upload_s3_spec() { + SPACK_COMPREPLY="-h --help -s --spec -y --spec-yaml -b --base-dir -e --endpoint-url" } -_spack_upload_s3_index () { - compgen -W "-h --help -e --endpoint-url" -- "$cur" +_spack_upload_s3_index() { + SPACK_COMPREPLY="-h --help -e --endpoint-url" } -_spack_url () { +_spack_url() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help" else - compgen -W "parse list summary stats" -- "$cur" + SPACK_COMPREPLY="parse list summary stats" fi } -_spack_url_parse () { +_spack_url_parse() { if $list_options then - compgen -W "-h --help -s --spider" -- "$cur" + SPACK_COMPREPLY="-h --help -s --spider" + else + SPACK_COMPREPLY="" fi } -_spack_url_list () { - compgen -W "-h --help -c --color -e --extrapolation -n --incorrect-name -N --correct-name -v --incorrect-version -V --correct-version" -- "$cur" +_spack_url_list() { + SPACK_COMPREPLY="-h --help -c --color -e --extrapolation -n --incorrect-name -N --correct-name -v --incorrect-version -V --correct-version" } -_spack_url_summary () { - compgen -W "-h --help" -- "$cur" +_spack_url_summary() { + SPACK_COMPREPLY="-h --help" } -_spack_url_stats () { - compgen -W "-h --help" -- "$cur" +_spack_url_stats() { + SPACK_COMPREPLY="-h --help" } -_spack_verify () { +_spack_verify() { if $list_options then - compgen -W "-h --help -l --local -j --json -a --all -s --specs -f --files" -- "$cur" + SPACK_COMPREPLY="-h --help -l --local -j --json -a --all -s --specs -f --files" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_versions () { +_spack_versions() { if $list_options then - compgen -W "-h --help -s --safe-only" -- "$cur" + SPACK_COMPREPLY="-h --help -s --safe-only" else - compgen -W "$(_all_packages)" -- "$cur" + _all_packages fi } -_spack_view () { +_spack_view() { if $list_options then - compgen -W "-h --help -v --verbose -e --exclude -d --dependencies" -- "$cur" + SPACK_COMPREPLY="-h --help -v --verbose -e --exclude -d --dependencies" else - compgen -W "symlink add soft hardlink hard remove rm statlink status check" -- "$cur" + SPACK_COMPREPLY="symlink add soft hardlink hard remove rm statlink status check" fi } -_spack_view_symlink () { +_spack_view_symlink() { if $list_options then - compgen -W "-h --help --projection-file -i --ignore-conflicts" -- "$cur" + SPACK_COMPREPLY="-h --help --projection-file -i --ignore-conflicts" + else + _all_packages fi } -_spack_view_add () { - # Alias for `spack view symlink` - _spack_view_symlink -} - -_spack_view_soft () { - # Alias for `spack view symlink` - _spack_view_symlink -} - -_spack_view_hardlink () { +_spack_view_add() { if $list_options then - compgen -W "-h --help --projection-file -i --ignore-conflicts" -- "$cur" + SPACK_COMPREPLY="-h --help --projection-file -i --ignore-conflicts" + else + _all_packages fi } -_spack_view_hard () { - # Alias for `spack view hardlink` - _spack_view_hardlink -} - -_spack_view_remove () { +_spack_view_soft() { if $list_options then - compgen -W "-h --help --no-remove-dependents -a --all" -- "$cur" + SPACK_COMPREPLY="-h --help --projection-file -i --ignore-conflicts" + else + _all_packages fi } -_spack_view_rm () { - # Alias for `spack view remove` - _spack_view_remove -} - -_spack_view_statlink () { +_spack_view_hardlink() { if $list_options then - compgen -W "-h --help" -- "$cur" + SPACK_COMPREPLY="-h --help --projection-file -i --ignore-conflicts" + else + _all_packages fi } -_spack_view_status () { - # Alias for `spack view statlink` - _spack_view_statlink -} - -_spack_view_check () { - # Alias for `spack view statlink` - _spack_view_statlink -} - -# Helper functions for subcommands - -_subcommands () { - spack commands -} - -_all_packages () { - spack list -} - -_all_resource_hashes () { - spack resource list --only-hashes -} - -_installed_packages () { - spack --color=never find --no-groups -} - -_installed_compilers () { - spack compilers | egrep -v "^(-|=)" -} - -_providers () { - spack providers -} - -_mirrors () { - spack mirror list | awk '{print $1}' -} - -_repos () { - spack repo list | awk '{print $1}' +_spack_view_hard() { + if $list_options + then + SPACK_COMPREPLY="-h --help --projection-file -i --ignore-conflicts" + else + _all_packages + fi } -_tests () { - spack test -l +_spack_view_remove() { + if $list_options + then + SPACK_COMPREPLY="-h --help --no-remove-dependents -a --all" + else + _all_packages + fi } -_environments () { - spack env list +_spack_view_rm() { + if $list_options + then + SPACK_COMPREPLY="-h --help --no-remove-dependents -a --all" + else + _all_packages + fi } -_keys () { - spack gpg list +_spack_view_statlink() { + if $list_options + then + SPACK_COMPREPLY="-h --help" + else + _all_packages + fi } -# Testing functions - -_test_vars () { - echo "-----------------------------------------------------" >> temp - echo "Full line: '$COMP_LINE'" >> temp - echo >> temp - echo "Word list w/ flags: $(_pretty_print COMP_WORDS[@])" >> temp - echo "# words w/ flags: '${#COMP_WORDS[@]}'" >> temp - echo "Cursor index w/ flags: '$COMP_CWORD'" >> temp - echo >> temp - echo "Word list w/out flags: $(_pretty_print COMP_WORDS_NO_FLAGS[@])" >> temp - echo "# words w/out flags: '${#COMP_WORDS_NO_FLAGS[@]}'" >> temp - echo "Cursor index w/out flags: '$COMP_CWORD_NO_FLAGS'" >> temp - echo >> temp - echo "Subfunction: '$subfunction'" >> temp +_spack_view_status() { if $list_options then - echo "List options: 'True'" >> temp + SPACK_COMPREPLY="-h --help" else - echo "List options: 'False'" >> temp + _all_packages fi - echo "Current word: '$cur'" >> temp - echo "Previous word: '$prev'" >> temp } -# Pretty-prints one or more arrays -# Syntax: _pretty_print array1[@] ... -_pretty_print () { - for arg in $@ - do - local array=("${!arg}") - echo -n "$arg: [" - printf "'%s'" "${array[0]}" - printf ", '%s'" "${array[@]:1}" - echo "]" - done +_spack_view_check() { + if $list_options + then + SPACK_COMPREPLY="-h --help" + else + _all_packages + fi } - -complete -o default -F _bash_completion_spack spack |