summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorMassimiliano Culpo <massimiliano.culpo@googlemail.com>2017-08-17 18:15:57 +0200
committerbecker33 <becker33@llnl.gov>2017-08-17 09:15:57 -0700
commit0f5582cefcfddf04cae2d345aa3d9d036e2feeda (patch)
tree2939d46f4a52f13747d43b5c41eca2b89d92c24b /lib
parentaa215900991f24108d255cd5ebd4a2a64663431b (diff)
downloadspack-0f5582cefcfddf04cae2d345aa3d9d036e2feeda.tar.gz
spack-0f5582cefcfddf04cae2d345aa3d9d036e2feeda.tar.bz2
spack-0f5582cefcfddf04cae2d345aa3d9d036e2feeda.tar.xz
spack-0f5582cefcfddf04cae2d345aa3d9d036e2feeda.zip
Colorize spack info. Adds prominence to preferred version. (#4994)
* Colorize spack info. Adds prominence to preferred version. fixes #2708 This uses 'llnl.util.tty.color' to colorize the output of 'spack info'. It also displays versions in the order the concretizer would choose them and shows the preferred in a line on its own and in bold. * Modified output according to Adam and Denis reviews. Section titles are not bold + black, but bold + blue. Added a new section named "Preferred version", which prints the preferred version in bold characters. * Further modifications according to Adam and Denis reviews. After "Homepage:" we now have a single space. Removed newline after each variant. Preferred version is not in bold fonts anymore. Added a simple test that just runs the command.
Diffstat (limited to 'lib')
-rw-r--r--lib/spack/spack/cmd/info.py110
-rw-r--r--lib/spack/spack/test/cmd/info.py40
2 files changed, 117 insertions, 33 deletions
diff --git a/lib/spack/spack/cmd/info.py b/lib/spack/spack/cmd/info.py
index 575b65f8b0..71ab5e3207 100644
--- a/lib/spack/spack/cmd/info.py
+++ b/lib/spack/spack/cmd/info.py
@@ -25,14 +25,22 @@
from __future__ import print_function
import textwrap
-from six.moves import zip_longest
-from llnl.util.tty.colify import *
+
+import llnl.util.tty.color as color
import spack
import spack.fetch_strategy as fs
+import spack.spec
+
+from llnl.util.tty.colify import *
-description = "get detailed information on a particular package"
-section = "basic"
-level = "short"
+from six.moves import zip_longest
+
+description = 'get detailed information on a particular package'
+section = 'basic'
+level = 'short'
+
+header_color = '@*b'
+plain_format = '@.'
def padder(str_list, extra=0):
@@ -48,11 +56,23 @@ def padder(str_list, extra=0):
def setup_parser(subparser):
subparser.add_argument(
- 'name', metavar="PACKAGE", help="name of package to get info for")
+ 'name', metavar='PACKAGE', help='name of package to get info for')
+
+
+def section_title(s):
+ return header_color + s + plain_format
+
+
+def version(s):
+ return spack.spec.version_color + s + plain_format
+
+
+def variant(s):
+ return spack.spec.enabled_variant_color + s + plain_format
class VariantFormatter(object):
- def __init__(self, variants, max_widths=(25, 20, 35)):
+ def __init__(self, variants, max_widths=(30, 20, 30)):
self.variants = variants
self.headers = ('Name [Default]', 'Allowed values', 'Description')
# Set max headers lengths
@@ -102,9 +122,9 @@ class VariantFormatter(object):
@property
def lines(self):
if not self.variants:
- yield " None"
+ yield ' None'
else:
- yield " " + self.fmt % self.headers
+ yield ' ' + self.fmt % self.headers
yield '\n'
for k, v in sorted(self.variants.items()):
name = textwrap.wrap(
@@ -123,61 +143,82 @@ class VariantFormatter(object):
name, allowed, description, fillvalue=''
):
yield " " + self.fmt % t
- yield '' # Trigger a new line
def print_text_info(pkg):
"""Print out a plain text description of a package."""
- header = "{0}: ".format(pkg.build_system_class)
- print(header, pkg.name)
+ header = section_title(
+ '{0}: '
+ ).format(pkg.build_system_class) + pkg.name
+ color.cprint(header)
- print()
- print("Description:")
+ color.cprint('')
+ color.cprint(section_title('Description:'))
if pkg.__doc__:
print(pkg.format_doc(indent=4))
else:
print(" None")
- whitespaces = ''.join([' '] * (len(header) - len("Homepage: ")))
- print("Homepage:", whitespaces, pkg.homepage)
+ color.cprint(section_title('Homepage: ') + pkg.homepage)
- print()
- print("Safe versions: ")
+ color.cprint('')
+ color.cprint(section_title('Preferred version: '))
if not pkg.versions:
- print(" None")
+ color.cprint(version(' None'))
+ color.cprint('')
+ color.cprint(section_title('Safe versions: '))
+ color.cprint(version(' None'))
else:
pad = padder(pkg.versions, 4)
+
+ # Here we sort first on the fact that a version is marked
+ # as preferred in the package, then on the fact that the
+ # version is not develop, then lexicographically
+ l = [
+ (value.get('preferred', False), not key.isdevelop(), key)
+ for key, value in pkg.versions.items()
+ ]
+ l = sorted(l)
+ _, _, preferred = l.pop()
+
+ f = fs.for_package_version(pkg, preferred)
+ line = version(' {0}'.format(pad(preferred))) + str(f)
+ color.cprint(line)
+ color.cprint('')
+ color.cprint(section_title('Safe versions: '))
+
for v in reversed(sorted(pkg.versions)):
f = fs.for_package_version(pkg, v)
- print(" %s%s" % (pad(v), str(f)))
+ line = version(' {0}'.format(pad(v))) + str(f)
+ color.cprint(line)
- print()
- print("Variants:")
+ color.cprint('')
+ color.cprint(section_title('Variants:'))
formatter = VariantFormatter(pkg.variants)
for line in formatter.lines:
- print(line)
+ color.cprint(line)
- print()
- print("Installation Phases:")
+ color.cprint('')
+ color.cprint(section_title('Installation Phases:'))
phase_str = ''
for phase in pkg.phases:
phase_str += " {0}".format(phase)
- print(phase_str)
+ color.cprint(phase_str)
for deptype in ('build', 'link', 'run'):
- print()
- print("%s Dependencies:" % deptype.capitalize())
+ color.cprint('')
+ color.cprint(section_title('%s Dependencies:' % deptype.capitalize()))
deps = sorted(pkg.dependencies_of_type(deptype))
if deps:
colify(deps, indent=4)
else:
- print(" None")
+ print(' None')
- print()
- print("Virtual Packages: ")
+ color.cprint('')
+ color.cprint(section_title('Virtual Packages: '))
if pkg.provided:
inverse_map = {}
for spec, whens in pkg.provided.items():
@@ -186,8 +227,11 @@ def print_text_info(pkg):
inverse_map[when] = set()
inverse_map[when].add(spec)
for when, specs in reversed(sorted(inverse_map.items())):
- print(" %s provides %s" % (
- when, ', '.join(str(s) for s in specs)))
+ line = " %s provides %s" % (
+ when.colorized(), ', '.join(s.colorized() for s in specs)
+ )
+ print(line)
+
else:
print(" None")
diff --git a/lib/spack/spack/test/cmd/info.py b/lib/spack/spack/test/cmd/info.py
new file mode 100644
index 0000000000..9819f2cd84
--- /dev/null
+++ b/lib/spack/spack/test/cmd/info.py
@@ -0,0 +1,40 @@
+##############################################################################
+# Copyright (c) 2013-2017, Lawrence Livermore National Security, LLC.
+# Produced at the Lawrence Livermore National Laboratory.
+#
+# This file is part of Spack.
+# Created by Todd Gamblin, tgamblin@llnl.gov, All rights reserved.
+# LLNL-CODE-647188
+#
+# For details, see https://github.com/llnl/spack
+# Please also see the NOTICE and LICENSE files 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 Lesser General Public License (as
+# published by the Free Software Foundation) version 2.1, 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 Lesser 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 pytest
+
+from spack.main import SpackCommand
+
+info = SpackCommand('info')
+
+
+@pytest.mark.parametrize('pkg', [
+ 'openmpi',
+ 'trilinos',
+ 'boost',
+ 'python',
+ 'dealii'
+])
+def test_it_just_runs(pkg):
+ info(pkg)