Skip to content
Snippets Groups Projects
Commit 5b5894af authored by Massimiliano Culpo's avatar Massimiliano Culpo Committed by Todd Gamblin
Browse files

spack find: accepts anonymous specs as arguments fixes #2170 (#2188)

parent b706da11
Branches
Tags
No related merge requests found
...@@ -46,19 +46,25 @@ class ConstraintAction(argparse.Action): ...@@ -46,19 +46,25 @@ class ConstraintAction(argparse.Action):
"""Constructs a list of specs based on a constraint given on the command line """Constructs a list of specs based on a constraint given on the command line
An instance of this class is supposed to be used as an argument action An instance of this class is supposed to be used as an argument action
in a parser. It will read a constraint and will attach a list of matching in a parser. It will read a constraint and will attach a function to the
specs to the namespace arguments that accepts optional keyword arguments.
To obtain the specs from a command the function must be called.
""" """
qualifiers = {}
def __call__(self, parser, namespace, values, option_string=None): def __call__(self, parser, namespace, values, option_string=None):
# Query specs from command line # Query specs from command line
d = self.qualifiers.get(namespace.subparser_name, {}) self.values = values
specs = [s for s in spack.store.db.query(**d)] namespace.contraint = values
values = ' '.join(values) namespace.specs = self._specs
def _specs(self, **kwargs):
specs = [s for s in spack.store.db.query(**kwargs)]
values = ' '.join(self.values)
if values: if values:
specs = [x for x in specs if x.satisfies(values, strict=True)] specs = [x for x in specs if x.satisfies(values, strict=True)]
namespace.specs = specs return specs
_arguments['constraint'] = Args( _arguments['constraint'] = Args(
'constraint', nargs='*', action=ConstraintAction, 'constraint', nargs='*', action=ConstraintAction,
......
...@@ -22,16 +22,11 @@ ...@@ -22,16 +22,11 @@
# License along with this program; if not, write to the Free Software # License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
import argparse
import sys import sys
import llnl.util.tty as tty import llnl.util.tty as tty
import spack import spack.cmd.common.arguments as arguments
import spack.spec
import spack.store
from llnl.util.lang import *
from llnl.util.tty.colify import *
from llnl.util.tty.color import *
from spack.cmd import display_specs from spack.cmd import display_specs
description = "Find installed spack packages" description = "Find installed spack packages"
...@@ -43,6 +38,7 @@ def setup_parser(subparser): ...@@ -43,6 +38,7 @@ def setup_parser(subparser):
action='store_const', action='store_const',
dest='mode', dest='mode',
const='short', const='short',
default='short',
help='Show only specs (default)') help='Show only specs (default)')
format_group.add_argument('-p', '--paths', format_group.add_argument('-p', '--paths',
action='store_const', action='store_const',
...@@ -68,12 +64,12 @@ def setup_parser(subparser): ...@@ -68,12 +64,12 @@ def setup_parser(subparser):
action='store_true', action='store_true',
dest='show_flags', dest='show_flags',
help='Show spec compiler flags.') help='Show spec compiler flags.')
implicit_explicit = subparser.add_mutually_exclusive_group()
subparser.add_argument( implicit_explicit.add_argument(
'-e', '--explicit', '-e', '--explicit',
action='store_true', action='store_true',
help='Show only specs that were installed explicitly') help='Show only specs that were installed explicitly')
subparser.add_argument( implicit_explicit.add_argument(
'-E', '--implicit', '-E', '--implicit',
action='store_true', action='store_true',
help='Show only specs that were installed as dependencies') help='Show only specs that were installed as dependencies')
...@@ -100,17 +96,10 @@ def setup_parser(subparser): ...@@ -100,17 +96,10 @@ def setup_parser(subparser):
action='store_true', action='store_true',
help='Show fully qualified package names.') help='Show fully qualified package names.')
subparser.add_argument('query_specs', arguments.add_common_arguments(subparser, ['constraint'])
nargs=argparse.REMAINDER,
help='optional specs to filter results')
def query_arguments(args): def query_arguments(args):
# Check arguments
if args.explicit and args.implicit:
tty.error('You can\'t pass -E and -e options simultaneously.')
raise SystemExit(1)
# Set up query arguments. # Set up query arguments.
installed, known = True, any installed, known = True, any
if args.only_missing: if args.only_missing:
...@@ -129,35 +118,17 @@ def query_arguments(args): ...@@ -129,35 +118,17 @@ def query_arguments(args):
def find(parser, args): def find(parser, args):
# Filter out specs that don't exist.
query_specs = spack.cmd.parse_specs(args.query_specs)
query_specs, nonexisting = partition_list(
query_specs, lambda s: spack.repo.exists(s.name) or not s.name)
if nonexisting:
msg = "No such package%s: " % ('s' if len(nonexisting) > 1 else '')
msg += ", ".join(s.name for s in nonexisting)
tty.msg(msg)
if not query_specs:
return
q_args = query_arguments(args) q_args = query_arguments(args)
query_specs = args.specs(**q_args)
# Get all the specs the user asked for # Exit early if no package matches the constraint
if not query_specs: if not query_specs:
specs = set(spack.store.db.query(**q_args)) msg = "No package matches the query: {0}".format(args.contraint)
else: tty.msg(msg)
results = [set(spack.store.db.query(qs, **q_args)) return
for qs in query_specs] # Display the result
specs = set.union(*results)
if not args.mode:
args.mode = 'short'
if sys.stdout.isatty(): if sys.stdout.isatty():
tty.msg("%d installed packages." % len(specs)) tty.msg("%d installed packages." % len(query_specs))
display_specs(specs, display_specs(query_specs,
mode=args.mode, mode=args.mode,
long=args.long, long=args.long,
very_long=args.very_long, very_long=args.very_long,
......
...@@ -244,17 +244,17 @@ def module(parser, args): ...@@ -244,17 +244,17 @@ def module(parser, args):
'known': True 'known': True
}, },
} }
arguments.ConstraintAction.qualifiers.update(constraint_qualifiers) query_args = constraint_qualifiers.get(args.subparser_name, {})
specs = args.specs(**query_args)
module_type = args.module_type module_type = args.module_type
constraint = args.constraint constraint = args.constraint
try: try:
callbacks[args.subparser_name](module_type, args.specs, args) callbacks[args.subparser_name](module_type, specs, args)
except MultipleMatches: except MultipleMatches:
message = ('the constraint \'{query}\' matches multiple packages, ' message = ('the constraint \'{query}\' matches multiple packages, '
'and this is not allowed in this context') 'and this is not allowed in this context')
tty.error(message.format(query=constraint)) tty.error(message.format(query=constraint))
for s in args.specs: for s in specs:
sys.stderr.write(s.format(color=True) + '\n') sys.stderr.write(s.format(color=True) + '\n')
raise SystemExit(1) raise SystemExit(1)
except NoMatch: except NoMatch:
......
...@@ -52,5 +52,3 @@ def test_query_arguments(self): ...@@ -52,5 +52,3 @@ def test_query_arguments(self):
args.implicit = True args.implicit = True
q_args = query_arguments(args) q_args = query_arguments(args)
self.assertEqual(q_args['explicit'], False) self.assertEqual(q_args['explicit'], False)
args.explicit = True
self.assertRaises(SystemExit, query_arguments, args)
...@@ -34,7 +34,7 @@ class TestModule(spack.test.mock_database.MockDatabase): ...@@ -34,7 +34,7 @@ class TestModule(spack.test.mock_database.MockDatabase):
def _get_module_files(self, args): def _get_module_files(self, args):
return [modules.module_types[args.module_type](spec).file_name return [modules.module_types[args.module_type](spec).file_name
for spec in args.specs] for spec in args.specs()]
def test_module_common_operations(self): def test_module_common_operations(self):
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment