summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.codecov.yml1
-rw-r--r--.coveragerc1
-rw-r--r--lib/spack/llnl/util/argparsewriter.py415
-rw-r--r--lib/spack/spack/cmd/activate.py7
-rw-r--r--lib/spack/spack/cmd/add.py6
-rw-r--r--lib/spack/spack/cmd/blame.py8
-rw-r--r--lib/spack/spack/cmd/build_env.py2
-rw-r--r--lib/spack/spack/cmd/buildcache.py32
-rw-r--r--lib/spack/spack/cmd/checksum.py5
-rw-r--r--lib/spack/spack/cmd/clean.py7
-rw-r--r--lib/spack/spack/cmd/commands.py125
-rw-r--r--lib/spack/spack/cmd/common/arguments.py46
-rw-r--r--lib/spack/spack/cmd/config.py6
-rw-r--r--lib/spack/spack/cmd/configure.py13
-rw-r--r--lib/spack/spack/cmd/deactivate.py6
-rw-r--r--lib/spack/spack/cmd/dependencies.py5
-rw-r--r--lib/spack/spack/cmd/dependents.py8
-rw-r--r--lib/spack/spack/cmd/dev_build.py7
-rw-r--r--lib/spack/spack/cmd/edit.py5
-rw-r--r--lib/spack/spack/cmd/env.py4
-rw-r--r--lib/spack/spack/cmd/extensions.py2
-rw-r--r--lib/spack/spack/cmd/fetch.py12
-rw-r--r--lib/spack/spack/cmd/gpg.py15
-rw-r--r--lib/spack/spack/cmd/graph.py7
-rw-r--r--lib/spack/spack/cmd/info.py6
-rw-r--r--lib/spack/spack/cmd/install.py13
-rw-r--r--lib/spack/spack/cmd/load.py8
-rw-r--r--lib/spack/spack/cmd/location.py6
-rw-r--r--lib/spack/spack/cmd/maintainers.py14
-rw-r--r--lib/spack/spack/cmd/mirror.py14
-rw-r--r--lib/spack/spack/cmd/patch.py13
-rw-r--r--lib/spack/spack/cmd/pkg.py5
-rw-r--r--lib/spack/spack/cmd/remove.py6
-rw-r--r--lib/spack/spack/cmd/repo.py12
-rw-r--r--lib/spack/spack/cmd/restage.py10
-rw-r--r--lib/spack/spack/cmd/setup.py5
-rw-r--r--lib/spack/spack/cmd/spec.py4
-rw-r--r--lib/spack/spack/cmd/stage.py7
-rw-r--r--lib/spack/spack/cmd/uninstall.py18
-rw-r--r--lib/spack/spack/cmd/unload.py7
-rw-r--r--lib/spack/spack/cmd/verify.py12
-rw-r--r--lib/spack/spack/cmd/versions.py7
-rw-r--r--lib/spack/spack/reporters/cdash.py4
-rw-r--r--lib/spack/spack/test/cmd/commands.py170
-rw-r--r--lib/spack/spack/test/llnl/util/argparsewriter.py37
-rwxr-xr-xshare/spack/bash/spack-completion.in309
-rwxr-xr-xshare/spack/qa/completion-test.sh89
-rwxr-xr-xshare/spack/qa/run-unit-tests17
-rwxr-xr-xshare/spack/qa/setup-env-test.sh195
-rwxr-xr-xshare/spack/qa/test-framework.sh195
-rwxr-xr-xshare/spack/qa/update-completion-scripts.sh23
-rwxr-xr-xshare/spack/spack-completion.bash1284
52 files changed, 2155 insertions, 1080 deletions
diff --git a/.codecov.yml b/.codecov.yml
index e45c500b76..a70b19c39c 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -12,6 +12,5 @@ ignore:
- lib/spack/docs/.*
- lib/spack/external/.*
- share/spack/qa/.*
- - share/spack/spack-completion.bash
comment: off
diff --git a/.coveragerc b/.coveragerc
index c0c5f76688..7292badff5 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -9,6 +9,7 @@ omit =
lib/spack/spack/test/*
lib/spack/docs/*
lib/spack/external/*
+ share/spack/qa/*
[report]
# Regexes for lines to exclude from consideration
diff --git a/lib/spack/llnl/util/argparsewriter.py b/lib/spack/llnl/util/argparsewriter.py
index ec6ea30df9..f43595145e 100644
--- a/lib/spack/llnl/util/argparsewriter.py
+++ b/lib/spack/llnl/util/argparsewriter.py
@@ -4,201 +4,376 @@
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
from __future__ import print_function
+
import re
import argparse
import errno
import sys
-
+from six import StringIO
+
+
+class Command(object):
+ """Parsed representation of a command from argparse.
+
+ This is a single command from an argparse parser. ``ArgparseWriter``
+ creates these and returns them from ``parse()``, and it passes one of
+ these to each call to ``format()`` so that we can take an action for
+ a single command.
+
+ Parts of a Command:
+ - prog: command name (str)
+ - description: command description (str)
+ - usage: command usage (str)
+ - positionals: list of positional arguments (list)
+ - optionals: list of optional arguments (list)
+ - subcommands: list of subcommand parsers (list)
+ """
+ def __init__(self, prog, description, usage,
+ positionals, optionals, subcommands):
+ self.prog = prog
+ self.description = description
+ self.usage = usage
+ self.positionals = positionals
+ self.optionals = optionals
+ self.subcommands = subcommands
+
+
+# NOTE: The only reason we subclass argparse.HelpFormatter is to get access
+# to self._expand_help(), ArgparseWriter is not intended to be used as a
+# formatter_class.
class ArgparseWriter(argparse.HelpFormatter):
"""Analyzes an argparse ArgumentParser for easy generation of help."""
- def __init__(self, out=sys.stdout):
- super(ArgparseWriter, self).__init__(out)
+
+ def __init__(self, prog, out=sys.stdout, aliases=False):
+ """Initializes a new ArgparseWriter instance.
+
+ Parameters:
+ prog (str): the program name
+ out (file object): the file to write to
+ aliases (bool): whether or not to include subparsers for aliases
+ """
+ super(ArgparseWriter, self).__init__(prog)
self.level = 0
+ self.prog = prog
self.out = out
+ self.aliases = aliases
+
+ def parse(self, parser, prog):
+ """Parses the parser object and returns the relavent components.
- def _write(self, parser, root=True, level=0):
+ Parameters:
+ parser (argparse.ArgumentParser): the parser
+ prog (str): the command name
+
+ Returns:
+ (Command) information about the command from the parser
+ """
self.parser = parser
- self.level = level
- actions = parser._actions
- # allow root level to be flattened with rest of commands
- if type(root) == int:
- self.level = root
- root = True
+ split_prog = parser.prog.split(' ')
+ split_prog[-1] = prog
+ prog = ' '.join(split_prog)
+ description = parser.description
+
+ fmt = parser._get_formatter()
+ actions = parser._actions
+ groups = parser._mutually_exclusive_groups
+ usage = fmt._format_usage(None, actions, groups, '').strip()
- # go through actions and split them into optionals, positionals,
+ # Go through actions and split them into optionals, positionals,
# and subcommands
optionals = []
positionals = []
subcommands = []
for action in actions:
if action.option_strings:
- optionals.append(action)
+ flags = action.option_strings
+ dest_flags = fmt._format_action_invocation(action)
+ help = self._expand_help(action) if action.help else ''
+ help = help.replace('\n', ' ')
+ optionals.append((flags, dest_flags, help))
elif isinstance(action, argparse._SubParsersAction):
for subaction in action._choices_actions:
subparser = action._name_parser_map[subaction.dest]
- subcommands.append(subparser)
+ subcommands.append((subparser, subaction.dest))
+
+ # Look for aliases of the form 'name (alias, ...)'
+ if self.aliases:
+ match = re.match(r'(.*) \((.*)\)', subaction.metavar)
+ if match:
+ aliases = match.group(2).split(', ')
+ for alias in aliases:
+ subparser = action._name_parser_map[alias]
+ subcommands.append((subparser, alias))
else:
- positionals.append(action)
+ args = fmt._format_action_invocation(action)
+ help = self._expand_help(action) if action.help else ''
+ help = help.replace('\n', ' ')
+ positionals.append((args, help))
- groups = parser._mutually_exclusive_groups
- fmt = parser._get_formatter()
- description = parser.description
+ return Command(
+ prog, description, usage, positionals, optionals, subcommands)
- def action_group(function, actions):
- for action in actions:
- arg = fmt._format_action_invocation(action)
- help = self._expand_help(action) if action.help else ''
- function(arg, re.sub('\n', ' ', help))
+ def format(self, cmd):
+ """Returns the string representation of a single node in the
+ parser tree.
- if root:
- self.begin_command(parser.prog)
+ Override this in subclasses to define how each subcommand
+ should be displayed.
- if description:
- self.description(parser.description)
+ Parameters:
+ (Command): parsed information about a command or subcommand
- usage = fmt._format_usage(None, actions, groups, '').strip()
- self.usage(usage)
+ Returns:
+ str: the string representation of this subcommand
+ """
+ raise NotImplementedError
- if positionals:
- self.begin_positionals()
- action_group(self.positional, positionals)
- self.end_positionals()
+ def _write(self, parser, prog, level=0):
+ """Recursively writes a parser.
- if optionals:
- self.begin_optionals()
- action_group(self.optional, optionals)
- self.end_optionals()
+ Parameters:
+ parser (argparse.ArgumentParser): the parser
+ prog (str): the command name
+ level (int): the current level
+ """
+ self.level = level
- if subcommands:
- self.begin_subcommands(subcommands)
- for subparser in subcommands:
- self._write(subparser, root=True, level=level + 1)
- self.end_subcommands(subcommands)
+ cmd = self.parse(parser, prog)
+ self.out.write(self.format(cmd))
- if root:
- self.end_command(parser.prog)
+ for subparser, prog in cmd.subcommands:
+ self._write(subparser, prog, level=level + 1)
- def write(self, parser, root=True):
+ def write(self, parser):
"""Write out details about an ArgumentParser.
Args:
- parser (ArgumentParser): an ``argparse`` parser
- root (bool or int): if bool, whether to include the root parser;
- or ``1`` to flatten the root parser with first-level
- subcommands
+ parser (argparse.ArgumentParser): the parser
"""
try:
- self._write(parser, root, level=0)
+ self._write(parser, self.prog)
except IOError as e:
- # swallow pipe errors
+ # Swallow pipe errors
+ # Raises IOError in Python 2 and BrokenPipeError in Python 3
if e.errno != errno.EPIPE:
raise
+
+_rst_levels = ['=', '-', '^', '~', ':', '`']
+
+
+class ArgparseRstWriter(ArgparseWriter):
+ """Write argparse output as rst sections."""
+
+ def __init__(self, prog, out=sys.stdout, aliases=False,
+ rst_levels=_rst_levels):
+ """Create a new ArgparseRstWriter.
+
+ Parameters:
+ prog (str): program name
+ out (file object): file to write to
+ aliases (bool): whether or not to include subparsers for aliases
+ rst_levels (list of str): list of characters
+ for rst section headings
+ """
+ super(ArgparseRstWriter, self).__init__(prog, out, aliases)
+ self.rst_levels = rst_levels
+
+ def format(self, cmd):
+ string = StringIO()
+ string.write(self.begin_command(cmd.prog))
+
+ if cmd.description:
+ string.write(self.description(cmd.description))
+
+ string.write(self.usage(cmd.usage))
+
+ if cmd.positionals:
+ string.write(self.begin_positionals())
+ for args, help in cmd.positionals:
+ string.write(self.positional(args, help))
+ string.write(self.end_positionals())
+
+ if cmd.optionals:
+ string.write(self.begin_optionals())
+ for flags, dest_flags, help in cmd.optionals:
+ string.write(self.optional(dest_flags, help))
+ string.write(self.end_optionals())
+
+ if cmd.subcommands:
+ string.write(self.begin_subcommands(cmd.subcommands))
+
+ return string.getvalue()
+
def begin_command(self, prog):
- pass
+ return """
+----
+
+.. _{0}:
- def end_command(self, prog):
- pass
+{1}
+{2}
+
+""".format(prog.replace(' ', '-'), prog,
+ self.rst_levels[self.level] * len(prog))
def description(self, description):
- pass
+ return description + '\n\n'
def usage(self, usage):
- pass
+ return """\
+.. code-block:: console
+
+ {0}
+
+""".format(usage)
def begin_positionals(self):
- pass
+ return '\n**Positional arguments**\n\n'
def positional(self, name, help):
- pass
+ return """\
+{0}
+ {1}
+
+""".format(name, help)
def end_positionals(self):
- pass
+ return ''
def begin_optionals(self):
- pass
+ return '\n**Optional arguments**\n\n'
+
+ def optional(self, opts, help):
+ return """\
+``{0}``
+ {1}
- def optional(self, option, help):
- pass
+""".format(opts, help)
def end_optionals(self):
- pass
+ return ''
def begin_subcommands(self, subcommands):
- pass
+ string = """
+**Subcommands**
- def end_subcommands(self, subcommands):
- pass
+.. hlist::
+ :columns: 4
+"""
-_rst_levels = ['=', '-', '^', '~', ':', '`']
+ for cmd, _ in subcommands:
+ prog = re.sub(r'^[^ ]* ', '', cmd.prog)
+ string += ' * :ref:`{0} <{1}>`\n'.format(
+ prog, cmd.prog.replace(' ', '-'))
+ return string + '\n'
-class ArgparseRstWriter(ArgparseWriter):
- """Write argparse output as rst sections."""
- def __init__(self, out=sys.stdout, rst_levels=_rst_levels,
- strip_root_prog=True):
- """Create a new ArgparseRstWriter.
+class ArgparseCompletionWriter(ArgparseWriter):
+ """Write argparse output as shell programmable tab completion functions."""
- Args:
- out (file object): file to write to
- rst_levels (list of str): list of characters
- for rst section headings
- strip_root_prog (bool): if ``True``, strip the base command name
- from subcommands in output
+ def format(self, cmd):
+ """Returns the string representation of a single node in the
+ parser tree.
+
+ Override this in subclasses to define how each subcommand
+ should be displayed.
+
+ Parameters:
+ (Command): parsed information about a command or subcommand
+
+ Returns:
+ str: the string representation of this subcommand
"""
- super(ArgparseRstWriter, self).__init__(out)
- self.rst_levels = rst_levels
- self.strip_root_prog = strip_root_prog
- def line(self, string=''):
- self.out.write('%s\n' % string)
+ assert cmd.optionals # we should always at least have -h, --help
+ assert not (cmd.positionals and cmd.subcommands) # one or the other
- def begin_command(self, prog):
- self.line()
- self.line('----')
- self.line()
- self.line('.. _%s:\n' % prog.replace(' ', '-'))
- self.line('%s' % prog)
- self.line(self.rst_levels[self.level] * len(prog) + '\n')
+ # We only care about the arguments/flags, not the help messages
+ positionals = []
+ if cmd.positionals:
+ positionals, _ = zip(*cmd.positionals)
+ optionals, _, _ = zip(*cmd.optionals)
+ subcommands = []
+ if cmd.subcommands:
+ _, subcommands = zip(*cmd.subcommands)
- def description(self, description):
- self.line('%s\n' % description)
+ # Flatten lists of lists
+ optionals = [x for xx in optionals for x in xx]
- def usage(self, usage):
- self.line('.. code-block:: console\n')
- self.line(' %s\n' % usage)
+ return (self.start_function(cmd.prog) +
+ self.body(positionals, optionals, subcommands) +
+ self.end_function(cmd.prog))
- def begin_positionals(self):
- self.line()
- self.line('**Positional arguments**\n')
+ def start_function(self, prog):
+ """Returns the syntax needed to begin a function definition.
- def positional(self, name, help):
- self.line(name)
- self.line(' %s\n' % help)
+ Parameters:
+ prog (str): the command name
- def begin_optionals(self):
- self.line()
- self.line('**Optional arguments**\n')
+ Returns:
+ str: the function definition beginning
+ """
+ name = prog.replace('-', '_').replace(' ', '_')
+ return '\n_{0}() {{'.format(name)
- def optional(self, opts, help):
- self.line('``%s``' % opts)
- self.line(' %s\n' % help)
+ def end_function(self, prog=None):
+ """Returns the syntax needed to end a function definition.
- def begin_subcommands(self, subcommands):
- self.line()
- self.line('**Subcommands**\n')
- self.line('.. hlist::')
- self.line(' :columns: 4\n')
-
- for cmd in subcommands:
- prog = cmd.prog
- if self.strip_root_prog:
- prog = re.sub(r'^[^ ]* ', '', prog)
-
- self.line(' * :ref:`%s <%s>`'
- % (prog, cmd.prog.replace(' ', '-')))
- self.line()
+ Parameters:
+ prog (str, optional): the command name
+
+ Returns:
+ str: the function definition ending
+ """
+ return '}\n'
+
+ def body(self, positionals, optionals, subcommands):
+ """Returns the body of the function.
+
+ Parameters:
+ positionals (list): list of positional arguments
+ optionals (list): list of optional arguments
+ subcommands (list): list of subcommand parsers
+
+ Returns:
+ str: the function body
+ """
+ return ''
+
+ def positionals(self, positionals):
+ """Returns the syntax for reporting positional arguments.
+
+ Parameters:
+ positionals (list): list of positional arguments
+
+ Returns:
+ str: the syntax for positional arguments
+ """
+ return ''
+
+ def optionals(self, optionals):
+ """Returns the syntax for reporting optional flags.
+
+ Parameters:
+ optionals (list): list of optional arguments
+
+ Returns:
+ str: the syntax for optional flags
+ """
+ return ''
+
+ def subcommands(self, subcommands):
+ """Returns the syntax for reporting subcommands.
+
+ Parameters:
+ subcommands (list): list of subcommand parsers
+
+ Returns:
+ str: the syntax for subcommand parsers
+ """
+ return ''
diff --git a/lib/spack/spack/cmd/activate.py b/lib/spack/spack/cmd/activate.py
index 718d30ce07..bfca9f5604 100644
--- a/lib/spack/spack/cmd/activate.py
+++ b/lib/spack/spack/cmd/activate.py
@@ -3,11 +3,10 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.environment as ev
from spack.filesystem_view import YamlFilesystemView
@@ -23,9 +22,7 @@ def setup_parser(subparser):
subparser.add_argument(
'-v', '--view', metavar='VIEW', type=str,
help="the view to operate on")
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER,
- help="spec of package extension to activate")
+ arguments.add_common_arguments(subparser, ['installed_spec'])
def activate(parser, args):
diff --git a/lib/spack/spack/cmd/add.py b/lib/spack/spack/cmd/add.py
index efae7ffeb7..e08c2c5aac 100644
--- a/lib/spack/spack/cmd/add.py
+++ b/lib/spack/spack/cmd/add.py
@@ -3,11 +3,10 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.environment as ev
@@ -20,8 +19,7 @@ def setup_parser(subparser):
subparser.add_argument('-l', '--list-name',
dest='list_name', default='specs',
help="name of the list to add specs to")
- subparser.add_argument(
- 'specs', nargs=argparse.REMAINDER, help="specs of packages to add")
+ arguments.add_common_arguments(subparser, ['specs'])
def add(parser, args):
diff --git a/lib/spack/spack/cmd/blame.py b/lib/spack/spack/cmd/blame.py
index ea1a310476..b806058aec 100644
--- a/lib/spack/spack/cmd/blame.py
+++ b/lib/spack/spack/cmd/blame.py
@@ -35,7 +35,7 @@ def setup_parser(subparser):
help='show git blame output instead of summary')
subparser.add_argument(
- 'package_name', help='name of package to show contributions for, '
+ 'package_or_file', help='name of package to show contributions for, '
'or path to a file in the spack repo')
@@ -47,13 +47,13 @@ def blame(parser, args):
# Get name of file to blame
blame_file = None
- if os.path.isfile(args.package_name):
- path = os.path.realpath(args.package_name)
+ if os.path.isfile(args.package_or_file):
+ path = os.path.realpath(args.package_or_file)
if path.startswith(spack.paths.prefix):
blame_file = path
if not blame_file:
- pkg = spack.repo.get(args.package_name)
+ pkg = spack.repo.get(args.package_or_file)
blame_file = pkg.module.__file__.rstrip('c') # .pyc -> .py
# get git blame for the package
diff --git a/lib/spack/spack/cmd/build_env.py b/lib/spack/spack/cmd/build_env.py
index 7f9f08c01f..128d167a29 100644
--- a/lib/spack/spack/cmd/build_env.py
+++ b/lib/spack/spack/cmd/build_env.py
@@ -33,7 +33,7 @@ def setup_parser(subparser):
subparser.add_argument(
'spec', nargs=argparse.REMAINDER,
metavar='spec [--] [cmd]...',
- help="specs of package environment to emulate")
+ help="spec of package environment to emulate")
subparser.epilog\
= 'If a command is not specified, the environment will be printed ' \
'to standard output (cf /usr/bin/env) unless --dump and/or --pickle ' \
diff --git a/lib/spack/spack/cmd/buildcache.py b/lib/spack/spack/cmd/buildcache.py
index 5baa63af85..cbcbc2c0cb 100644
--- a/lib/spack/spack/cmd/buildcache.py
+++ b/lib/spack/spack/cmd/buildcache.py
@@ -3,7 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
import os
import shutil
import sys
@@ -61,11 +60,9 @@ def setup_parser(subparser):
"building package(s)")
create.add_argument('-y', '--spec-yaml', default=None,
help='Create buildcache entry for spec from yaml file')
- create.add_argument(
- 'packages', nargs=argparse.REMAINDER,
- help="specs of packages to create buildcache for")
create.add_argument('--no-deps', action='store_true', default='false',
help='Create buildcache entry wo/ dependencies')
+ arguments.add_common_arguments(create, ['specs'])
create.set_defaults(func=createtarball)
install = subparsers.add_parser('install', help=installtarball.__doc__)
@@ -79,9 +76,7 @@ def setup_parser(subparser):
install.add_argument('-u', '--unsigned', action='store_true',
help="install unsigned buildcache" +
" tarballs for testing")
- install.add_argument(
- 'packages', nargs=argparse.REMAINDER,
- help="specs of packages to install buildcache for")
+ arguments.add_common_arguments(install, ['specs'])
install.set_defaults(func=installtarball)
listcache = subparsers.add_parser('list', help=listspecs.__doc__)
@@ -92,9 +87,7 @@ def setup_parser(subparser):
help='show variants in output (can be long)')
listcache.add_argument('-f', '--force', action='store_true',
help="force new download of specs")
- listcache.add_argument(
- 'packages', nargs=argparse.REMAINDER,
- help="specs of packages to search for")
+ arguments.add_common_arguments(listcache, ['specs'])
listcache.set_defaults(func=listspecs)
dlkeys = subparsers.add_parser('keys', help=getkeys.__doc__)
@@ -113,10 +106,9 @@ def setup_parser(subparser):
help='analyzes an installed spec and reports whether '
'executables and libraries are relocatable'
)
- preview_parser.add_argument(
- 'packages', nargs='+', help='list of installed packages'
- )
+ arguments.add_common_arguments(preview_parser, ['installed_specs'])
preview_parser.set_defaults(func=preview)
+
# Check if binaries need to be rebuilt on remote mirror
check = subparsers.add_parser('check', help=check_binaries.__doc__)
check.add_argument(
@@ -313,8 +305,10 @@ def _createtarball(env, spec_yaml, packages, directory, key, no_deps, force,
tty.debug(yaml_text)
s = Spec.from_yaml(yaml_text)
packages.add('/{0}'.format(s.dag_hash()))
+
elif packages:
packages = packages
+
else:
tty.die("build cache file creation requires at least one" +
" installed package argument or else path to a" +
@@ -378,17 +372,17 @@ def createtarball(args):
# restrict matching to current environment if one is active
env = ev.get_env(args, 'buildcache create')
- _createtarball(env, args.spec_yaml, args.packages, args.directory,
+ _createtarball(env, args.spec_yaml, args.specs, args.directory,
args.key, args.no_deps, args.force, args.rel, args.unsigned,
args.allow_root, args.no_rebuild_index)
def installtarball(args):
"""install from a binary package"""
- if not args.packages:
+ if not args.specs:
tty.die("build cache file installation requires" +
" at least one package spec argument")
- pkgs = set(args.packages)
+ pkgs = set(args.specs)
matches = match_downloaded_specs(pkgs, args.multiple, args.force)
for match in matches:
@@ -422,8 +416,8 @@ def install_tarball(spec, args):
def listspecs(args):
"""list binary packages available from mirrors"""
specs = bindist.get_specs(args.force)
- if args.packages:
- constraints = set(args.packages)
+ if args.specs:
+ constraints = set(args.specs)
specs = [s for s in specs if any(s.satisfies(c) for c in constraints)]
display_specs(specs, args, all_headers=True)
@@ -440,7 +434,7 @@ def preview(args):
Args:
args: command line arguments
"""
- specs = find_matching_specs(args.packages, allow_multiple_matches=True)
+ specs = find_matching_specs(args.specs, allow_multiple_matches=True)
# Cycle over the specs that match
for spec in specs:
diff --git a/lib/spack/spack/cmd/checksum.py b/lib/spack/spack/cmd/checksum.py
index c606cd3886..343915868c 100644
--- a/lib/spack/spack/cmd/checksum.py
+++ b/lib/spack/spack/cmd/checksum.py
@@ -10,6 +10,7 @@ import argparse
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.repo
import spack.stage
import spack.util.crypto
@@ -23,11 +24,9 @@ level = "long"
def setup_parser(subparser):
subparser.add_argument(
- 'package',
- help='package to checksum versions for')
- subparser.add_argument(
'--keep-stage', action='store_true',
help="don't clean up staging area when command completes")
+ arguments.add_common_arguments(subparser, ['package'])
subparser.add_argument(
'versions', nargs=argparse.REMAINDER,
help='versions to generate checksums for')
diff --git a/lib/spack/spack/cmd/clean.py b/lib/spack/spack/cmd/clean.py
index dc25857b51..791a1b7dc3 100644
--- a/lib/spack/spack/cmd/clean.py
+++ b/lib/spack/spack/cmd/clean.py
@@ -11,6 +11,7 @@ import llnl.util.tty as tty
import spack.caches
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.repo
import spack.stage
from spack.paths import lib_path, var_path
@@ -43,11 +44,7 @@ def setup_parser(subparser):
subparser.add_argument(
'-a', '--all', action=AllClean, help="equivalent to -sdmp", nargs=0
)
- subparser.add_argument(
- 'specs',
- nargs=argparse.REMAINDER,
- help="removes the build stages and tarballs for specs"
- )
+ arguments.add_common_arguments(subparser, ['specs'])
def clean(parser, args):
diff --git a/lib/spack/spack/cmd/commands.py b/lib/spack/spack/cmd/commands.py
index b4fde1aea4..4966bd7858 100644
--- a/lib/spack/spack/cmd/commands.py
+++ b/lib/spack/spack/cmd/commands.py
@@ -5,13 +5,16 @@
from __future__ import print_function
-import sys
+import argparse
+import copy
import os
import re
-import argparse
+import sys
import llnl.util.tty as tty
-from llnl.util.argparsewriter import ArgparseWriter, ArgparseRstWriter
+from llnl.util.argparsewriter import (
+ ArgparseWriter, ArgparseRstWriter, ArgparseCompletionWriter
+)
from llnl.util.tty.colify import colify
import spack.cmd
@@ -36,6 +39,8 @@ def formatter(func):
def setup_parser(subparser):
subparser.add_argument(
+ '-a', '--aliases', action='store_true', help='include command aliases')
+ subparser.add_argument(
'--format', default='names', choices=formatters,
help='format to be used to print the output (default: names)')
subparser.add_argument(
@@ -52,29 +57,97 @@ def setup_parser(subparser):
class SpackArgparseRstWriter(ArgparseRstWriter):
"""RST writer tailored for spack documentation."""
- def __init__(self, documented_commands, out=sys.stdout):
- super(SpackArgparseRstWriter, self).__init__(out)
- self.documented = documented_commands if documented_commands else []
+ def __init__(self, prog, out=sys.stdout, aliases=False,
+ documented_commands=[],
+ rst_levels=['-', '-', '^', '~', ':', '`']):
+ super(SpackArgparseRstWriter, self).__init__(
+ prog, out, aliases, rst_levels)
+ self.documented = documented_commands
def usage(self, *args):
- super(SpackArgparseRstWriter, self).usage(*args)
- cmd = re.sub(' ', '-', self.parser.prog)
+ string = super(SpackArgparseRstWriter, self).usage(*args)
+
+ cmd = self.parser.prog.replace(' ', '-')
if cmd in self.documented:
- self.line()
- self.line(':ref:`More documentation <cmd-%s>`' % cmd)
+ string += '\n:ref:`More documentation <cmd-{0}>`\n'.format(cmd)
+
+ return string
class SubcommandWriter(ArgparseWriter):
- def begin_command(self, prog):
- self.out.write(' ' * self.level + prog)
- self.out.write('\n')
+ def format(self, cmd):
+ return ' ' * self.level + cmd.prog + '\n'
+
+
+_positional_to_subroutine = {
+ 'package': '_all_packages',
+ 'spec': '_all_packages',
+ 'filter': '_all_packages',
+ 'installed': '_installed_packages',
+ 'compiler': '_installed_compilers',
+ 'section': '_config_sections',
+ 'env': '_environments',
+ 'extendable': '_extensions',
+ 'keys': '_keys',
+ 'help_command': '_subcommands',
+ 'mirror': '_mirrors',
+ 'virtual': '_providers',
+ 'namespace': '_repos',
+ 'hash': '_all_resource_hashes',
+ 'pytest': '_tests',
+}
+
+
+class BashCompletionWriter(ArgparseCompletionWriter):
+ """Write argparse output as bash programmable tab completion."""
+
+ def body(self, positionals, optionals, subcommands):
+ if positionals:
+ return """
+ if $list_options
+ then
+ {0}
+ else
+ {1}
+ fi
+""".format(self.optionals(optionals), self.positionals(positionals))
+ elif subcommands:
+ return """
+ if $list_options
+ then
+ {0}
+ else
+ {1}
+ fi
+""".format(self.optionals(optionals), self.subcommands(subcommands))
+ else:
+ return """
+ {0}
+""".format(self.optionals(optionals))
+
+ def positionals(self, positionals):
+ # If match found, return function name
+ for positional in positionals:
+ for key, value in _positional_to_subroutine.items():
+ if positional.startswith(key):
+ return value
+
+ # If no matches found, return empty list
+ return 'SPACK_COMPREPLY=""'
+
+ def optionals(self, optionals):
+ return 'SPACK_COMPREPLY="{0}"'.format(' '.join(optionals))
+
+ def subcommands(self, subcommands):
+ return 'SPACK_COMPREPLY="{0}"'.format(' '.join(subcommands))
@formatter
def subcommands(args, out):
parser = spack.main.make_argument_parser()
spack.main.add_all_commands(parser)
- SubcommandWriter(out).write(parser)
+ writer = SubcommandWriter(parser.prog, out, args.aliases)
+ writer.write(parser)
def rst_index(out):
@@ -124,12 +197,28 @@ def rst(args, out):
out.write('\n')
# print sections for each command and subcommand
- SpackArgparseRstWriter(documented_commands, out).write(parser, root=1)
+ writer = SpackArgparseRstWriter(
+ parser.prog, out, args.aliases, documented_commands)
+ writer.write(parser)
@formatter
def names(args, out):
- colify(spack.cmd.all_commands(), output=out)
+ commands = copy.copy(spack.cmd.all_commands())
+
+ if args.aliases:
+ commands.extend(spack.main.aliases.keys())
+
+ colify(commands, output=out)
+
+
+@formatter
+def bash(args, out):
+ parser = spack.main.make_argument_parser()
+ spack.main.add_all_commands(parser)
+
+ writer = BashCompletionWriter(parser.prog, out, args.aliases)
+ writer.write(parser)
def prepend_header(args, out):
@@ -148,12 +237,14 @@ def commands(parser, args):
tty.die("No such file: '%s'" % args.header)
# if we're updating an existing file, only write output if a command
- # is newer than the file.
+ # or the header is newer than the file.
if args.update:
if os.path.exists(args.update):
files = [
spack.cmd.get_module(command).__file__.rstrip('c') # pyc -> py
for command in spack.cmd.all_commands()]
+ if args.header:
+ files.append(args.header)
last_update = os.path.getmtime(args.update)
if not any(os.path.getmtime(f) > last_update for f in files):
tty.msg('File is up to date: %s' % args.update)
diff --git a/lib/spack/spack/cmd/common/arguments.py b/lib/spack/spack/cmd/common/arguments.py
index da8b0b0277..b93f265c7a 100644
--- a/lib/spack/spack/cmd/common/arguments.py
+++ b/lib/spack/spack/cmd/common/arguments.py
@@ -120,7 +120,7 @@ class SetParallelJobs(argparse.Action):
class DeptypeAction(argparse.Action):
- """Creates a tuple of valid dependency tpyes from a deptype argument."""
+ """Creates a tuple of valid dependency types from a deptype argument."""
def __call__(self, parser, namespace, values, option_string=None):
deptype = dep.all_deptypes
if values:
@@ -132,11 +132,53 @@ class DeptypeAction(argparse.Action):
setattr(namespace, self.dest, deptype)
+# TODO: merge constraint and installed_specs
@arg
def constraint():
return Args(
'constraint', nargs=argparse.REMAINDER, action=ConstraintAction,
- help='constraint to select a subset of installed packages')
+ help='constraint to select a subset of installed packages',
+ metavar='installed_specs')
+
+
+@arg
+def package():
+ return Args('package', help='package name')
+
+
+@arg
+def packages():
+ return Args(
+ 'packages', nargs='+', help='one or more package names',
+ metavar='package')
+
+
+# Specs must use `nargs=argparse.REMAINDER` because a single spec can
+# contain spaces, and contain variants like '-mpi' that argparse thinks
+# are a collection of optional flags.
+@arg
+def spec():
+ return Args('spec', nargs=argparse.REMAINDER, help='package spec')
+
+
+@arg
+def specs():
+ return Args(
+ 'specs', nargs=argparse.REMAINDER, help='one or more package specs')
+
+
+@arg
+def installed_spec():
+ return Args(
+ 'spec', nargs=argparse.REMAINDER, help='installed package spec',
+ metavar='installed_spec')
+
+
+@arg
+def installed_specs():
+ return Args(
+ 'specs', nargs=argparse.REMAINDER,
+ help='one or more installed package specs', metavar='installed_specs')
@arg
diff --git a/lib/spack/spack/cmd/config.py b/lib/spack/spack/cmd/config.py
index 9951f346cb..b6055a7f6b 100644
--- a/lib/spack/spack/cmd/config.py
+++ b/lib/spack/spack/cmd/config.py
@@ -34,7 +34,7 @@ def setup_parser(subparser):
help="configuration section to print. "
"options: %(choices)s",
nargs='?',
- metavar='SECTION',
+ metavar='section',
choices=spack.config.section_schemas)
blame_parser = sp.add_parser(
@@ -42,14 +42,14 @@ def setup_parser(subparser):
blame_parser.add_argument('section',
help="configuration section to print. "
"options: %(choices)s",
- metavar='SECTION',
+ metavar='section',
choices=spack.config.section_schemas)
edit_parser = sp.add_parser('edit', help='edit configuration file')
edit_parser.add_argument('section',
help="configuration section to edit. "
"options: %(choices)s",
- metavar='SECTION',
+ metavar='section',
nargs='?',
choices=spack.config.section_schemas)
edit_parser.add_argument(
diff --git a/lib/spack/spack/cmd/configure.py b/lib/spack/spack/cmd/configure.py
index d15d2be912..3df3c87413 100644
--- a/lib/spack/spack/cmd/configure.py
+++ b/lib/spack/spack/cmd/configure.py
@@ -7,6 +7,7 @@ import argparse
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.cmd.install as inst
from spack.build_systems.autotools import AutotoolsPackage
@@ -37,15 +38,11 @@ build_system_to_phase = {
def setup_parser(subparser):
subparser.add_argument(
- 'package',
- nargs=argparse.REMAINDER,
- help="spec of the package to install"
- )
- subparser.add_argument(
'-v', '--verbose',
action='store_true',
help="print additional output during builds"
)
+ arguments.add_common_arguments(subparser, ['spec'])
def _stop_at_phase_during_install(args, calling_fn, phase_mapping):
@@ -64,15 +61,15 @@ def _stop_at_phase_during_install(args, calling_fn, phase_mapping):
# Install package dependencies if needed
parser = argparse.ArgumentParser()
inst.setup_parser(parser)
- tty.msg('Checking dependencies for {0}'.format(args.package[0]))
+ tty.msg('Checking dependencies for {0}'.format(args.spec[0]))
cli_args = ['-v'] if args.verbose else []
install_args = parser.parse_args(cli_args + ['--only=dependencies'])
- install_args.package = args.package
+ install_args.spec = args.spec
inst.install(parser, install_args)
# Install package and stop at the given phase
cli_args = ['-v'] if args.verbose else []
install_args = parser.parse_args(cli_args + ['--only=package'])
- install_args.package = args.package
+ install_args.spec = args.spec
inst.install(parser, install_args, stop_at=phase)
except IndexError:
tty.error(
diff --git a/lib/spack/spack/cmd/deactivate.py b/lib/spack/spack/cmd/deactivate.py
index 43ef09a9b1..3c72531a9c 100644
--- a/lib/spack/spack/cmd/deactivate.py
+++ b/lib/spack/spack/cmd/deactivate.py
@@ -3,10 +3,10 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.environment as ev
import spack.store
from spack.filesystem_view import YamlFilesystemView
@@ -28,9 +28,7 @@ def setup_parser(subparser):
'-a', '--all', action='store_true',
help="deactivate all extensions of an extendable package, or "
"deactivate an extension AND its dependencies")
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER,
- help="spec of package extension to deactivate")
+ arguments.add_common_arguments(subparser, ['installed_spec'])
def deactivate(parser, args):
diff --git a/lib/spack/spack/cmd/dependencies.py b/lib/spack/spack/cmd/dependencies.py
index db8fbe4b48..e65e050bfa 100644
--- a/lib/spack/spack/cmd/dependencies.py
+++ b/lib/spack/spack/cmd/dependencies.py
@@ -3,8 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
from llnl.util.tty.colify import colify
@@ -31,8 +29,7 @@ def setup_parser(subparser):
subparser.add_argument(
'-V', '--no-expand-virtuals', action='store_false', default=True,
dest="expand_virtuals", help="do not expand virtual dependencies")
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER, help="spec or package name")
+ arguments.add_common_arguments(subparser, ['spec'])
def dependencies(parser, args):
diff --git a/lib/spack/spack/cmd/dependents.py b/lib/spack/spack/cmd/dependents.py
index 78e862a982..e60733f589 100644
--- a/lib/spack/spack/cmd/dependents.py
+++ b/lib/spack/spack/cmd/dependents.py
@@ -3,15 +3,14 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
from llnl.util.tty.colify import colify
+import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.environment as ev
import spack.repo
import spack.store
-import spack.cmd
description = "show packages that depend on another"
section = "basic"
@@ -26,8 +25,7 @@ def setup_parser(subparser):
subparser.add_argument(
'-t', '--transitive', action='store_true', default=False,
help="Show all transitive dependents.")
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER, help="spec or package name")
+ arguments.add_common_arguments(subparser, ['spec'])
def inverted_dependencies():
diff --git a/lib/spack/spack/cmd/dev_build.py b/lib/spack/spack/cmd/dev_build.py
index 190720b05f..c1004f24b3 100644
--- a/lib/spack/spack/cmd/dev_build.py
+++ b/lib/spack/spack/cmd/dev_build.py
@@ -5,14 +5,13 @@
import sys
import os
-import argparse
import llnl.util.tty as tty
import spack.config
import spack.cmd
-import spack.repo
import spack.cmd.common.arguments as arguments
+import spack.repo
from spack.stage import DIYStage
description = "developer build: build from code in current working directory"
@@ -41,9 +40,7 @@ def setup_parser(subparser):
subparser.add_argument(
'-u', '--until', type=str, dest='until', default=None,
help="phase to stop after when installing (default None)")
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER,
- help="specs to use for install. must contain package AND version")
+ arguments.add_common_arguments(subparser, ['spec'])
cd_group = subparser.add_mutually_exclusive_group()
arguments.add_common_arguments(cd_group, ['clean', 'dirty'])
diff --git a/lib/spack/spack/cmd/edit.py b/lib/spack/spack/cmd/edit.py
index 1438383b2c..6cdc3b788d 100644
--- a/lib/spack/spack/cmd/edit.py
+++ b/lib/spack/spack/cmd/edit.py
@@ -84,12 +84,11 @@ def setup_parser(subparser):
help="namespace of package to edit")
subparser.add_argument(
- 'name', nargs='?', default=None,
- help="name of package to edit")
+ 'package', nargs='?', default=None, help="package name")
def edit(parser, args):
- name = args.name
+ name = args.package
# By default, edit package files
path = spack.paths.packages_path
diff --git a/lib/spack/spack/cmd/env.py b/lib/spack/spack/cmd/env.py
index 1d61dfc250..a8bc1e5bbe 100644
--- a/lib/spack/spack/cmd/env.py
+++ b/lib/spack/spack/cmd/env.py
@@ -157,7 +157,7 @@ def env_deactivate(args):
def env_create_setup_parser(subparser):
"""create a new environment"""
subparser.add_argument(
- 'create_env', metavar='ENV', help='name of environment to create')
+ 'create_env', metavar='env', help='name of environment to create')
subparser.add_argument(
'-d', '--dir', action='store_true',
help='create an environment in a specific directory')
@@ -221,7 +221,7 @@ def _env_create(name_or_path, init_file=None, dir=False, with_view=None):
def env_remove_setup_parser(subparser):
"""remove an existing environment"""
subparser.add_argument(
- 'rm_env', metavar='ENV', nargs='+',
+ 'rm_env', metavar='env', nargs='+',
help='environment(s) to remove')
arguments.add_common_arguments(subparser, ['yes_to_all'])
diff --git a/lib/spack/spack/cmd/extensions.py b/lib/spack/spack/cmd/extensions.py
index 7e3db66384..e834d7fd18 100644
--- a/lib/spack/spack/cmd/extensions.py
+++ b/lib/spack/spack/cmd/extensions.py
@@ -37,7 +37,7 @@ def setup_parser(subparser):
subparser.add_argument(
'spec', nargs=argparse.REMAINDER,
- help='spec of package to list extensions for')
+ help='spec of package to list extensions for', metavar='extendable')
def extensions(parser, args):
diff --git a/lib/spack/spack/cmd/fetch.py b/lib/spack/spack/cmd/fetch.py
index 3004250f03..b91eb52ab8 100644
--- a/lib/spack/spack/cmd/fetch.py
+++ b/lib/spack/spack/cmd/fetch.py
@@ -3,14 +3,12 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.config
import spack.repo
-import spack.cmd.common.arguments as arguments
description = "fetch archives for packages"
section = "build"
@@ -25,19 +23,17 @@ def setup_parser(subparser):
subparser.add_argument(
'-D', '--dependencies', action='store_true',
help="also fetch all dependencies")
- subparser.add_argument(
- 'packages', nargs=argparse.REMAINDER,
- help="specs of packages to fetch")
+ arguments.add_common_arguments(subparser, ['specs'])
def fetch(parser, args):
- if not args.packages:
+ if not args.specs:
tty.die("fetch requires at least one package argument")
if args.no_checksum:
spack.config.set('config:checksum', False, scope='command_line')
- specs = spack.cmd.parse_specs(args.packages, concretize=True)
+ specs = spack.cmd.parse_specs(args.specs, concretize=True)
for spec in specs:
if args.missing or args.dependencies:
for s in spec.traverse():
diff --git a/lib/spack/spack/cmd/gpg.py b/lib/spack/spack/cmd/gpg.py
index c1a0cafe45..0a77812c12 100644
--- a/lib/spack/spack/cmd/gpg.py
+++ b/lib/spack/spack/cmd/gpg.py
@@ -6,6 +6,7 @@
import os
import argparse
+import spack.cmd.common.arguments as arguments
import spack.paths
from spack.util.gpg import Gpg
@@ -19,8 +20,7 @@ def setup_parser(subparser):
subparsers = subparser.add_subparsers(help='GPG sub-commands')
verify = subparsers.add_parser('verify', help=gpg_verify.__doc__)
- verify.add_argument('package', type=str,
- help='the package to verify')
+ arguments.add_common_arguments(verify, ['installed_spec'])
verify.add_argument('signature', type=str, nargs='?',
help='the signature file')
verify.set_defaults(func=gpg_verify)
@@ -44,8 +44,7 @@ def setup_parser(subparser):
help='the key to use for signing')
sign.add_argument('--clearsign', action='store_true',
help='if specified, create a clearsign signature')
- sign.add_argument('package', type=str,
- help='the package to sign')
+ arguments.add_common_arguments(sign, ['installed_spec'])
sign.set_defaults(func=gpg_sign)
create = subparsers.add_parser('create', help=gpg_create.__doc__)
@@ -122,9 +121,9 @@ def gpg_sign(args):
'please choose one')
output = args.output
if not output:
- output = args.package + '.asc'
+ output = args.spec[0] + '.asc'
# TODO: Support the package format Spack creates.
- Gpg.sign(key, args.package, output, args.clearsign)
+ Gpg.sign(key, ' '.join(args.spec), output, args.clearsign)
def gpg_trust(args):
@@ -155,8 +154,8 @@ def gpg_verify(args):
# TODO: Support the package format Spack creates.
signature = args.signature
if signature is None:
- signature = args.package + '.asc'
- Gpg.verify(signature, args.package)
+ signature = args.spec[0] + '.asc'
+ Gpg.verify(signature, ' '.join(args.spec))
def gpg(parser, args):
diff --git a/lib/spack/spack/cmd/graph.py b/lib/spack/spack/cmd/graph.py
index 94197283b8..d0fbf8e6c6 100644
--- a/lib/spack/spack/cmd/graph.py
+++ b/lib/spack/spack/cmd/graph.py
@@ -5,7 +5,6 @@
from __future__ import print_function
-import argparse
import llnl.util.tty as tty
import spack.cmd
@@ -38,11 +37,7 @@ def setup_parser(subparser):
'-i', '--installed', action='store_true',
help="graph all installed specs in dot format (implies --dot)")
- arguments.add_common_arguments(subparser, ['deptype'])
-
- subparser.add_argument(
- 'specs', nargs=argparse.REMAINDER,
- help="specs of packages to graph")
+ arguments.add_common_arguments(subparser, ['deptype', 'specs'])
def graph(parser, args):
diff --git a/lib/spack/spack/cmd/info.py b/lib/spack/spack/cmd/info.py
index 413b96fe18..81a68dae96 100644
--- a/lib/spack/spack/cmd/info.py
+++ b/lib/spack/spack/cmd/info.py
@@ -11,6 +11,7 @@ from six.moves import zip_longest
import llnl.util.tty.color as color
from llnl.util.tty.colify import colify
+import spack.cmd.common.arguments as arguments
import spack.repo
import spack.spec
import spack.fetch_strategy as fs
@@ -36,8 +37,7 @@ def padder(str_list, extra=0):
def setup_parser(subparser):
- subparser.add_argument(
- 'name', metavar='PACKAGE', help='name of package to get info for')
+ arguments.add_common_arguments(subparser, ['package'])
def section_title(s):
@@ -237,5 +237,5 @@ def print_text_info(pkg):
def info(parser, args):
- pkg = spack.repo.get(args.name)
+ pkg = spack.repo.get(args.package)
print_text_info(pkg)
diff --git a/lib/spack/spack/cmd/install.py b/lib/spack/spack/cmd/install.py
index ace27577eb..18dad6108b 100644
--- a/lib/spack/spack/cmd/install.py
+++ b/lib/spack/spack/cmd/install.py
@@ -122,11 +122,6 @@ the dependencies"""
cd_group = subparser.add_mutually_exclusive_group()
arguments.add_common_arguments(cd_group, ['clean', 'dirty'])
- subparser.add_argument(
- 'package',
- nargs=argparse.REMAINDER,
- help="spec of the package to install"
- )
testing = subparser.add_mutually_exclusive_group()
testing.add_argument(
'--test', default=None,
@@ -157,7 +152,7 @@ packages. If neither are chosen, don't run tests for any packages."""
help="Show usage instructions for CDash reporting"
)
add_cdash_args(subparser, False)
- arguments.add_common_arguments(subparser, ['yes_to_all'])
+ arguments.add_common_arguments(subparser, ['yes_to_all', 'spec'])
def add_cdash_args(subparser, add_help):
@@ -258,7 +253,7 @@ environment variables:
parser.print_help()
return
- if not args.package and not args.specfiles:
+ if not args.spec and not args.specfiles:
# if there are no args but an active environment or spack.yaml file
# then install the packages from it.
env = ev.get_env(args, 'install')
@@ -293,7 +288,7 @@ environment variables:
if args.log_file:
reporter.filename = args.log_file
- abstract_specs = spack.cmd.parse_specs(args.package)
+ abstract_specs = spack.cmd.parse_specs(args.spec)
tests = False
if args.test == 'all' or args.run_tests:
tests = True
@@ -303,7 +298,7 @@ environment variables:
try:
specs = spack.cmd.parse_specs(
- args.package, concretize=True, tests=tests)
+ args.spec, concretize=True, tests=tests)
except SpackError as e:
tty.debug(e)
reporter.concretization_report(e.message)
diff --git a/lib/spack/spack/cmd/load.py b/lib/spack/spack/cmd/load.py
index 89dd61675e..9c48fe802a 100644
--- a/lib/spack/spack/cmd/load.py
+++ b/lib/spack/spack/cmd/load.py
@@ -3,7 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
from spack.cmd.common import print_module_placeholder_help, arguments
description = "add package to environment using `module load`"
@@ -14,11 +13,8 @@ level = "short"
def setup_parser(subparser):
"""Parser is only constructed so that this prints a nice help
message with -h. """
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER,
- help="spec of package to load with modules "
- )
- arguments.add_common_arguments(subparser, ['recurse_dependencies'])
+ arguments.add_common_arguments(
+ subparser, ['recurse_dependencies', 'installed_spec'])
def load(parser, args):
diff --git a/lib/spack/spack/cmd/location.py b/lib/spack/spack/cmd/location.py
index a48ce85261..60978fe404 100644
--- a/lib/spack/spack/cmd/location.py
+++ b/lib/spack/spack/cmd/location.py
@@ -6,11 +6,11 @@
from __future__ import print_function
import os
-import argparse
import llnl.util.tty as tty
import spack.environment as ev
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.environment
import spack.paths
import spack.repo
@@ -55,9 +55,7 @@ def setup_parser(subparser):
'-e', '--env', action='store',
help="location of an environment managed by spack")
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER,
- help="spec of package to fetch directory for")
+ arguments.add_common_arguments(subparser, ['spec'])
def location(parser, args):
diff --git a/lib/spack/spack/cmd/maintainers.py b/lib/spack/spack/cmd/maintainers.py
index a1fb7716f9..a1cf477146 100644
--- a/lib/spack/spack/cmd/maintainers.py
+++ b/lib/spack/spack/cmd/maintainers.py
@@ -40,7 +40,7 @@ def setup_parser(subparser):
# options for commands that take package arguments
subparser.add_argument(
- 'pkg_or_user', nargs=argparse.REMAINDER,
+ 'package_or_user', nargs=argparse.REMAINDER,
help='names of packages or users to get info for')
@@ -104,31 +104,31 @@ def maintainers(parser, args):
if args.all:
if args.by_user:
- maintainers = maintainers_to_packages(args.pkg_or_user)
+ maintainers = maintainers_to_packages(args.package_or_user)
for user, packages in sorted(maintainers.items()):
color.cprint('@c{%s}: %s'
% (user, ', '.join(sorted(packages))))
return 0 if maintainers else 1
else:
- packages = packages_to_maintainers(args.pkg_or_user)
+ packages = packages_to_maintainers(args.package_or_user)
for pkg, maintainers in sorted(packages.items()):
color.cprint('@c{%s}: %s'
% (pkg, ', '.join(sorted(maintainers))))
return 0 if packages else 1
if args.by_user:
- if not args.pkg_or_user:
+ if not args.package_or_user:
tty.die('spack maintainers --by-user requires a user or --all')
- packages = union_values(maintainers_to_packages(args.pkg_or_user))
+ packages = union_values(maintainers_to_packages(args.package_or_user))
colify(packages)
return 0 if packages else 1
else:
- if not args.pkg_or_user:
+ if not args.package_or_user:
tty.die('spack maintainers requires a package or --all')
- users = union_values(packages_to_maintainers(args.pkg_or_user))
+ users = union_values(packages_to_maintainers(args.package_or_user))
colify(users)
return 0 if users else 1
diff --git a/lib/spack/spack/cmd/mirror.py b/lib/spack/spack/cmd/mirror.py
index 10f01fd363..5206927895 100644
--- a/lib/spack/spack/cmd/mirror.py
+++ b/lib/spack/spack/cmd/mirror.py
@@ -5,7 +5,6 @@
import sys
-import argparse
import llnl.util.tty as tty
from llnl.util.tty.colify import colify
@@ -40,9 +39,6 @@ def setup_parser(subparser):
help="directory in which to create mirror")
create_parser.add_argument(
- 'specs', nargs=argparse.REMAINDER,
- help="specs of packages to put in mirror")
- create_parser.add_argument(
'-a', '--all', action='store_true',
help="mirror all versions of all packages in Spack, or all packages"
" in the current environment if there is an active environment"
@@ -57,6 +53,7 @@ def setup_parser(subparser):
'-n', '--versions-per-spec',
help="the number of versions to fetch for each spec, choose 'all' to"
" retrieve all versions of each package")
+ arguments.add_common_arguments(create_parser, ['specs'])
# used to construct scope arguments below
scopes = spack.config.scopes()
@@ -64,7 +61,8 @@ def setup_parser(subparser):
# Add
add_parser = sp.add_parser('add', help=mirror_add.__doc__)
- add_parser.add_argument('name', help="mnemonic name for mirror")
+ add_parser.add_argument(
+ 'name', help="mnemonic name for mirror", metavar="mirror")
add_parser.add_argument(
'url', help="url of mirror directory from 'spack mirror create'")
add_parser.add_argument(
@@ -75,7 +73,8 @@ def setup_parser(subparser):
# Remove
remove_parser = sp.add_parser('remove', aliases=['rm'],
help=mirror_remove.__doc__)
- remove_parser.add_argument('name')
+ remove_parser.add_argument(
+ 'name', help="mnemonic name for mirror", metavar="mirror")
remove_parser.add_argument(
'--scope', choices=scopes, metavar=scopes_metavar,
default=spack.config.default_modify_scope(),
@@ -83,7 +82,8 @@ def setup_parser(subparser):
# Set-Url
set_url_parser = sp.add_parser('set-url', help=mirror_set_url.__doc__)
- set_url_parser.add_argument('name', help="mnemonic name for mirror")
+ set_url_parser.add_argument(
+ 'name', help="mnemonic name for mirror", metavar="mirror")
set_url_parser.add_argument(
'url', help="url of mirror directory from 'spack mirror create'")
set_url_parser.add_argument(
diff --git a/lib/spack/spack/cmd/patch.py b/lib/spack/spack/cmd/patch.py
index 9e7cc4164b..8f91edb8f1 100644
--- a/lib/spack/spack/cmd/patch.py
+++ b/lib/spack/spack/cmd/patch.py
@@ -3,8 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
import spack.repo
@@ -18,20 +16,17 @@ level = "long"
def setup_parser(subparser):
- arguments.add_common_arguments(subparser, ['no_checksum'])
- subparser.add_argument(
- 'packages', nargs=argparse.REMAINDER,
- help="specs of packages to stage")
+ arguments.add_common_arguments(subparser, ['no_checksum', 'specs'])
def patch(parser, args):
- if not args.packages:
- tty.die("patch requires at least one package argument")
+ if not args.specs:
+ tty.die("patch requires at least one spec argument")
if args.no_checksum:
spack.config.set('config:checksum', False, scope='command_line')
- specs = spack.cmd.parse_specs(args.packages, concretize=True)
+ specs = spack.cmd.parse_specs(args.specs, concretize=True)
for spec in specs:
package = spack.repo.get(spec)
package.do_patch()
diff --git a/lib/spack/spack/cmd/pkg.py b/lib/spack/spack/cmd/pkg.py
index 86ff535d5e..b988d6a848 100644
--- a/lib/spack/spack/cmd/pkg.py
+++ b/lib/spack/spack/cmd/pkg.py
@@ -6,7 +6,6 @@
from __future__ import print_function
import os
-import argparse
import re
import llnl.util.tty as tty
@@ -14,6 +13,7 @@ from llnl.util.tty.colify import colify
from llnl.util.filesystem import working_dir
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.paths
import spack.repo
from spack.util.executable import which
@@ -28,8 +28,7 @@ def setup_parser(subparser):
metavar='SUBCOMMAND', dest='pkg_command')
add_parser = sp.add_parser('add', help=pkg_add.__doc__)
- add_parser.add_argument('packages', nargs=argparse.REMAINDER,
- help="names of packages to add to git repo")
+ arguments.add_common_arguments(add_parser, ['packages'])
list_parser = sp.add_parser('list', help=pkg_list.__doc__)
list_parser.add_argument('rev', default='HEAD', nargs='?',
diff --git a/lib/spack/spack/cmd/remove.py b/lib/spack/spack/cmd/remove.py
index cce197af2e..049041ce83 100644
--- a/lib/spack/spack/cmd/remove.py
+++ b/lib/spack/spack/cmd/remove.py
@@ -3,11 +3,10 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.environment as ev
@@ -26,8 +25,7 @@ def setup_parser(subparser):
subparser.add_argument(
'-f', '--force', action='store_true',
help="remove concretized spec (if any) immediately")
- subparser.add_argument(
- 'specs', nargs=argparse.REMAINDER, help="specs to be removed")
+ arguments.add_common_arguments(subparser, ['specs'])
def remove(parser, args):
diff --git a/lib/spack/spack/cmd/repo.py b/lib/spack/spack/cmd/repo.py
index 019813fc9f..83acf796a2 100644
--- a/lib/spack/spack/cmd/repo.py
+++ b/lib/spack/spack/cmd/repo.py
@@ -51,8 +51,8 @@ def setup_parser(subparser):
remove_parser = sp.add_parser(
'remove', help=repo_remove.__doc__, aliases=['rm'])
remove_parser.add_argument(
- 'path_or_namespace',
- help="path or namespace of a Spack package repository")
+ 'namespace_or_path',
+ help="namespace or path of a Spack package repository")
remove_parser.add_argument(
'--scope', choices=scopes, metavar=scopes_metavar,
default=spack.config.default_modify_scope(),
@@ -101,10 +101,10 @@ def repo_add(args):
def repo_remove(args):
"""Remove a repository from Spack's configuration."""
repos = spack.config.get('repos', scope=args.scope)
- path_or_namespace = args.path_or_namespace
+ namespace_or_path = args.namespace_or_path
# If the argument is a path, remove that repository from config.
- canon_path = canonicalize_path(path_or_namespace)
+ canon_path = canonicalize_path(namespace_or_path)
for repo_path in repos:
repo_canon_path = canonicalize_path(repo_path)
if canon_path == repo_canon_path:
@@ -117,7 +117,7 @@ def repo_remove(args):
for path in repos:
try:
repo = Repo(path)
- if repo.namespace == path_or_namespace:
+ if repo.namespace == namespace_or_path:
repos.remove(path)
spack.config.set('repos', repos, args.scope)
tty.msg("Removed repository %s with namespace '%s'."
@@ -127,7 +127,7 @@ def repo_remove(args):
continue
tty.die("No repository with path or namespace: %s"
- % path_or_namespace)
+ % namespace_or_path)
def repo_list(args):
diff --git a/lib/spack/spack/cmd/restage.py b/lib/spack/spack/cmd/restage.py
index f74ef09a12..0f55884bfe 100644
--- a/lib/spack/spack/cmd/restage.py
+++ b/lib/spack/spack/cmd/restage.py
@@ -3,11 +3,10 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
import spack.cmd
+import spack.cmd.common.arguments as arguments
import spack.repo
description = "revert checked out package source code"
@@ -16,15 +15,14 @@ level = "long"
def setup_parser(subparser):
- subparser.add_argument('packages', nargs=argparse.REMAINDER,
- help="specs of packages to restage")
+ arguments.add_common_arguments(subparser, ['specs'])
def restage(parser, args):
- if not args.packages:
+ if not args.specs:
tty.die("spack restage requires at least one package spec.")
- specs = spack.cmd.parse_specs(args.packages, concretize=True)
+ specs = spack.cmd.parse_specs(args.specs, concretize=True)
for spec in specs:
package = spack.repo.get(spec)
package.do_restage()
diff --git a/lib/spack/spack/cmd/setup.py b/lib/spack/spack/cmd/setup.py
index 3e4f9135d7..246e3b4275 100644
--- a/lib/spack/spack/cmd/setup.py
+++ b/lib/spack/spack/cmd/setup.py
@@ -30,13 +30,10 @@ def setup_parser(subparser):
subparser.add_argument(
'-i', '--ignore-dependencies', action='store_true', dest='ignore_deps',
help="do not try to install dependencies of requested packages")
- arguments.add_common_arguments(subparser, ['no_checksum'])
+ arguments.add_common_arguments(subparser, ['no_checksum', 'spec'])
subparser.add_argument(
'-v', '--verbose', action='store_true', dest='verbose',
help="display verbose build output while installing")
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER,
- help="specs to use for install. must contain package AND version")
cd_group = subparser.add_mutually_exclusive_group()
arguments.add_common_arguments(cd_group, ['clean', 'dirty'])
diff --git a/lib/spack/spack/cmd/spec.py b/lib/spack/spack/cmd/spec.py
index 85fe5a1a9e..fd03f09e57 100644
--- a/lib/spack/spack/cmd/spec.py
+++ b/lib/spack/spack/cmd/spec.py
@@ -5,7 +5,6 @@
from __future__ import print_function
-import argparse
import contextlib
import sys
@@ -47,8 +46,7 @@ for further documentation regarding the spec syntax, see:
subparser.add_argument(
'-t', '--types', action='store_true', default=False,
help='show dependency types')
- subparser.add_argument(
- 'specs', nargs=argparse.REMAINDER, help="specs of packages")
+ arguments.add_common_arguments(subparser, ['specs'])
@contextlib.contextmanager
diff --git a/lib/spack/spack/cmd/stage.py b/lib/spack/spack/cmd/stage.py
index 9c0d3ad63c..1acefb723c 100644
--- a/lib/spack/spack/cmd/stage.py
+++ b/lib/spack/spack/cmd/stage.py
@@ -3,8 +3,6 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-
import llnl.util.tty as tty
import spack.environment as ev
@@ -18,14 +16,11 @@ level = "long"
def setup_parser(subparser):
- arguments.add_common_arguments(subparser, ['no_checksum'])
+ arguments.add_common_arguments(subparser, ['no_checksum', 'specs'])
subparser.add_argument(
'-p', '--path', dest='path',
help="path to stage package, does not add to spack tree")
- subparser.add_argument(
- 'specs', nargs=argparse.REMAINDER, help="specs of packages to stage")
-
def stage(parser, args):
if not args.specs:
diff --git a/lib/spack/spack/cmd/uninstall.py b/lib/spack/spack/cmd/uninstall.py
index 906da8d3b3..0ad42f4dfb 100644
--- a/lib/spack/spack/cmd/uninstall.py
+++ b/lib/spack/spack/cmd/uninstall.py
@@ -5,7 +5,6 @@
from __future__ import print_function
-import argparse
import sys
import spack.cmd
@@ -38,17 +37,13 @@ display_args = {
}
-def add_common_arguments(subparser):
+def setup_parser(subparser):
subparser.add_argument(
'-f', '--force', action='store_true', dest='force',
help="remove regardless of whether other packages or environments "
"depend on this one")
arguments.add_common_arguments(
- subparser, ['recurse_dependents', 'yes_to_all'])
-
-
-def setup_parser(subparser):
- add_common_arguments(subparser)
+ subparser, ['recurse_dependents', 'yes_to_all', 'installed_specs'])
subparser.add_argument(
'-a', '--all', action='store_true', dest='all',
help="USE CAREFULLY. Remove ALL installed packages that match each "
@@ -58,11 +53,6 @@ def setup_parser(subparser):
"If used in an environment, all packages in the environment "
"will be uninstalled.")
- subparser.add_argument(
- 'packages',
- nargs=argparse.REMAINDER,
- help="specs of packages to uninstall")
-
def find_matching_specs(env, specs, allow_multiple_matches=False, force=False):
"""Returns a list of specs matching the not necessarily
@@ -351,10 +341,10 @@ def confirm_removal(specs):
def uninstall(parser, args):
- if not args.packages and not args.all:
+ if not args.specs and not args.all:
tty.die('uninstall requires at least one package argument.',
' Use `spack uninstall --all` to uninstall ALL packages.')
# [any] here handles the --all case by forcing all specs to be returned
- specs = spack.cmd.parse_specs(args.packages) if args.packages else [any]
+ specs = spack.cmd.parse_specs(args.specs) if args.specs else [any]
uninstall_specs(args, specs)
diff --git a/lib/spack/spack/cmd/unload.py b/lib/spack/spack/cmd/unload.py
index 581b37a013..92a25478b6 100644
--- a/lib/spack/spack/cmd/unload.py
+++ b/lib/spack/spack/cmd/unload.py
@@ -3,8 +3,7 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import argparse
-from spack.cmd.common import print_module_placeholder_help
+from spack.cmd.common import print_module_placeholder_help, arguments
description = "remove package from environment using `module unload`"
section = "modules"
@@ -14,9 +13,7 @@ level = "short"
def setup_parser(subparser):
"""Parser is only constructed so that this prints a nice help
message with -h. """
- subparser.add_argument(
- 'spec', nargs=argparse.REMAINDER,
- help='spec of package to unload with modules')
+ arguments.add_common_arguments(subparser, ['installed_spec'])
def unload(parser, args):
diff --git a/lib/spack/spack/cmd/verify.py b/lib/spack/spack/cmd/verify.py
index 9a38284691..b20d795ce5 100644
--- a/lib/spack/spack/cmd/verify.py
+++ b/lib/spack/spack/cmd/verify.py
@@ -25,8 +25,8 @@ def setup_parser(subparser):
help="Ouptut json-formatted errors")
subparser.add_argument('-a', '--all', action='store_true',
help="Verify all packages")
- subparser.add_argument('files_or_specs', nargs=argparse.REMAINDER,
- help="Files or specs to verify")
+ subparser.add_argument('specs_or_files', nargs=argparse.REMAINDER,
+ help="Specs or files to verify")
type = subparser.add_mutually_exclusive_group()
type.add_argument(
@@ -47,7 +47,7 @@ def verify(parser, args):
setup_parser.parser.print_help()
return 1
- for file in args.files_or_specs:
+ for file in args.specs_or_files:
results = spack.verify.check_file_manifest(file)
if results.has_errors():
if args.json:
@@ -57,21 +57,21 @@ def verify(parser, args):
return 0
else:
- spec_args = spack.cmd.parse_specs(args.files_or_specs)
+ spec_args = spack.cmd.parse_specs(args.specs_or_files)
if args.all:
query = spack.store.db.query_local if local else spack.store.db.query
# construct spec list
if spec_args:
- spec_list = spack.cmd.parse_specs(args.files_or_specs)
+ spec_list = spack.cmd.parse_specs(args.specs_or_files)
specs = []
for spec in spec_list:
specs += query(spec, installed=True)
else:
specs = query(installed=True)
- elif args.files_or_specs:
+ elif args.specs_or_files:
# construct disambiguated spec list
env = ev.get_env(args, 'verify')
specs = list(map(lambda x: spack.cmd.disambiguate_spec(x, env,
diff --git a/lib/spack/spack/cmd/versions.py b/lib/spack/spack/cmd/versions.py
index c12e7d6290..723f89ce08 100644
--- a/lib/spack/spack/cmd/versions.py
+++ b/lib/spack/spack/cmd/versions.py
@@ -5,11 +5,13 @@
from __future__ import print_function
+import sys
+
from llnl.util.tty.colify import colify
import llnl.util.tty as tty
+import spack.cmd.common.arguments as arguments
import spack.repo
-import sys
description = "list available versions of a package"
section = "packaging"
@@ -17,10 +19,9 @@ level = "long"
def setup_parser(subparser):
- subparser.add_argument('package', metavar='PACKAGE',
- help='package to list versions for')
subparser.add_argument('-s', '--safe-only', action='store_true',
help='only list safe versions of the package')
+ arguments.add_common_arguments(subparser, ['package'])
def versions(parser, args):
diff --git a/lib/spack/spack/reporters/cdash.py b/lib/spack/spack/reporters/cdash.py
index 178747706a..580df7866f 100644
--- a/lib/spack/spack/reporters/cdash.py
+++ b/lib/spack/spack/reporters/cdash.py
@@ -72,8 +72,8 @@ class CDash(Reporter):
tty.verbose("Using CDash auth token from environment")
self.authtoken = os.environ.get('SPACK_CDASH_AUTH_TOKEN')
- if args.package:
- packages = args.package
+ if args.spec:
+ packages = args.spec
else:
packages = []
for file in args.specfiles:
diff --git a/lib/spack/spack/test/cmd/commands.py b/lib/spack/spack/test/cmd/commands.py
index c8ec60d823..2fe62b9bba 100644
--- a/lib/spack/spack/test/cmd/commands.py
+++ b/lib/spack/spack/test/cmd/commands.py
@@ -3,13 +3,17 @@
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
-import re
-import pytest
+import filecmp
+import os
+import subprocess
-from llnl.util.argparsewriter import ArgparseWriter
+import pytest
import spack.cmd
+from spack.cmd.commands import _positional_to_subroutine
import spack.main
+import spack.paths
+
commands = spack.main.SpackCommand('commands')
@@ -17,38 +21,64 @@ parser = spack.main.make_argument_parser()
spack.main.add_all_commands(parser)
-def test_commands_by_name():
+def test_names():
"""Test default output of spack commands."""
- out = commands()
- assert out.strip().split('\n') == sorted(spack.cmd.all_commands())
+ out1 = commands().strip().split('\n')
+ assert out1 == spack.cmd.all_commands()
+ assert 'rm' not in out1
+ out2 = commands('--aliases').strip().split('\n')
+ assert out1 != out2
+ assert 'rm' in out2
-def test_subcommands():
- """Test subcommand traversal."""
- out = commands('--format=subcommands')
- assert 'spack mirror create' in out
- assert 'spack buildcache list' in out
- assert 'spack repo add' in out
- assert 'spack pkg diff' in out
- assert 'spack url parse' in out
- assert 'spack view symlink' in out
+ out3 = commands('--format=names').strip().split('\n')
+ assert out1 == out3
- class Subcommands(ArgparseWriter):
- def begin_command(self, prog):
- assert prog in out
- Subcommands().write(parser)
+def test_subcommands():
+ """Test subcommand traversal."""
+ out1 = commands('--format=subcommands')
+ assert 'spack mirror create' in out1
+ assert 'spack buildcache list' in out1
+ assert 'spack repo add' in out1
+ assert 'spack pkg diff' in out1
+ assert 'spack url parse' in out1
+ assert 'spack view symlink' in out1
+ assert 'spack rm' not in out1
+ assert 'spack compiler add' not in out1
+
+ out2 = commands('--aliases', '--format=subcommands')
+ assert 'spack mirror create' in out2
+ assert 'spack buildcache list' in out2
+ assert 'spack repo add' in out2
+ assert 'spack pkg diff' in out2
+ assert 'spack url parse' in out2
+ assert 'spack view symlink' in out2
+ assert 'spack rm' in out2
+ assert 'spack compiler add' in out2
def test_rst():
"""Do some simple sanity checks of the rst writer."""
- out = commands('--format=rst')
-
- class Subcommands(ArgparseWriter):
- def begin_command(self, prog):
- assert prog in out
- assert re.sub(r' ', '-', prog) in out
- Subcommands().write(parser)
+ out1 = commands('--format=rst')
+ assert 'spack mirror create' in out1
+ assert 'spack buildcache list' in out1
+ assert 'spack repo add' in out1
+ assert 'spack pkg diff' in out1
+ assert 'spack url parse' in out1
+ assert 'spack view symlink' in out1
+ assert 'spack rm' not in out1
+ assert 'spack compiler add' not in out1
+
+ out2 = commands('--aliases', '--format=rst')
+ assert 'spack mirror create' in out2
+ assert 'spack buildcache list' in out2
+ assert 'spack repo add' in out2
+ assert 'spack pkg diff' in out2
+ assert 'spack url parse' in out2
+ assert 'spack view symlink' in out2
+ assert 'spack rm' in out2
+ assert 'spack compiler add' in out2
def test_rst_with_input_files(tmpdir):
@@ -109,3 +139,91 @@ def test_rst_update(tmpdir):
assert update_file.exists()
with update_file.open() as f:
assert f.read() == 'empty\n'
+
+
+def test_update_with_header(tmpdir):
+ update_file = tmpdir.join('output')
+
+ # not yet created when commands is run
+ commands('--update', str(update_file))
+ assert update_file.exists()
+ with update_file.open() as f:
+ assert f.read()
+ fake_header = 'this is a header!\n\n'
+
+ filename = tmpdir.join('header.txt')
+ with filename.open('w') as f:
+ f.write(fake_header)
+
+ # created, newer than commands, but older than header
+ commands('--update', str(update_file), '--header', str(filename))
+
+ # newer than commands and header
+ commands('--update', str(update_file), '--header', str(filename))
+
+
+@pytest.mark.xfail
+def test_no_pipe_error():
+ """Make sure we don't see any pipe errors when piping output."""
+
+ proc = subprocess.Popen(
+ ['spack', 'commands', '--format=rst'],
+ stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+ # Call close() on stdout to cause a broken pipe
+ proc.stdout.close()
+ proc.wait()
+ stderr = proc.stderr.read().decode('utf-8')
+
+ assert 'Broken pipe' not in stderr
+
+
+def test_bash_completion():
+ """Test the bash completion writer."""
+ out1 = commands('--format=bash')
+
+ # Make sure header not included
+ assert '_bash_completion_spack() {' not in out1
+ assert '_all_packages() {' not in out1
+
+ # Make sure subcommands appear
+ assert '_spack_remove() {' in out1
+ assert '_spack_compiler_find() {' in out1
+
+ # Make sure aliases don't appear
+ assert '_spack_rm() {' not in out1
+ assert '_spack_compiler_add() {' not in out1
+
+ # Make sure options appear
+ assert '-h --help' in out1
+
+ # Make sure subcommands are called
+ for function in _positional_to_subroutine.values():
+ assert function in out1
+
+ out2 = commands('--aliases', '--format=bash')
+
+ # Make sure aliases appear
+ assert '_spack_rm() {' in out2
+ assert '_spack_compiler_add() {' in out2
+
+
+def test_updated_completion_scripts(tmpdir):
+ """Make sure our shell tab completion scripts remain up-to-date."""
+
+ msg = ("It looks like Spack's command-line interface has been modified. "
+ "Please update Spack's shell tab completion scripts by running:\n\n"
+ " share/spack/qa/update-completion-scripts.sh\n\n"
+ "and adding the changed files to your pull request.")
+
+ for shell in ['bash']: # 'zsh', 'fish']:
+ header = os.path.join(
+ spack.paths.share_path, shell, 'spack-completion.in')
+ script = 'spack-completion.{0}'.format(shell)
+ old_script = os.path.join(spack.paths.share_path, script)
+ new_script = str(tmpdir.join(script))
+
+ commands('--aliases', '--format', shell,
+ '--header', header, '--update', new_script)
+
+ assert filecmp.cmp(old_script, new_script), msg
diff --git a/lib/spack/spack/test/llnl/util/argparsewriter.py b/lib/spack/spack/test/llnl/util/argparsewriter.py
new file mode 100644
index 0000000000..127149bbaa
--- /dev/null
+++ b/lib/spack/spack/test/llnl/util/argparsewriter.py
@@ -0,0 +1,37 @@
+# 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)
+
+"""Tests for ``llnl/util/argparsewriter.py``
+
+These tests are fairly minimal, and ArgparseWriter is more extensively
+tested in ``cmd/commands.py``.
+"""
+
+import pytest
+
+import llnl.util.argparsewriter as aw
+
+import spack.main
+
+
+parser = spack.main.make_argument_parser()
+spack.main.add_all_commands(parser)
+
+
+def test_format_not_overridden():
+ writer = aw.ArgparseWriter('spack')
+
+ with pytest.raises(NotImplementedError):
+ writer.write(parser)
+
+
+def test_completion_format_not_overridden():
+ writer = aw.ArgparseCompletionWriter('spack')
+
+ assert writer.positionals([]) == ''
+ assert writer.optionals([]) == ''
+ assert writer.subcommands([]) == ''
+
+ writer.write(parser)
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