Example #1
0
def list(terse=False, show_command=False, regex=None):
    Namespace = pymod.module.Namespace
    loaded_modules = pymod.mc.get_loaded_modules()
    if not loaded_modules:
        return "No loaded modules\n"

    sio = StringIO()
    loaded_module_names = []
    for loaded in loaded_modules:
        fullname = loaded.fullname
        if loaded.opts:
            fullname += " " + Namespace(**(loaded.opts)).joined(" ")
        loaded_module_names.append(fullname)

    if terse:
        sio.write("\n".join(loaded_module_names))
    elif show_command:
        for module in loaded_module_names:
            sio.write("module load {0}\n".format(module))
    else:
        sio.write("Currently loaded modules\n")
        loaded = [
            "{0}) {1}".format(i + 1, m)
            for (i, m) in enumerate(loaded_module_names)
        ]
        _, width = terminal_size()
        sio.write(colified(loaded, indent=4, width=max(100, width)))

    s = sio.getvalue()
    if regex:
        s = grep_pat_in_string(s, regex, color="G")

    return s
Example #2
0
 def avail_full(self, regex=None, long_format=False):
     sio = StringIO()
     sio.write("\n")
     _, width = tty.terminal_size()
     # head = lambda x: (" " + x + " ").center(width, "-")
     for path in self:
         directory = path.path
         modules = sorted([m for m in path.modules if m.is_enabled],
                          key=self.sort_key)
         modules = self.filter_modules_by_regex(modules, regex)
         if not os.path.isdir(directory):  # pragma: no cover
             s = colorize("@r{(Directory not readable)}".center(width))
         elif not modules:  # pragma: no cover
             if regex:
                 continue
             s = colorize("@r{(None)}".center(width))
         else:
             modules = [
                 self.colorize(m.format_dl_status()) for m in modules
             ]
             aliases = pymod.alias.get(directory)
             if aliases:  # pragma: no cover
                 for (alias, target) in aliases:
                     i = bisect.bisect_left(modules, alias)
                     insert_key = colorize("@M{%s}@@" % (alias))
                     if long_format:  # pragma: no cover
                         insert_key += " -> %s" % (target)
                     modules.insert(i, insert_key)
             s = colified(modules, width=width)
         directory = directory.replace(os.path.expanduser("~/"), "~/")
         # sio.write(head(directory) + '\n')
         sio.write(colorize("@G{%s}:\n" % (directory)))
         sio.write(s + "\n")
     return sio.getvalue()
Example #3
0
def textfill(string, width=None, indent=None, **kwds):
    if width is None:
        _, width = terminal_size()
    if indent is not None:
        kwds["initial_indent"] = " " * indent
        kwds["subsequent_indent"] = " " * indent
    s = textwrap.fill(string, width, **kwds)
    return s
Example #4
0
def colify(elts, **options):
    # Get keyword arguments or set defaults
    output = options.get("output", sys.stdout)
    indent = options.get("indent", 0)
    padding = options.get("padding", 2)
    tty = options.get('tty', None)

    # elts needs to be an array of strings so we can count the elements
    elts = [str(elt) for elt in elts]
    if not elts:
        return (0, ())

    if not tty:
        if tty is False or not isatty(output):
            for elt in elts:
                output.write("%s\n" % elt)

            maxlen = max(len(str(s)) for s in elts)
            return (1, (maxlen, ))

    console_cols = options.get("cols", None)
    if not console_cols:
        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)

    method = options.get("method", "variable")
    if method == "variable":
        config = config_variable_cols(elts, console_cols, padding)
    elif method == "uniform":
        config = config_uniform_cols(elts, console_cols, padding)
    else:
        raise ValueError("method must be one of: " + allowed_methods)

    cols = config.cols
    formats = ["%%-%ds" % width for width in config.widths[:-1]]
    formats.append("%s")  # last column has no trailing space

    rows = (len(elts) + cols - 1) / cols
    rows_last_col = len(elts) % rows

    for row in xrange(rows):
        output.write(" " * indent)
        for col in xrange(cols):
            elt = col * rows + row
            output.write(formats[col] % elts[elt])

        output.write("\n")
        row += 1
        if row == rows_last_col:
            cols -= 1

    return (config.cols, tuple(config.widths))
Example #5
0
 def avail(self, terse=False):
     names = sorted([x for x in self.data.keys()])
     if not names:  # pragma: no cover
         return ""
     sio = StringIO()
     if not terse:
         _, width = terminal_size()
         s = colified(names, width=width)
         sio.write("{0}\n{1}\n".format(" Saved clones ".center(width, "-"), s))
     else:
         sio.write("\n".join(c for c in names))
     return sio.getvalue()
Example #6
0
    def __init__(self, variants):
        self.variants = variants
        self.headers = ('Name [Default]', 'When', 'Allowed values',
                        'Description')

        # Formats
        fmt_name = '{0} [{1}]'

        # Initialize column widths with the length of the
        # corresponding headers, as they cannot be shorter
        # than that
        self.column_widths = [len(x) for x in self.headers]

        # Expand columns based on max line lengths
        for k, e in variants.items():
            v, w = e
            candidate_max_widths = (
                len(fmt_name.format(k, self.default(v))),  # Name [Default]
                len(str(w)),
                len(v.allowed_values),  # Allowed values
                len(v.description)  # Description
            )

            self.column_widths = (max(self.column_widths[0],
                                      candidate_max_widths[0]),
                                  max(self.column_widths[1],
                                      candidate_max_widths[1]),
                                  max(self.column_widths[2],
                                      candidate_max_widths[2]),
                                  max(self.column_widths[3],
                                      candidate_max_widths[3]))

        # Don't let name or possible values be less than max widths
        _, cols = tty.terminal_size()
        max_name = min(self.column_widths[0], 30)
        max_when = min(self.column_widths[1], 30)
        max_vals = min(self.column_widths[2], 20)

        # allow the description column to extend as wide as the terminal.
        max_description = min(
            self.column_widths[3],
            # min width 70 cols, 14 cols of margins and column spacing
            max(cols, 70) - max_name - max_vals - 14,
        )
        self.column_widths = (max_name, max_when, max_vals, max_description)

        # Compute the format
        self.fmt = "%%-%ss%%-%ss%%-%ss%%s" % (self.column_widths[0] + 4,
                                              self.column_widths[1] + 4,
                                              self.column_widths[2] + 4)
Example #7
0
    def format_help(self):
        if self.helpstr is None:
            return "{0}: no help string provided".format(self.fullname)

        sio = StringIO()
        _, width = terminal_size()
        rule = "=" * width
        head = "{0}".format((" " + self.name + " ").center(width, "="))
        sio.write(head + "\n")
        sio.write(fill(self.helpstr) + "\n")
        option_help = self.option_help_string()
        if option_help:  # pragma: no cover
            sio.write("\n" + option_help + "\n")
        sio.write(rule)
        return sio.getvalue()
Example #8
0
def colify(elts, **options):
    # Get keyword arguments or set defaults
    output       = options.get("output", sys.stdout)
    indent       = options.get("indent", 0)
    padding      = options.get("padding", 2)

    # elts needs to be an array of strings so we can count the elements
    elts = [str(elt) for elt in elts]
    if not elts:
        return

    if not isatty(output):
        for elt in elts:
            output.write("%s\n" % elt)
        return

    console_cols = options.get("cols", None)
    if not console_cols:
        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)

    method = options.get("method", "variable")
    if method == "variable":
        config = config_variable_cols(elts, console_cols, padding)
    elif method == "uniform":
        config = config_uniform_cols(elts, console_cols, padding)
    else:
        raise ValueError("method must be one of: " + allowed_methods)

    cols = config.cols
    formats = ["%%-%ds" % width for width in config.widths[:-1]]
    formats.append("%s")  # last column has no trailing space

    rows = (len(elts) + cols - 1) / cols
    rows_last_col = len(elts) % rows

    for row in xrange(rows):
        output.write(" " * indent)
        for col in xrange(cols):
            elt = col * rows + row
            output.write(formats[col] % elts[elt])

        output.write("\n")
        row += 1
        if row == rows_last_col:
            cols -= 1
Example #9
0
 def format_whatis(self):
     if not self.whatisstr:  # pragma: no cover
         return '{0}: no "whatis" description has been provided'.format(
             self.fullname)
     sio = StringIO()
     _, width = terminal_size()
     rule = "=" * width
     head = "{0}".format((" " + self.name + " ").center(width, "="))
     text_width = min(width, 80)
     sio.write(head + "\n")
     sio.write(fill(self.whatisstr, width=text_width) + "\n")
     option_help = self.option_help_string()
     if option_help:  # pragma: no cover
         sio.write("\n" + option_help + "\n")
     sio.write(rule)
     return sio.getvalue()
Example #10
0
    def avail(self, terse=False, regex=None):
        skip = (pymod.names.default_user_collection, )
        names = sorted([x for x in self.data if x not in skip])

        if regex:
            names = self.filter_collections_by_regex(names, regex)

        if not names:  # pragma: no cover
            return ""

        sio = StringIO()
        if not terse:
            _, width = terminal_size()
            s = colified(names, width=width)
            # sio.write('{0}\n{1}\n'
            #          .format(' Saved collections '.center(width, '-'), s))
            sio.write(colorize("@G{Saved collections}:\n%s\n" % (s)))
        else:
            sio.write("\n".join(c for c in names))
        string = sio.getvalue()
        return string
Example #11
0
    def avail(self, terse=False):
        if not self.data:  # pragma: no cover
            return ""

        keys = sorted(list(self.data.keys()))
        fun = lambda key: "{0} -> {1} ({2})".format(
            key,
            self.data[key]["target"],
            colorize("@C{%s}" % self.data[key]["modulepath"]),
        )
        names = [fun(_) for _ in keys]

        sio = StringIO()
        if not terse:
            _, width = terminal_size()
            s = colified(names, width=width)
            sio.write("{0}\n{1}\n".format(" Aliases ".center(width, "-"), s))
        else:
            sio.write("{0}\n".format("\n".join(c for c in names)))
        string = sio.getvalue()
        return string
Example #12
0
File: colify.py Project: d-tk/spack
def colify(elts, **options):
    """Takes a list of elements as input and finds a good columnization
    of them, similar to how gnu ls does. This supports both
    uniform-width and variable-width (tighter) columns.

    If elts is not a list of strings, each element is first conveted
    using str().

    Keyword arguments:

    output=<stream>   A file object to write to.  Default is sys.stdout.
    indent=<int>      Optionally indent all columns by some number of spaces.
    padding=<int>     Spaces between columns.  Default is 2.
    width=<int>       Width of the output.  Default is 80 if tty is not detected.

    cols=<int>        Force number of columns. Default is to size to terminal,
                      or single-column if no tty

    tty=<bool>        Whether to attempt to write to a tty.  Default is to
                      autodetect a tty. Set to False to force single-column output.

    method=<string>   Method to use to fit columns.  Options are variable or uniform.
                      Variable-width columns are tighter, uniform columns are all the
                      same width and fit less data on the screen.
    """
    # Get keyword arguments or set defaults
    cols = options.pop("cols", 0)
    output = options.pop("output", sys.stdout)
    indent = options.pop("indent", 0)
    padding = options.pop("padding", 2)
    tty = options.pop("tty", None)
    method = options.pop("method", "variable")
    console_cols = options.pop("width", None)

    if options:
        raise TypeError("'%s' is an invalid keyword argument for this function." % next(options.iterkeys()))

    # elts needs to be an array of strings so we can count the elements
    elts = [str(elt) for elt in elts]
    if not elts:
        return (0, ())

    # environment size is of the form "<rows>x<cols>"
    env_size = os.environ.get("COLIFY_SIZE")
    if env_size:
        try:
            r, c = env_size.split("x")
            console_rows, console_cols = int(r), int(c)
            tty = True
        except:
            pass

    # Use only one column if not a tty.
    if not tty:
        if tty is False or not output.isatty():
            cols = 1

    # Specify the number of character columns to use.
    if not console_cols:
        console_rows, console_cols = terminal_size()
    elif type(console_cols) != int:
        raise ValueError("Number of columns must be an int")
    console_cols = max(1, console_cols - indent)

    # Choose a method.  Variable-width colums vs uniform-width.
    if method == "variable":
        config = config_variable_cols(elts, console_cols, padding, cols)
    elif method == "uniform":
        config = config_uniform_cols(elts, console_cols, padding, cols)
    else:
        raise ValueError("method must be one of: " + allowed_methods)

    cols = config.cols
    rows = (len(elts) + cols - 1) / cols
    rows_last_col = len(elts) % rows

    for row in xrange(rows):
        output.write(" " * indent)
        for col in xrange(cols):
            elt = col * rows + row
            width = config.widths[col] + cextra(elts[elt])
            fmt = "%%-%ds" % width
            output.write(fmt % elts[elt])

        output.write("\n")
        row += 1
        if row == rows_last_col:
            cols -= 1

    return (config.cols, tuple(config.widths))
Example #13
0
def make_log_context(log_events, width=None):
    """Get error context from a log file.

    Args:
        log_events (list): list of events created by
            ``ctest_log_parser.parse()``
        width (int or None): wrap width; ``0`` for no limit; ``None`` to
            auto-size for terminal
    Returns:
        str: context from the build log with errors highlighted

    Parses the log file for lines containing errors, and prints them out
    with line numbers and context.  Errors are highlighted with '>>' and
    with red highlighting (if color is enabled).

    Events are sorted by line number before they are displayed.
    """
    error_lines = set(e.line_no for e in log_events)
    log_events = sorted(log_events, key=lambda e: e.line_no)

    num_width = len(str(max(error_lines or [0]))) + 4
    line_fmt = '%%-%dd%%s' % num_width
    indent = ' ' * (5 + num_width)

    if width is None:
        _, width = tty.terminal_size()
    if width <= 0:
        width = sys.maxsize
    wrap_width = width - num_width - 6

    out = StringIO()
    next_line = 1
    for event in log_events:
        start = event.start

        if isinstance(event, BuildError):
            color = 'R'
        elif isinstance(event, BuildWarning):
            color = 'Y'
        else:
            color = 'W'

        if next_line != 1 and start > next_line:
            out.write('\n     ...\n\n')

        if start < next_line:
            start = next_line

        for i in range(start, event.end):
            # wrap to width
            lines = _wrap(event[i], wrap_width)
            lines[1:] = [indent + ln for ln in lines[1:]]
            wrapped_line = line_fmt % (i, '\n'.join(lines))

            if i in error_lines:
                out.write(
                    colorize('  @%s{>> %s}\n' %
                             (color, cescape(wrapped_line))))
            else:
                out.write('     %s\n' % wrapped_line)

        next_line = event.end

    return out.getvalue()
Example #14
0
def colify(elts, **options):
    """Takes a list of elements as input and finds a good columnization
    of them, similar to how gnu ls does. This supports both
    uniform-width and variable-width (tighter) columns.

    If elts is not a list of strings, each element is first conveted
    using ``str()``.

    Keyword Arguments:
        output (stream): A file object to write to. Default is ``sys.stdout``
        indent (int):    Optionally indent all columns by some number of spaces
        padding (int):   Spaces between columns. Default is 2
        width (int):     Width of the output. Default is 80 if tty not detected
        cols (int):      Force number of columns. Default is to size to
                         terminal, or single-column if no tty
        tty (bool):      Whether to attempt to write to a tty. Default is to
                         autodetect a tty. Set to False to force single-column
                         output
        method (str):    Method to use to fit columns. Options are variable or
                         uniform. Variable-width columns are tighter, uniform
                         columns are all the same width and fit less data on
                         the screen
    """
    # Get keyword arguments or set defaults
    cols         = options.pop("cols", 0)
    output       = options.pop("output", sys.stdout)
    indent       = options.pop("indent", 0)
    padding      = options.pop("padding", 2)
    tty          = options.pop('tty', None)
    method       = options.pop("method", "variable")
    console_cols = options.pop("width", None)

    if options:
        raise TypeError(
            "'%s' is an invalid keyword argument for this function."
            % next(options.iterkeys()))

    # elts needs to be an array of strings so we can count the elements
    elts = [text_type(elt) for elt in elts]
    if not elts:
        return (0, ())

    # environment size is of the form "<rows>x<cols>"
    env_size = os.environ.get('COLIFY_SIZE')
    if env_size:
        try:
            r, c = env_size.split('x')
            console_rows, console_cols = int(r), int(c)
            tty = True
        except BaseException:
            pass

    # Use only one column if not a tty.
    if not tty:
        if tty is False or not output.isatty():
            cols = 1

    # Specify the number of character columns to use.
    if not console_cols:
        console_rows, console_cols = terminal_size()
    elif type(console_cols) != int:
        raise ValueError("Number of columns must be an int")
    console_cols = max(1, console_cols - indent)

    # Choose a method.  Variable-width colums vs uniform-width.
    if method == "variable":
        config = config_variable_cols(elts, console_cols, padding, cols)
    elif method == "uniform":
        config = config_uniform_cols(elts, console_cols, padding, cols)
    else:
        raise ValueError("method must be either 'variable' or 'uniform'")

    cols = config.cols
    rows = (len(elts) + cols - 1) // cols
    rows_last_col = len(elts) % rows

    for row in range(rows):
        output.write(" " * indent)
        for col in range(cols):
            elt = col * rows + row
            width = config.widths[col] + cextra(elts[elt])
            if col < cols - 1:
                fmt = '%%-%ds' % width
                output.write(fmt % elts[elt])
            else:
                # Don't pad the rightmost column (sapces can wrap on
                # small teriminals if one line is overlong)
                output.write(elts[elt])

        output.write("\n")
        row += 1
        if row == rows_last_col:
            cols -= 1

    return (config.cols, tuple(config.widths))
Example #15
0
def make_log_context(log_events, width=None):
    """Get error context from a log file.

    Args:
        log_events (list of LogEvent): list of events created by
            ``ctest_log_parser.parse()``
        width (int or None): wrap width; ``0`` for no limit; ``None`` to
            auto-size for terminal
    Returns:
        str: context from the build log with errors highlighted

    Parses the log file for lines containing errors, and prints them out
    with line numbers and context.  Errors are highlighted with '>>' and
    with red highlighting (if color is enabled).

    Events are sorted by line number before they are displayed.
    """
    error_lines = set(e.line_no for e in log_events)
    log_events = sorted(log_events, key=lambda e: e.line_no)

    num_width = len(str(max(error_lines))) + 4
    line_fmt = '%%-%dd%%s' % num_width
    indent = ' ' * (5 + num_width)

    if width is None:
        _, width = tty.terminal_size()
    if width <= 0:
        width = sys.maxsize
    wrap_width = width - num_width - 6

    out = StringIO()
    next_line = 1
    for event in log_events:
        start = event.start

        if isinstance(event, BuildError):
            color = 'R'
        elif isinstance(event, BuildWarning):
            color = 'Y'
        else:
            color = 'W'

        if next_line != 1 and start > next_line:
            out.write('\n     ...\n\n')

        if start < next_line:
            start = next_line

        for i in range(start, event.end):
            # wrap to width
            lines = _wrap(event[i], wrap_width)
            lines[1:] = [indent + l for l in lines[1:]]
            wrapped_line = line_fmt % (i, '\n'.join(lines))

            if i in error_lines:
                out.write(colorize(
                    '  @%s{>> %s}\n' % (color, cescape(wrapped_line))))
            else:
                out.write('     %s\n' % wrapped_line)

        next_line = event.end

    return out.getvalue()
Example #16
0
    for row in xrange(rows):
        output.write(" " * indent)
        for col in xrange(cols):
            elt = col * rows + row
            output.write(formats[col] % elts[elt])

        output.write("\n")
        row += 1
        if row == rows_last_col:
            cols -= 1


if __name__ == "__main__":
    import optparse

    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.")
    parser.add_option("-p", "--padding", metavar="PADDING", action="store",
                      type=int, default=2, help="Spaces to add between columns.  Default is 2.")
    parser.add_option("-i", "--indent", metavar="SPACES", action="store",
                      type=int, default=0, help="Indent the output by SPACES.  Default is 0.")
    parser.add_option("-w", "--width", metavar="COLS", action="store",
                      type=int, default=cols, help="Indent the output by SPACES.  Default is 0.")
    options, args = parser.parse_args()

    method = "variable"
    if options.uniform:
        method = "uniform"
Example #17
0
    for row in xrange(rows):
        output.write(" " * indent)
        for col in xrange(cols):
            elt = col * rows + row
            output.write(formats[col] % elts[elt])

        output.write("\n")
        row += 1
        if row == rows_last_col:
            cols -= 1


if __name__ == "__main__":
    import optparse

    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.")
    parser.add_option("-p",
                      "--padding",
                      metavar="PADDING",
                      action="store",
                      type=int,
                      default=2,
                      help="Spaces to add between columns.  Default is 2.")
    parser.add_option("-i",
Example #18
0
def colify(elts, **options):
    """Takes a list of elements as input and finds a good columnization
    of them, similar to how gnu ls does. This supports both
    uniform-width and variable-width (tighter) columns.

    If elts is not a list of strings, each element is first conveted
    using str().

    Keyword arguments:

    output=<stream>   A file object to write to.  Default is sys.stdout.
    indent=<int>      Optionally indent all columns by some number of spaces.
    padding=<int>     Spaces between columns.  Default is 2.
    width=<int>       Width of the output.  Default is 80 if tty is not detected.

    cols=<int>        Force number of columns. Default is to size to terminal,
                      or single-column if no tty

    tty=<bool>        Whether to attempt to write to a tty.  Default is to
                      autodetect a tty. Set to False to force single-column output.

    method=<string>   Method to use to fit columns.  Options are variable or uniform.
                      Variable-width columns are tighter, uniform columns are all the
                      same width and fit less data on the screen.

    len=<func>        Function to use for calculating string length.
                      Useful for ignoring ansi color. Default is 'len'.
    """
    # Get keyword arguments or set defaults
    cols         = options.pop("cols", 0)
    output       = options.pop("output", sys.stdout)
    indent       = options.pop("indent", 0)
    padding      = options.pop("padding", 2)
    tty          = options.pop('tty', None)
    method       = options.pop("method", "variable")
    console_cols = options.pop("width", None)

    if options:
        raise TypeError("'%s' is an invalid keyword argument for this function."
                        % next(options.iterkeys()))

    # elts needs to be an array of strings so we can count the elements
    elts = [str(elt) for elt in elts]
    if not elts:
        return (0, ())

    # environment size is of the form "<rows>x<cols>"
    env_size = os.environ.get('COLIFY_SIZE')
    if env_size:
        try:
            r, c = env_size.split('x')
            console_rows, console_cols = int(r), int(c)
            tty = True
        except: pass

    # Use only one column if not a tty.
    if not tty:
        if tty is False or not output.isatty():
            cols = 1

    # Specify the number of character columns to use.
    if not console_cols:
        console_rows, console_cols = terminal_size()
    elif type(console_cols) != int:
        raise ValueError("Number of columns must be an int")
    console_cols = max(1, console_cols - indent)

    # Choose a method.  Variable-width colums vs uniform-width.
    if method == "variable":
        config = config_variable_cols(elts, console_cols, padding, cols)
    elif method == "uniform":
        config = config_uniform_cols(elts, console_cols, padding, cols)
    else:
        raise ValueError("method must be one of: " + allowed_methods)

    cols = config.cols
    formats = ["%%-%ds" % width for width in config.cwidths[:-1]]
    formats.append("%s")  # last column has no trailing space

    rows = (len(elts) + cols - 1) / cols
    rows_last_col = len(elts) % rows

    for row in xrange(rows):
        output.write(" " * indent)
        for col in xrange(cols):
            elt = col * rows + row
            output.write(formats[col] % elts[elt])

        output.write("\n")
        row += 1
        if row == rows_last_col:
            cols -= 1

    return (config.cols, tuple(config.widths))