"""Generic pretty display utils... envvar:: FORCE_COLOR By default, we will not color strings in non-interactive ttys, but you can force it with :envvar:`FORCE_COLOR`, ie. gitlab-ci etc"""importdifflibimportosimportsysimportyamltry:importjsonlightasjsonexceptImportError:importjson_print=print
[docs]defhighlight(string,lexer):""" Use pygments to render a string with a lexer. :param string: String to render :param lexer: Lexer name, Yaml, Diff, etc """FORCE_COLOR=bool(os.getenv('FORCE_COLOR',''))ifnotsys.stdout.isatty()andnotFORCE_COLOR:returnstringtry:importpygmentsimportpygments.lexersimportpygments.formattersexceptImportError:returnstringformatter=pygments.formatters.TerminalFormatter()lexer=getattr(pygments.lexers,lexer+'Lexer')()returnpygments.highlight(string,lexer,formatter)
defyaml_dump(data):ifisinstance(data,dict):# ensure that objects inheriting from dict render nicelydata=dict(data)returnyaml.dump(data,indent=4,width=float('inf'))
[docs]defrender(arg,highlight=True):""" Try to render arg as yaml. If the arg has a ``.json()`` method, it'll be called. If it is parseable as JSON then it'l be parsed as such. Then, it'll be dumped as colored YAML. Set the env var `FORCE_COLOR` to anything to force into printing colors even if terminal is non-interactive (ie. gitlab-ci) .. code-block:: python # pretty render some_object print(cli2.render(some_object)) """try:# deal with response objectsarg=arg.json()except:# noqapasstry:# is this json?arg=json.loads(arg)except:# noqapass# does this wants to show specific data to cli2?try:arg=arg.cli2_displayexceptAttributeError:passstring=argifisinstance(arg,str)elseyaml_dump(arg)ifnothighlight:returnstringreturnyaml_highlight(string)
[docs]defprint(*args,**kwargs):""" Try to print the :py:func:`render`'ed args, pass the kwargs to actual print method. .. code-block:: python # pretty print some_object cli2.print(some_object) """forarginargs:_print(render(arg),**kwargs)
[docs]defdiff(diff,**kwargs):""" Pretty-print a diff generated by Python's standard difflib.unified_diff method. .. code-block:: python # pretty print a diff cli2.diff(difflib.unified_diff(old, new)) """_print(diff_highlight(diff),**kwargs)
[docs]defdiff_data(before,after,before_label='before',after_label='after'):""" YAML Dump before and after objects and return the unified diff, printable with :py:func:`diff`. :param before: First object to compare :param after: Second object to compare :param before_label: Name of the first object to display in diff :param after_label: Name of the second object to display in diff """returndifflib.unified_diff(yaml.dump(before).splitlines(),yaml.dump(after).splitlines(),before_label,after_label,)