[Color] Detect isatty when enabling color#209
Conversation
knack/util.py
Outdated
| # Code copied from | ||
| # https://github.com/tartley/colorama/blob/3d8d48a95de10be25b161c914f274ec6c41d3129/colorama/ansitowin32.py#L43-L53 | ||
| import sys | ||
| if 'PYCHARM_HOSTED' in os.environ: |
There was a problem hiding this comment.
PyCharm's integrated terminal is not a tty but it does support color, so detect if the command is run in PyCharm's integrated terminal. If so, enable color.
However, this still has some edge cases (Azure/azure-cli#9903, Azure/azure-sdk-for-python#11362) when colorama is used within PyCharm: tartley/colorama#263.
There was a problem hiding this comment.
Even though colorama already has this logic and can strip escape sequences \033[ if the stream is not a TTY, we still need to detect it by ourselves so that we don't print escape sequences when colorama is not initialized. In other words, we shouldn't rely on colorama to do the stripping.
| def get_formatter(self, format_type): # pylint: disable=no-self-use | ||
| # remove color if stdout is not a tty | ||
| if not sys.stdout.isatty() and format_type == 'jsonc': | ||
| if not self.cli_ctx.enable_color and format_type == 'jsonc': |
There was a problem hiding this comment.
Correct the logic to use cli_ctx.enable_color instead of sys.stdout to make the decision about falling back from jsonc to json.
| # As logging is initialized in `invoke`, call `logger.debug` or `logger.info` here won't work. | ||
| self.init_debug_log = [] | ||
| self.init_info_log = [] |
There was a problem hiding this comment.
Add lists for debug and info logs which can't be printed with logger.debug and logger.info yet, until the logger has been initialized.
knack/cli.py
Outdated
| self.only_show_errors = self.config.getboolean('core', 'only_show_errors', fallback=False) | ||
| self.enable_color = not self.config.getboolean('core', 'no_color', fallback=False) | ||
|
|
||
| # Color is only enabled when all conditions are met: |
|
CI was broken due to a breaking change in Updating Pylint so that |
knack/util.py
Outdated
|
|
||
| def isatty(stream): | ||
| # Code copied from | ||
| # https://github.com/tartley/colorama/blob/3d8d48a95de10be25b161c914f274ec6c41d3129/colorama/ansitowin32.py#L43-L53 |
There was a problem hiding this comment.
Can code under BSD-3-Clause be used in MIT project?
There was a problem hiding this comment.
Refactored to remove unnecessary code.

This PR is an improvement to #171.
Only enable color if all of the below conditions stand:
Color is not explicitly disabled
AZURE_CORE_NO_COLORand this config shouldn't be set:stdoutis a TTYOtherwise (enable color while
stdoutis redirected), combined withheadcommand, colorama will fail withBrokenPipeError: [Errno 32] Broken pipe(Azure/azure-cli#13413):With this RP, color sequences are not printed or sent to downstream command.
Also, if color is written to
stderr, the terminal color can't revert back (Azure/azure-cli#6080, Azure/azure-cli#8483, Azure/azure-cli#11671, Azure/azure-cli#12084, Azure/azure-cli#13979) :This is due to colorama issue tartley/colorama#200. In order for color to be reset correctly, the
Style.RESET_ALLcontrol sequence must be sent to bothstdoutandstderr. However, colorama can't sendStyle.RESET_ALLtostderrcorrectly, causing the terminal stuck at the previous color:stderris a TTYOtherwise (enable color while
stderris redirected),err.txtwill have no level information (because there is no color):With this RP, each message will be prefixed with a LEVEL_TAG -
ERROR,WARNING,INFO,DEBUG: