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>
This commit is contained in:
Adam J. Stewart
2020-01-05 23:35:23 -08:00
committed by Todd Gamblin
parent 8011fedd9c
commit 11f2b61261
52 changed files with 2860 additions and 1785 deletions

View File

@@ -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.

View File

@@ -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

View File

@@ -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"

View File

@@ -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

195
share/spack/qa/test-framework.sh Executable file
View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff