def __init__(self, output_format, pfxlen, color=None, unicode=True): self._terminal = ColorTerm(enabled=color) self._pfxlen = pfxlen self._fmt = output_format self._resource = None C = namedtuple('Corners', ['nw', 'ne', 'se', 'sw']) if unicode: self._corners = C._make('\u250C\u2510\u2518\u2514') self._hz, self._vt = '\u2500', '\u2502' else: self._corners = C._make('++++') self._hz, self._vt = '-', '|'
def status(color, show, show_all): if show_all == "yes": show = ["all"] _log.debug( f"Get status. Show items: {' '.join(show) if show else '(basic)'}") t = ColorTerm(enabled=color) if not DMFConfig.configuration_exists(): click.echo( f"No configuration found at '{DMFConfig.configuration_path()}'") sys.exit(Code.CONFIGURATION_NOT_FOUND.value) try: d = DMF() except errors.WorkspaceConfNotFoundError as err: _log.fatal(f"Cannot get status: {err}") click.echo(str(err)) sys.exit(Code.WORKSPACE_NOT_FOUND.value) # pretty-display a key/value pair or list value def item(key, value=None, before="", color=t.green): after_key = "" if key == "" else ":" if value is None: return f"{before}{color}{key}{after_key}{t.reset}" elif key is None: return f"{before}{color}{value}{t.reset}" return f"{before}{color}{key}{after_key}{t.reset} {value}" indent_spc = " " print(item("settings", color=t.blue)) indent = indent_spc conf = DMFConfig() # note: must exist due to earlier check for key, value in conf.c.items(): print(item(key, value, before=indent)) print(item("workspace", color=t.blue)) indent = indent_spc for key, value in ( ("location", d.root), ("name", d.name), ("description", d.description), ("created", d.meta[d.CONF_CREATED]), ("modified", d.meta[d.CONF_MODIFIED]), ): print(item(key, value, before=indent)) _show_optional_workspace_items(d, show, indent_spc, item, t=t)
import os import re import time # package import idaes from idaes.dmf.util import ColorTerm import pytest good_modname = re.compile(r"[a-zA-Z][a-zA-Z0-9_]*") SKIP, OK, BAD = "skipped", "success", "failed" _term = ColorTerm() def print_path_status(path, status, msg=""): color = {SKIP: "", OK: _term.green, BAD: _term.red}[status] print(f"{color}{status.upper():8s}{_term.resetc} {path} {msg}") def importr(root: pathlib.Path, max_sec=10): """Import r_ecursively from the given root path. """ base, failures, total = root.parent, {}, 0 # iterate over flattened list of all paths ending a Python source file for path in root.rglob("*.py"): # check that all path components are valid module names # - this is to skip directories like '.ipynb_checkpoints'
def related(identifier, direction, color, unicode): _log.info(f"related to resource id='{identifier}'") t = ColorTerm(enabled=color) dmf = DMF() try: resource.identifier_str(identifier, allow_prefix=True) except ValueError as err: click.echo(f"{err}") sys.exit(Code.INPUT_VALUE.value) _log.debug(f"begin: finding root resource {identifier}") rsrc_list = list(find_by_id(identifier, dmf=dmf)) n = len(rsrc_list) if n > 1: click.echo(f"Too many resources matching `{identifier}`") sys.exit(Code.INPUT_VALUE) rsrc = rsrc_list[0] _log.debug(f"end: finding root resource {identifier}") # get related resources _log.debug(f"begin: finding related resources for {identifier}") outgoing = direction == "out" rr = list( dmf.find_related(rsrc, meta=["aliases", "type"], outgoing=outgoing)) _log.debug(f"end: finding related resources for {identifier}") # stop if no relations if not rr: _log.warning(f"no resource related to {identifier}") click.echo(f"No relations for resource `{identifier}`") sys.exit(0) _log.info(f"got {len(rr)} related resources") # debugging if _log.isEnabledFor(logging.DEBUG): dbgtree = '\n'.join([' ' + str(x) for x in rr]) _log.debug(f"related resources:\n{dbgtree}") # extract uuids & determine common UUID prefix length uuids = [item[2][resource.Resource.ID_FIELD] for item in rr] pfx = util.uuid_prefix_len(uuids) # initialize queue with depth=1 items q = [item for item in rr if item[0] == 1] # print root resource print(_related_item(rsrc.id, rsrc.name, rsrc.type, pfx, t, unicode)) # set up printing style if unicode: # connector chars vrt, vrd, relbow, relbow2, rarr = ( '\u2502', '\u2506', '\u2514', '\u251C', '\u2500\u2500', ) # relation prefix and arrow relpre, relarr = ( ['\u2500\u25C0\u2500\u2524', '\u2524'][outgoing], ['\u2502', '\u251C\u2500\u25B6'][outgoing], ) else: # connector chars vrt, vrd, relbow, relbow2, rarr = '|', '.', '+', '+', '--' # relation prefix and arrow relpre, relarr = ['<-[', '-['][outgoing], [']-', ']->'][outgoing] # create map of #items at each level, so we can easily # know when there are more at a given level, for drawing n_at_level = {0: 0} for item in rr: depth = item[0] if depth in n_at_level: n_at_level[depth] += 1 else: n_at_level[depth] = 1 # print tree while q: depth, rel, meta = q.pop() n_at_level[depth] -= 1 indent = ''.join([ f" {t.blue}{vrd if n_at_level[i - 1] else ' '}{t.resetc} " for i in range(1, depth + 1) ]) print(f"{indent} {t.blue}{vrt}") rstr = f"{t.blue}{relpre}{t.yellow}{rel.predicate}"\ f"{t.blue}{relarr}{t.reset}" if meta["aliases"]: item_name = meta["aliases"][0] else: item_name = meta.get("desc", "-") istr = _related_item(meta[resource.Resource.ID_FIELD], item_name, meta["type"], pfx, t, unicode) # determine correct connector (whether there is another one down the stack) elbow = relbow if (not q or q[-1][0] != depth) else relbow2 print(f"{indent} {t.blue}{elbow}{rarr}{t.resetc}{rstr} {istr}") new_rr = [] for d2, rel2, _ in rr: if outgoing: is_same = rel2.subject == rel.object else: is_same = rel2.object == rel.subject if d2 == depth + 1 and is_same: q.append((d2, rel2, _)) else: new_rr.append((d2, rel2, _)) rr = new_rr
def _print_resource_table(resources, show_fields, sort_by, reverse, prefix, color): """Text-mode `ls`. """ t = ColorTerm(enabled=color) if len(resources) == 0: print("no resources to display") return uuid_len = util.uuid_prefix_len([r.id for r in resources]) full_len = max((len(r.id) for r in resources)) if not prefix else uuid_len fields = ["id"] + list(show_fields) nfields = len(fields) # calculate table body. do this first to get widths. hdr_fields = [".".join(f) if isinstance(f, tuple) else f for f in fields] rows, maxwid, widths = [], 60, [len(f) for f in hdr_fields] for r in resources: row = [] for i, fld in enumerate(fields): # transform field for display try: transformer = _show_fields[fld] except KeyError: transformer = _IdentityField(fld) transformer.set_value(r) # if it's a UUID field, add info about unique prefix length is_id_field = isinstance(transformer, _IdField) if is_id_field: transformer.term = t transformer.pfxlen = uuid_len transformer.flen = full_len # extract display string and set field width s = str(transformer) slen = full_len if is_id_field else len(s) if slen > widths[i]: if slen > maxwid: s, widths[i] = s[:maxwid], maxwid else: widths[i] = slen row.append(s) # append sort keys (not displayed) sort_obj = [_show_fields[fld] for fld in sort_by] for o in sort_obj: o.set_value(r) row.extend([o.value for o in sort_obj]) # add row to table body rows.append(row) # sort rows nsort = len(sort_by) if nsort > 0: sort_key_idx = tuple(range(nfields, nfields + nsort)) rows.sort(key=itemgetter(*sort_key_idx), reverse=reverse) # print table header hdr_columns = [ t.bold + "{{f:{w}s}}".format(w=w).format(f=f) for f, w in zip(hdr_fields, widths) ] print(" ".join(hdr_columns) + t.normal) # print table body for row in rows: col = [] for i, fld in enumerate(fields): if i == 0: col.append(t.red) elif fld == resource.Resource.TYPE_FIELD: col.append(t.yellow) elif fld != "desc": col.append(t.green) else: col.append("") row_columns = [ f"{col[i]}{f:{w}}{t.reset}" for i, f, w in zip(range(len(widths)), row[:nfields], widths) ] print(" ".join(row_columns))