From 1f9dfeb9b52d8be22d0d14a3cf88dd2442d6cdbd Mon Sep 17 00:00:00 2001 From: Todd Gamblin Date: Mon, 14 Apr 2014 12:53:23 -0700 Subject: Clean up find command, move code to utils. --- lib/spack/llnl/util/lang.py | 16 ++++++++++ lib/spack/llnl/util/tty/__init__.py | 61 +++++++++++++++++++++++++++++++++++++ lib/spack/llnl/util/tty/colify.py | 26 ++-------------- lib/spack/spack/cmd/find.py | 49 ++++++++++------------------- lib/spack/spack/package.py | 5 +-- 5 files changed, 99 insertions(+), 58 deletions(-) (limited to 'lib') diff --git a/lib/spack/llnl/util/lang.py b/lib/spack/llnl/util/lang.py index 034c3b374d..9a21c5be5c 100644 --- a/lib/spack/llnl/util/lang.py +++ b/lib/spack/llnl/util/lang.py @@ -31,6 +31,22 @@ import inspect # Ignore emacs backups when listing modules ignore_modules = [r'^\.#', '~$'] + +def partition_list(elements, predicate): + """Partition a list into two lists, the first containing elements + for which the predicate evaluates to true, the second containing + those for which it is false. + """ + trues = [] + falses = [] + for elt in elements: + if predicate(elt): + trues.append(elt) + else: + falses.append(elt) + return trues, falses + + def caller_locals(): """This will return the locals of the *parent* of the caller. This allows a fucntion to insert variables into its caller's diff --git a/lib/spack/llnl/util/tty/__init__.py b/lib/spack/llnl/util/tty/__init__.py index 0e5ddab5fe..fcbafa82a7 100644 --- a/lib/spack/llnl/util/tty/__init__.py +++ b/lib/spack/llnl/util/tty/__init__.py @@ -23,7 +23,10 @@ # Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ############################################################################## import sys +import os import textwrap +from StringIO import StringIO + from llnl.util.tty.color import * debug = False @@ -97,3 +100,61 @@ def get_number(prompt, **kwargs): elif default is not None: number = default return number + + +def hline(label=None, **kwargs): + """Draw an optionally colored or labeled horizontal line. + Options: + + char Char to draw the line with. Default '-' + color Color of the label. Default is no color. + max_width Maximum width of the line. Default is 64 chars. + + See tty.color for possible color formats. + """ + char = kwargs.get('char', '-') + color = kwargs.get('color', '') + max_width = kwargs.get('max_width', 64) + + cols, rows = terminal_size() + if not cols: + cols = max_width + else: + cols -= 2 + cols = min(max_width, cols) + + label = str(label) + prefix = char * 2 + " " + label + " " + suffix = (cols - len(prefix)) * char + + out = StringIO() + if color: + prefix = char * 2 + " " + color + cescape(label) + "@. " + cwrite(prefix, stream=out, color=True) + else: + out.write(prefix) + out.write(suffix) + + print out.getvalue() + + +def terminal_size(): + """Gets the dimensions of the console: cols, rows.""" + def ioctl_GWINSZ(fd): + try: + cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) + except: + return + return cr + cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) + if not cr: + try: + fd = os.open(os.ctermid(), os.O_RDONLY) + cr = ioctl_GWINSZ(fd) + os.close(fd) + except: + pass + if not cr: + cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) + + return int(cr[1]), int(cr[0]) diff --git a/lib/spack/llnl/util/tty/colify.py b/lib/spack/llnl/util/tty/colify.py index 1f66416e69..1b04f1012f 100644 --- a/lib/spack/llnl/util/tty/colify.py +++ b/lib/spack/llnl/util/tty/colify.py @@ -38,27 +38,7 @@ import fcntl import termios import struct -def get_terminal_size(): - """Get the dimensions of the console.""" - def ioctl_GWINSZ(fd): - try: - cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234')) - except: - return - return cr - cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2) - if not cr: - try: - fd = os.open(os.ctermid(), os.O_RDONLY) - cr = ioctl_GWINSZ(fd) - os.close(fd) - except: - pass - if not cr: - cr = (os.environ.get('LINES', 25), os.environ.get('COLUMNS', 80)) - - return int(cr[1]), int(cr[0]) - +from llnl.util.tty import terminal_size class ColumnConfig: def __init__(self, cols): @@ -135,7 +115,7 @@ def colify(elts, **options): console_cols = options.get("cols", None) if not console_cols: - console_cols, console_rows = get_terminal_size() + console_cols, console_rows = terminal_size() elif type(console_cols) != int: raise ValueError("Number of columns must be an int") console_cols = max(1, console_cols - indent) @@ -170,7 +150,7 @@ def colify(elts, **options): if __name__ == "__main__": import optparse - cols, rows = get_terminal_size() + cols, rows = terminal_size() parser = optparse.OptionParser() parser.add_option("-u", "--uniform", action="store_true", default=False, help="Use uniformly sized columns instead of variable-size.") diff --git a/lib/spack/spack/cmd/find.py b/lib/spack/spack/cmd/find.py index c3a92566ef..b354833751 100644 --- a/lib/spack/spack/cmd/find.py +++ b/lib/spack/spack/cmd/find.py @@ -26,13 +26,13 @@ import collections import argparse from StringIO import StringIO -from llnl.util.tty.colify import colify, get_terminal_size +import llnl.util.tty as tty +from llnl.util.tty.colify import colify from llnl.util.tty.color import * +from llnl.util.lang import partition_list import spack import spack.spec -import spack - description ="Find installed spack packages" @@ -48,42 +48,25 @@ def setup_parser(subparser): help='optional specs to filter results') -# TODO: move this and colify to tty. -def hline(label, char, color=''): - max_width = 64 - cols, rows = get_terminal_size() - if not cols: - cols = max_width - else: - cols -= 2 - cols = min(max_width, cols) - - label = str(label) - prefix = char * 2 + " " + label + " " - suffix = (cols - len(prefix)) * char - - out = StringIO() - if color: - prefix = char * 2 + " " + color + cescape(label) + "@. " - cwrite(prefix, stream=out, color=True) - else: - out.write(prefix) - out.write(suffix) - - return out.getvalue() - - def find(parser, args): def hasher(): return collections.defaultdict(hasher) - query_specs = [] - if args.query_specs: - query_specs = spack.cmd.parse_specs(args.query_specs, normalize=True) + # 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 '') + tty.msg(msg + ", ".join(s.name for s in nonexisting)) + if not query_specs: + return # Make a dict with specs keyed by architecture and compiler. index = hasher() for spec in spack.db.installed_package_specs(): + # Check whether this installed package matches any query. if query_specs and not any(spec.satisfies(q) for q in query_specs): continue @@ -93,9 +76,9 @@ def find(parser, args): # Traverse the index and print out each package for architecture in index: - print hline(architecture, "=", spack.spec.architecture_color) + tty.hline(architecture, char='=', color=spack.spec.architecture_color) for compiler in index[architecture]: - print hline(compiler, "-", spack.spec.compiler_color) + tty.hline(architecture, char='-', color=spack.spec.compiler_color) specs = index[architecture][compiler] specs.sort() diff --git a/lib/spack/spack/package.py b/lib/spack/spack/package.py index b3b1538b31..b3f2b1857d 100644 --- a/lib/spack/spack/package.py +++ b/lib/spack/spack/package.py @@ -326,7 +326,9 @@ class Package(object): """Controls whether install and uninstall check deps before running.""" ignore_dependencies = False - """Dirty hack for forcing packages with uninterpretable URLs""" + """Dirty hack for forcing packages with uninterpretable URLs + TODO: get rid of this. + """ force_url = False @@ -676,7 +678,6 @@ class Package(object): if os.path.exists(self.prefix): tty.msg("%s is already installed." % self.name) - print_pkg(self.prefix) return if not self.ignore_dependencies: -- cgit v1.2.3-60-g2f50