From 6400ace90152a08a32684f97490369467ae1e37d Mon Sep 17 00:00:00 2001
From: Todd Gamblin <tgamblin@llnl.gov>
Date: Mon, 26 Jan 2015 15:45:19 -0800
Subject: [PATCH] Add "spack extensions" command to list activated extensions.

---
 lib/spack/spack/cmd/extensions.py | 75 +++++++++++++++++++++++++++++++
 lib/spack/spack/cmd/find.py       | 69 +++++++++++++++++-----------
 2 files changed, 117 insertions(+), 27 deletions(-)
 create mode 100644 lib/spack/spack/cmd/extensions.py

diff --git a/lib/spack/spack/cmd/extensions.py b/lib/spack/spack/cmd/extensions.py
new file mode 100644
index 0000000000..961d7e3f24
--- /dev/null
+++ b/lib/spack/spack/cmd/extensions.py
@@ -0,0 +1,75 @@
+##############################################################################
+# Copyright (c) 2013, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Written by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://scalability-llnl.github.io/spack
+# Please also see the LICENSE file for our notice and the LGPL.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License (as published by
+# the Free Software Foundation) version 2.1 dated February 1999.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the IMPLIED WARRANTY OF
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the terms and
+# conditions of the GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public 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 sys
+from external import argparse
+
+import llnl.util.tty as tty
+
+import spack
+import spack.cmd
+import spack.cmd.find
+
+description = "List extensions for package."
+
+def setup_parser(subparser):
+    format_group = subparser.add_mutually_exclusive_group()
+    format_group.add_argument(
+        '-l', '--long', action='store_const', dest='mode', const='long',
+        help='Show dependency hashes as well as versions.')
+    format_group.add_argument(
+        '-p', '--paths', action='store_const', dest='mode', const='paths',
+        help='Show paths to extension install directories')
+    format_group.add_argument(
+        '-d', '--deps', action='store_const', dest='mode', const='deps',
+        help='Show full dependency DAG of extensions')
+
+    subparser.add_argument(
+        'spec', nargs=argparse.REMAINDER, help='Spec of package to list extensions for')
+
+
+def extensions(parser, args):
+    if not args.spec:
+        tty.die("extensions requires a package spec.")
+
+    spec = spack.cmd.parse_specs(args.spec)
+    if len(spec) > 1:
+        tty.die("Can only list extensions for one package.")
+    spec = spack.cmd.disambiguate_spec(spec[0])
+
+    if not spec.package.extendable:
+        tty.die("%s does not have extensions." % spec.short_spec)
+
+    if not args.mode:
+        args.mode = 'short'
+
+    exts = spack.install_layout.get_extensions(spec)
+    if not exts:
+        tty.msg("%s has no activated extensions." % spec.short_spec)
+    else:
+        tty.msg("Showing %d activated extension%s for package:"
+                % (len(exts), 's' if len(exts) > 1 else ''),
+                spec.short_spec)
+        print
+        spack.cmd.find.display_specs(exts, mode=args.mode)
diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py
index 1de3413d42..f6f503afe5 100644
--- a/lib/spack/spack/cmd/find.py
+++ b/lib/spack/spack/cmd/find.py
@@ -41,13 +41,13 @@
 def setup_parser(subparser):
     format_group = subparser.add_mutually_exclusive_group()
     format_group.add_argument(
-        '-l', '--long', action='store_true', dest='long',
+        '-l', '--long', action='store_const', dest='mode', const='long',
         help='Show dependency hashes as well as versions.')
     format_group.add_argument(
-        '-p', '--paths', action='store_true', dest='paths',
+        '-p', '--paths', action='store_const', dest='mode', const='paths',
         help='Show paths to package install directories')
     format_group.add_argument(
-        '-d', '--deps', action='store_true', dest='full_deps',
+        '-d', '--deps', action='store_const', dest='mode', const='deps',
         help='Show full dependency DAG of installed packages')
 
     subparser.add_argument(
@@ -55,26 +55,8 @@ def setup_parser(subparser):
         help='optional specs to filter results')
 
 
-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.db.exists(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
-
-    # Get all the specs the user asked for
-    if not query_specs:
-        specs = set(spack.db.installed_package_specs())
-    else:
-        results = [set(spack.db.get_installed(qs)) for qs in query_specs]
-        specs = set.union(*results)
+def display_specs(specs, **kwargs):
+    mode = kwargs.get('mode', 'short')
 
     # Make a dict with specs keyed by architecture and compiler.
     index = index_by(specs, ('architecture', 'compiler'))
@@ -92,7 +74,7 @@ def find(parser, args):
         specs.sort()
 
         abbreviated = [s.format('$_$@$+', color=True) for s in specs]
-        if args.paths:
+        if mode == 'paths':
             # Print one spec per line along with prefix path
             width = max(len(s) for s in abbreviated)
             width += 2
@@ -101,11 +83,44 @@ def find(parser, args):
             for abbrv, spec in zip(abbreviated, specs):
                 print format % (abbrv, spec.prefix)
 
-        elif args.full_deps:
+        elif mode == 'deps':
             for spec in specs:
                 print spec.tree(indent=4, format='$_$@$+', color=True),
-        else:
+
+        elif mode in ('short', 'long'):
             fmt = '$-_$@$+'
-            if args.long:
+            if mode == 'long':
                 fmt += '$#'
             colify(s.format(fmt, color=True) for s in specs)
+
+        else:
+            raise ValueError(
+                "Invalid mode for display_specs: %s. Must be one of (paths, deps, short)." % mode)
+
+
+
+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.db.exists(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
+
+    # Get all the specs the user asked for
+    if not query_specs:
+        specs = set(spack.db.installed_package_specs())
+    else:
+        results = [set(spack.db.get_installed(qs)) for qs in query_specs]
+        specs = set.union(*results)
+
+    if not args.mode:
+        args.mode = 'short'
+    display_specs(specs, mode=args.mode)
+
-- 
GitLab