summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@googlemail.com>2016-11-03 08:45:15 +0100
committerTodd Gamblin <tgamblin@llnl.gov>2016-11-03 00:45:15 -0700
commit5b5894afba1c81b286582f4dda8a8f1c94314db7 (patch)
treef99ea6d090761965b072d10d979a0645d052dc16
parentb706da1109e5bf71f3f7ffd56598677ebb9c3dad (diff)
downloadspack-5b5894afba1c81b286582f4dda8a8f1c94314db7.tar.gz
spack-5b5894afba1c81b286582f4dda8a8f1c94314db7.tar.bz2
spack-5b5894afba1c81b286582f4dda8a8f1c94314db7.tar.xz
spack-5b5894afba1c81b286582f4dda8a8f1c94314db7.zip
spack find: accepts anonymous specs as arguments fixes #2170 (#2188)
-rw-r--r--lib/spack/spack/cmd/common/arguments.py20
-rw-r--r--lib/spack/spack/cmd/find.py59
-rw-r--r--lib/spack/spack/cmd/module.py8
-rw-r--r--lib/spack/spack/test/cmd/find.py2
-rw-r--r--lib/spack/spack/test/cmd/module.py2
5 files changed, 33 insertions, 58 deletions
diff --git a/lib/spack/spack/cmd/common/arguments.py b/lib/spack/spack/cmd/common/arguments.py
index ade6844813..d5bd4bb711 100644
--- a/lib/spack/spack/cmd/common/arguments.py
+++ b/lib/spack/spack/cmd/common/arguments.py
@@ -46,19 +46,25 @@ class ConstraintAction(argparse.Action):
"""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
- in a parser. It will read a constraint and will attach a list of matching
- specs to the namespace
+ in a parser. It will read a constraint and will attach a function to the
+ 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):
# Query specs from command line
- d = self.qualifiers.get(namespace.subparser_name, {})
- specs = [s for s in spack.store.db.query(**d)]
- values = ' '.join(values)
+ self.values = values
+ namespace.contraint = 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:
specs = [x for x in specs if x.satisfies(values, strict=True)]
- namespace.specs = specs
+ return specs
+
_arguments['constraint'] = Args(
'constraint', nargs='*', action=ConstraintAction,
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 50e6112486..29bf263f51 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -22,16 +22,11 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
##############################################################################
-import argparse
import sys
import llnl.util.tty as tty
-import spack
-import spack.spec
-import spack.store
-from llnl.util.lang import *
-from llnl.util.tty.colify import *
-from llnl.util.tty.color import *
+import spack.cmd.common.arguments as arguments
+
from spack.cmd import display_specs
description = "Find installed spack packages"
@@ -43,6 +38,7 @@ def setup_parser(subparser):
action='store_const',
dest='mode',
const='short',
+ default='short',
help='Show only specs (default)')
format_group.add_argument('-p', '--paths',
action='store_const',
@@ -68,12 +64,12 @@ def setup_parser(subparser):
action='store_true',
dest='show_flags',
help='Show spec compiler flags.')
-
- subparser.add_argument(
+ implicit_explicit = subparser.add_mutually_exclusive_group()
+ implicit_explicit.add_argument(
'-e', '--explicit',
action='store_true',
help='Show only specs that were installed explicitly')
- subparser.add_argument(
+ implicit_explicit.add_argument(
'-E', '--implicit',
action='store_true',
help='Show only specs that were installed as dependencies')
@@ -100,17 +96,10 @@ def setup_parser(subparser):
action='store_true',
help='Show fully qualified package names.')
- subparser.add_argument('query_specs',
- nargs=argparse.REMAINDER,
- help='optional specs to filter results')
+ arguments.add_common_arguments(subparser, ['constraint'])
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.
installed, known = True, any
if args.only_missing:
@@ -129,35 +118,17 @@ def query_arguments(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)
-
- # Get all the specs the user asked for
+ query_specs = args.specs(**q_args)
+ # Exit early if no package matches the constraint
if not query_specs:
- specs = set(spack.store.db.query(**q_args))
- else:
- results = [set(spack.store.db.query(qs, **q_args))
- for qs in query_specs]
- specs = set.union(*results)
-
- if not args.mode:
- args.mode = 'short'
-
+ msg = "No package matches the query: {0}".format(args.contraint)
+ tty.msg(msg)
+ return
+ # Display the result
if sys.stdout.isatty():
- tty.msg("%d installed packages." % len(specs))
- display_specs(specs,
+ tty.msg("%d installed packages." % len(query_specs))
+ display_specs(query_specs,
mode=args.mode,
long=args.long,
very_long=args.very_long,
diff --git a/lib/spack/spack/cmd/module.py b/lib/spack/spack/cmd/module.py
index d7abe0fa87..31460b3124 100644
--- a/lib/spack/spack/cmd/module.py
+++ b/lib/spack/spack/cmd/module.py
@@ -244,17 +244,17 @@ def module(parser, args):
'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
constraint = args.constraint
try:
- callbacks[args.subparser_name](module_type, args.specs, args)
+ callbacks[args.subparser_name](module_type, specs, args)
except MultipleMatches:
message = ('the constraint \'{query}\' matches multiple packages, '
'and this is not allowed in this context')
tty.error(message.format(query=constraint))
- for s in args.specs:
+ for s in specs:
sys.stderr.write(s.format(color=True) + '\n')
raise SystemExit(1)
except NoMatch:
diff --git a/lib/spack/spack/test/cmd/find.py b/lib/spack/spack/test/cmd/find.py
index fa82db7733..4788da8ec6 100644
--- a/lib/spack/spack/test/cmd/find.py
+++ b/lib/spack/spack/test/cmd/find.py
@@ -52,5 +52,3 @@ class FindTest(unittest.TestCase):
args.implicit = True
q_args = query_arguments(args)
self.assertEqual(q_args['explicit'], False)
- args.explicit = True
- self.assertRaises(SystemExit, query_arguments, args)
diff --git a/lib/spack/spack/test/cmd/module.py b/lib/spack/spack/test/cmd/module.py
index 3a0ce32e6c..39f9c5649f 100644
--- a/lib/spack/spack/test/cmd/module.py
+++ b/lib/spack/spack/test/cmd/module.py
@@ -34,7 +34,7 @@ class TestModule(spack.test.mock_database.MockDatabase):
def _get_module_files(self, args):
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):
parser = argparse.ArgumentParser()