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
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()
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
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))
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()
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)
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()
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
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()
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
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
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))
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()
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))
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()
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"
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",
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))