CLI colors refactored
Colors are now stored in their own module. Output coloring was factored out into a separate utility function. State => color mapping is now implemented as a dictionary instead of multiple conditionals. Tests included. Signed-off-by: Jiri Podivin <jpodivin@redhat.com> Change-Id: I41f15c28dfddd911294ecc8e3e0331a4956dc5d8
This commit is contained in:
parent
5fad1a4d18
commit
03981dba8a
57
validations_libs/cli/colors.py
Normal file
57
validations_libs/cli/colors.py
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright 2021 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
# PrettyTable Colors:
|
||||||
|
RED = "\033[1;31m"
|
||||||
|
GREEN = "\033[0;32m"
|
||||||
|
CYAN = "\033[36m"
|
||||||
|
RESET = "\033[0;0m"
|
||||||
|
YELLOW = "\033[0;33m"
|
||||||
|
|
||||||
|
colors = {
|
||||||
|
'starting': CYAN,
|
||||||
|
'running': CYAN,
|
||||||
|
'PASSED': GREEN,
|
||||||
|
'UNKNOWN': YELLOW,
|
||||||
|
'UNREACHABLE': YELLOW,
|
||||||
|
'ERROR': RED,
|
||||||
|
'FAILED': RED
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def color_output(output, status=None):
|
||||||
|
"""Apply color to output based on colors dict entries.
|
||||||
|
Unknown status or no status at all results in aplication
|
||||||
|
of YELLOW color.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Coloring itself is performed using format method of the
|
||||||
|
string class. This function is merely a wrapper around it,
|
||||||
|
and around ANSI escape sequences as defined by ECMA-48.
|
||||||
|
|
||||||
|
"""
|
||||||
|
if status:
|
||||||
|
color = colors.get(status, YELLOW)
|
||||||
|
else:
|
||||||
|
color = colors['UNKNOWN']
|
||||||
|
|
||||||
|
output = '{}{}{}'.format(
|
||||||
|
color,
|
||||||
|
output,
|
||||||
|
RESET)
|
||||||
|
|
||||||
|
return output
|
@ -19,16 +19,10 @@ from prettytable import PrettyTable
|
|||||||
|
|
||||||
from validations_libs import constants
|
from validations_libs import constants
|
||||||
from validations_libs import utils as v_utils
|
from validations_libs import utils as v_utils
|
||||||
|
from validations_libs.cli import colors
|
||||||
|
|
||||||
GROUP_FILE = constants.VALIDATION_GROUPS_INFO
|
GROUP_FILE = constants.VALIDATION_GROUPS_INFO
|
||||||
|
|
||||||
# PrettyTable Colors:
|
|
||||||
RED = "\033[1;31m"
|
|
||||||
GREEN = "\033[0;32m"
|
|
||||||
CYAN = "\033[36m"
|
|
||||||
RESET = "\033[0;0m"
|
|
||||||
YELLOW = "\033[0;33m"
|
|
||||||
|
|
||||||
|
|
||||||
def print_dict(data):
|
def print_dict(data):
|
||||||
"""Print table from python dict with PrettyTable"""
|
"""Print table from python dict with PrettyTable"""
|
||||||
@ -49,16 +43,12 @@ def print_dict(data):
|
|||||||
# if ValueError, then host is in unknown state:
|
# if ValueError, then host is in unknown state:
|
||||||
_name = host
|
_name = host
|
||||||
_status = 'UNKNOWN'
|
_status = 'UNKNOWN'
|
||||||
color = (GREEN if _status == 'PASSED' else
|
_name = colors.color_output(_name, status=_status)
|
||||||
(YELLOW if _status == 'UNREACHABLE' else RED))
|
|
||||||
_name = '{}{}{}'.format(color, _name, RESET)
|
|
||||||
hosts.append(_name)
|
hosts.append(_name)
|
||||||
row['Status_by_Host'] = ', '.join(hosts)
|
row['Status_by_Host'] = ', '.join(hosts)
|
||||||
if row.get('Status'):
|
if row.get('Status'):
|
||||||
status = row.get('Status')
|
status = row.get('Status')
|
||||||
color = (CYAN if status in ['starting', 'running']
|
row['Status'] = colors.color_output(status, status=status)
|
||||||
else GREEN if status == 'PASSED' else RED)
|
|
||||||
row['Status'] = '{}{}{}'.format(color, status, RESET)
|
|
||||||
table.add_row(row.values())
|
table.add_row(row.values())
|
||||||
print(table)
|
print(table)
|
||||||
|
|
||||||
|
68
validations_libs/tests/cli/test_colors.py
Normal file
68
validations_libs/tests/cli/test_colors.py
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# Copyright 2021 Red Hat, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
#
|
||||||
|
try:
|
||||||
|
from unittest import mock
|
||||||
|
except ImportError:
|
||||||
|
import mock
|
||||||
|
from unittest import TestCase
|
||||||
|
|
||||||
|
from validations_libs.cli import colors
|
||||||
|
|
||||||
|
|
||||||
|
class TestColors(TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
RED = "\033[1;31m"
|
||||||
|
GREEN = "\033[0;32m"
|
||||||
|
CYAN = "\033[36m"
|
||||||
|
RESET = "\033[0;0m"
|
||||||
|
YELLOW = "\033[0;33m"
|
||||||
|
|
||||||
|
self.status_color = {
|
||||||
|
'starting': CYAN,
|
||||||
|
'running': CYAN,
|
||||||
|
'PASSED': GREEN,
|
||||||
|
'UNKNOWN': YELLOW,
|
||||||
|
'UNREACHABLE': YELLOW,
|
||||||
|
'ERROR': RED,
|
||||||
|
'FAILED': RED
|
||||||
|
}
|
||||||
|
|
||||||
|
super(TestColors, self).setUp()
|
||||||
|
|
||||||
|
def test_format_known_status(self):
|
||||||
|
"""Tests formatting, meaning coloring, for every
|
||||||
|
status recognized by VF.
|
||||||
|
"""
|
||||||
|
|
||||||
|
for status in self.status_color:
|
||||||
|
color = self.status_color[status]
|
||||||
|
colored_output = colors.color_output("fizz", status=status)
|
||||||
|
#Checking reset color
|
||||||
|
self.assertEquals(colored_output[-6:], '\033[0;0m')
|
||||||
|
#Checking output color
|
||||||
|
self.assertEquals(colored_output[:len(color)], color)
|
||||||
|
#Checking output string
|
||||||
|
self.assertEquals(colored_output[len(color):][:4], "fizz")
|
||||||
|
|
||||||
|
def test_format_unknown_status(self):
|
||||||
|
|
||||||
|
color = self.status_color['UNKNOWN']
|
||||||
|
colored_output = colors.color_output("buzz")
|
||||||
|
#Checking reset color
|
||||||
|
self.assertEquals(colored_output[-6:], '\033[0;0m')
|
||||||
|
#Checking output color
|
||||||
|
self.assertEquals(colored_output[:len(color)], color)
|
||||||
|
#Checking output string
|
||||||
|
self.assertEquals(colored_output[len(color):][:4], "buzz")
|
Loading…
x
Reference in New Issue
Block a user