Merge "Remove extra CLI formatters"

This commit is contained in:
Jenkins 2015-01-29 11:51:01 +00:00 committed by Gerrit Code Review
commit 7c77bacc40
6 changed files with 7 additions and 192 deletions

View File

@ -12,107 +12,6 @@
from __future__ import print_function
import sys
import prettytable
def pretty_choice_list(l):
return ', '.join("'%s'" % i for i in l)
def print_list(objs, fields, formatters={}, custom_labels={}, sortby=0,
outfile=sys.stdout):
'''Prints a list of objects.
:param objs: list of objects to print
:param fields: list of attributes of the objects to print;
attributes beginning with '!' have a special meaning - they
should be used with custom field labels and formatters only,
and the formatter receives the whole object
:param formatters: dict of functions that perform pre-print
formatting of attributes (keys are strings from `fields`
parameter, values are functions that take one parameter - the
attribute)
:param custom_labels: dict of label overrides for fields (keys are
strings from `fields` parameter, values are custom labels -
headers of the table)
'''
field_labels = [custom_labels.get(f, f) for f in fields]
pt = prettytable.PrettyTable([f for f in field_labels],
caching=False, print_empty=False)
pt.align = 'l'
for o in objs:
row = []
for field in fields:
if field[0] == '!': # custom field
if field in formatters:
row.append(formatters[field](o))
else:
raise KeyError(
'Custom field "%s" needs a formatter.' % field)
else: # attribute-based field
if hasattr(o, field) and field in formatters:
row.append(formatters[field](getattr(o, field)))
else:
row.append(getattr(o, field, ''))
pt.add_row(row)
print(pt.get_string(sortby=field_labels[sortby]), file=outfile)
def print_dict(d, formatters={}, custom_labels={}, outfile=sys.stdout):
'''Prints a dict to the provided file or file-like object.
:param d: dict to print
:param formatters: dict of functions that perform pre-print
formatting of dict values (keys are keys from `d` parameter,
values are functions that take one parameter - the dict value
to format). A wild card formatter can be provided as '*' which
will be applied to all fields without a dedicated formatter.
:param custom_labels: dict of label overrides for keys (keys are
keys from `d` parameter, values are custom labels)
'''
pt = prettytable.PrettyTable(['Property', 'Value'],
caching=False, print_empty=False)
pt.align = 'l'
global_formatter = formatters.get('*')
for field in d.keys():
label = custom_labels.get(field, field)
if field in formatters:
pt.add_row([label, formatters[field](d[field])])
elif global_formatter:
pt.add_row([label, global_formatter(d[field])])
else:
pt.add_row([label, d[field]])
print(pt.get_string(sortby='Property'), file=outfile)
def attr_proxy(attr, formatter=lambda a: a, allow_undefined=True):
'''Creates a new formatter function. It will format an object for
output by printing it's attribute or running another formatter on
that attribute.
:param attr: name of the attribute to look for on an object
:param formatter: formatter to run on that attribute (if not given,
the attribute is returned as-is)
:param allow_undefined: if true, the created function will return
None if `attr` is not defined on the formatted object
'''
def formatter_proxy(obj):
try:
attr_value = getattr(obj, attr)
except AttributeError as e:
if allow_undefined:
return None
else:
raise e
return formatter(attr_value)
return formatter_proxy
def attributes_formatter(attributes):
"""Given a simple dict format the keyvalue pairs with one on each line.
@ -127,20 +26,6 @@ def parameters_v2_formatter(parameters):
for parameter in parameters)
def counts_formatter(counts):
"""Given a list of dicts that represent Overcloud Roles output the
Overcloud Role ID with the num_noces
"""
pretty_counts = []
for count in counts:
line = "{0}={1}".format(count['overcloud_role_id'], count['num_nodes'])
pretty_counts.append(line)
return u"\n".join(pretty_counts)
def list_plan_roles_formatter(roles):
"""Given a list of Roles format roles' names into row."""
return u", ".join(role.name for role in roles)

View File

@ -10,70 +10,11 @@
# License for the specific language governing permissions and limitations
# under the License.
import mock
import six
import tuskarclient.common.formatting as fmt
import tuskarclient.tests.utils as tutils
from tuskarclient.v2 import plans
class PrintTest(tutils.TestCase):
def setUp(self):
super(PrintTest, self).setUp()
self.outfile = six.StringIO()
def test_print_dict(self):
dict_ = {'k': 'v', 'key': 'value'}
formatters = {'key': lambda v: 'custom ' + v}
custom_labels = {'k': 'custom_key'}
fmt.print_dict(dict_, formatters, custom_labels,
outfile=self.outfile)
self.assertEqual(
('+------------+--------------+\n'
'| Property | Value |\n'
'+------------+--------------+\n'
'| custom_key | v |\n'
'| key | custom value |\n'
'+------------+--------------+\n'),
self.outfile.getvalue()
)
def test_print_list(self):
fields = ['thing', 'color', '!artistic_name']
formatters = {
'!artistic_name': lambda obj: '{0} {1}'.format(obj.color,
obj.thing),
'color': lambda c: c.split(' ')[1],
}
custom_labels = {'thing': 'name', '!artistic_name': 'artistic name'}
fmt.print_list(self.objects(), fields, formatters, custom_labels,
outfile=self.outfile)
self.assertEqual(
('+------+-------+-----------------+\n'
'| name | color | artistic name |\n'
'+------+-------+-----------------+\n'
'| moon | green | dark green moon |\n'
'| sun | blue | bright blue sun |\n'
'+------+-------+-----------------+\n'),
self.outfile.getvalue()
)
def test_print_list_custom_field_without_formatter(self):
fields = ['!artistic_name']
self.assertRaises(KeyError, fmt.print_list, self.objects(), fields)
def objects(self):
return [
mock.Mock(thing='sun', color='bright blue'),
mock.Mock(thing='moon', color='dark green'),
]
class FormattersTest(tutils.TestCase):
def test_attributes_formatter(self):
@ -89,18 +30,6 @@ class FormattersTest(tutils.TestCase):
fmt.attributes_formatter(attributes),
)
def test_counts_formatter(self):
resource_link = [
{'overcloud_role_id': 1, 'num_nodes': 10},
{'overcloud_role_id': 2, 'num_nodes': 20}
]
self.assertEqual(
("1=10\n2=20"),
fmt.counts_formatter(resource_link),
)
def test_list_plan_roles_formatter(self):
roles = plans.Plan(None,
{'roles': [{'name': 'foo_role'},

View File

@ -42,7 +42,7 @@ class BasePlansShellTest(tutils.TestCase):
class PlansShellTest(BasePlansShellTest):
@mock.patch('tuskarclient.common.formatting.print_list')
@mock.patch('tuskarclient.openstack.common.cliutils.print_list')
def test_plan_list(self, mock_print_list):
args = empty_args()

View File

@ -35,7 +35,7 @@ class BaseRolesShellTest(tutils.TestCase):
class RolesShellTest(BaseRolesShellTest):
@mock.patch('tuskarclient.common.formatting.print_list')
@mock.patch('tuskarclient.openstack.common.cliutils.print_list')
def test_role_list(self, mock_print_list):
args = empty_args()

View File

@ -17,6 +17,7 @@ import sys
import tuskarclient.common.formatting as fmt
from tuskarclient.common import utils
from tuskarclient.openstack.common import cliutils
def do_plan_list(tuskar, args, outfile=sys.stdout):
@ -28,7 +29,7 @@ def do_plan_list(tuskar, args, outfile=sys.stdout):
'roles': fmt.list_plan_roles_formatter,
}
fmt.print_list(plans, fields, formatters, outfile=outfile)
cliutils.print_list(plans, fields, formatters, outfile=outfile)
@utils.arg('plan', metavar="<PLAN>",
@ -47,7 +48,7 @@ def print_plan_detail(plan, outfile=sys.stdout):
'parameters': fmt.parameters_v2_formatter,
}
plan_dict = plan.to_dict()
fmt.print_dict(plan_dict, formatters, outfile=outfile)
cliutils.print_dict(plan_dict, formatters, outfile=outfile)
@utils.arg('plan', metavar="<PLAN>",

View File

@ -14,7 +14,7 @@ from __future__ import print_function
import sys
import tuskarclient.common.formatting as fmt
from tuskarclient.openstack.common import cliutils
def do_role_list(tuskar, args, outfile=sys.stdout):
@ -25,4 +25,4 @@ def do_role_list(tuskar, args, outfile=sys.stdout):
formatters = {
}
fmt.print_list(roles, fields, formatters, outfile=outfile)
cliutils.print_list(roles, fields, formatters, outfile=outfile)