nerdvegas/rez — pull request #76 by mstreatfield (2014-07-02 05:17:34+00:00)
Title: Colorized Output for Logging

This picks up the discussion in [pull request 73](https://github.com/nerdvegas/rez/pull/73 "73").

We have two use cases:

1. larger blocks of text that require richer formatting, and don't suite the event-style of a log (e.g. `rez env`)
2. traditional event-style log messages (in place of the `print` statements throughout the code).

In this branch, I create a new module `rez.colorize` to integrate the `rez.vendor.colorama` package in a rez-like way.

`rez.colorize` provides `critical`, `error`, `warning`, `info` and `debug` functions to style arbitrary strings for printing. The style applied is based entirely on the configuration in `rezconfig`, where parameters for the foreground, background and style are kept. `rezconfig` has been set to include some suitable defaults for these functions.

This goes some way to meeting the first use case, allowing arbitrary strings to be styled. The following should be possible:

import rez.colorize as c
print "This is a test " + c.critical("of mixing") + " styling inline " + c.warning("without logging")

Additional functions might be required, but the pattern for use is clearly established and easy to extend.

`rez.colorize` then provides a `ColorizedConsoleFormatter` for use with the python `logging` module. This formatter maps the `critical`, `error`, `warning`, `info` and `debug` functions from earlier to python's log levels. This itself is not configurable, but does provide consistency, a call to `logger.critical` will give the same visual output as `print rez.colorize.critical`. This formatter has been integrated with rez, using `rez.utils` as an example - if we agree this implementation is ok I'll apply it more widely.

I use a config file to control the configuration of the logging when rez is imported. It is not possible to take this configuration from the rezconfig file. It is likely the logger will be needed in the code that is reading the rezconfig file and so we have a circular dependency. I am not sure that applying the configuration in `rez.__init__` is the most appropriate place as it will affect all use cases of rez - I think `rez.cli` might be more appropriate.

Finally, I have posted this as a pull request but it is most likely not ready for merging. This however seemed the best way to post them for review - not sure if there is a better alternative in github.