From 336feeb5236d549cde44053dfe1a3693e22cd111 Mon Sep 17 00:00:00 2001 From: Fei Long Wang Date: Fri, 15 Nov 2013 16:02:46 +0800 Subject: [PATCH] Get better format for long lines with PrettyTable Based on current implement, the cli output format will be bad if the lines are too long. This issue can be fixed by setting 'max_width'. However, there is a bug against it, see https://code.google.com/p/prettytable/source/browse/trunk/CHANGELOG?r=85 line 3. So the requirements.txt is updated as well. docImpact Fixes bug 1251283 Change-Id: I0d4192ad9d10a3d6d47a8319463a5edb57719a68 --- glanceclient/common/utils.py | 3 ++- glanceclient/v1/shell.py | 9 ++++++--- glanceclient/v2/shell.py | 4 +++- tests/test_utils.py | 20 +++++++++++++------- tests/v2/test_shell_v2.py | 6 ++++-- 5 files changed, 28 insertions(+), 14 deletions(-) diff --git a/glanceclient/common/utils.py b/glanceclient/common/utils.py index 3e327631..01205728 100644 --- a/glanceclient/common/utils.py +++ b/glanceclient/common/utils.py @@ -119,9 +119,10 @@ def print_list(objs, fields, formatters={}): print(strutils.safe_encode(pt.get_string())) -def print_dict(d): +def print_dict(d, max_column_width=80): pt = prettytable.PrettyTable(['Property', 'Value'], caching=False) pt.align = 'l' + pt.max_width = max_column_width [pt.add_row(list(r)) for r in d.iteritems()] print(strutils.safe_encode(pt.get_string(sortby='Property'))) diff --git a/glanceclient/v1/shell.py b/glanceclient/v1/shell.py index 8cf4b43a..a0089baf 100644 --- a/glanceclient/v1/shell.py +++ b/glanceclient/v1/shell.py @@ -108,7 +108,7 @@ def do_image_list(gc, args): utils.print_list(images, columns) -def _image_show(image, human_readable=False): +def _image_show(image, human_readable=False, max_column_width=80): # Flatten image properties dict for display info = copy.deepcopy(image._info) if human_readable: @@ -116,7 +116,7 @@ def _image_show(image, human_readable=False): for (k, v) in info.pop('properties').iteritems(): info['Property \'%s\'' % k] = v - utils.print_dict(info) + utils.print_dict(info, max_column_width=max_column_width) def _set_data_field(fields, args): @@ -127,11 +127,14 @@ def _set_data_field(fields, args): @utils.arg('image', metavar='', help='Name or ID of image to describe.') @utils.arg('--human-readable', action='store_true', default=False, help='Print image size in a human-friendly format.') +@utils.arg('--max-column-width', metavar='', default=80, + help='The max column width of the printed table.') def do_image_show(gc, args): """Describe a specific image.""" image_id = utils.find_resource(gc.images, args.image).id image = gc.images.get(image_id) - _image_show(image, args.human_readable) + _image_show(image, args.human_readable, + max_column_width=int(args.max_column_width)) @utils.arg('--file', metavar='', diff --git a/glanceclient/v2/shell.py b/glanceclient/v2/shell.py index 5851acdd..5ee87a5c 100644 --- a/glanceclient/v2/shell.py +++ b/glanceclient/v2/shell.py @@ -118,12 +118,14 @@ def do_image_list(gc, args): @utils.arg('id', metavar='', help='ID of image to describe.') +@utils.arg('--max-column-width', metavar='', default=80, + help='The max column width of the printed table.') def do_image_show(gc, args): """Describe a specific image.""" image = gc.images.get(args.id) ignore = ['self', 'access', 'file', 'schema'] image = dict([item for item in image.iteritems() if item[0] not in ignore]) - utils.print_dict(image) + utils.print_dict(image, max_column_width=int(args.max_column_width)) @utils.arg('--image-id', metavar='', required=True, diff --git a/tests/test_utils.py b/tests/test_utils.py index e5d7f191..8bf58f5f 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -68,7 +68,11 @@ class TestUtils(testtools.TestCase): utils.print_list(images, columns) sys.stdout = output_dict = StringIO.StringIO() - utils.print_dict({'K': 'k', 'Key': 'Value'}) + utils.print_dict({'K': 'k', 'Key': 'veeeeeeeeeeeeeeeeeeeeeeee' + 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' + 'eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' + 'eeeeeeeeeeeery long value'}, + max_column_width=60) finally: sys.stdout = saved_stdout @@ -84,12 +88,14 @@ class TestUtils(testtools.TestCase): ''') self.assertEqual(output_dict.getvalue(), '''\ -+----------+-------+ -| Property | Value | -+----------+-------+ -| K | k | -| Key | Value | -+----------+-------+ ++----------+--------------------------------------------------------------+ +| Property | Value | ++----------+--------------------------------------------------------------+ +| K | k | +| Key | veeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee | +| | eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee | +| | ery long value | ++----------+--------------------------------------------------------------+ ''') def test_exception_to_str(self): diff --git a/tests/v2/test_shell_v2.py b/tests/v2/test_shell_v2.py index 4a13e0b5..32e113dd 100644 --- a/tests/v2/test_shell_v2.py +++ b/tests/v2/test_shell_v2.py @@ -90,7 +90,8 @@ class ShellV2Test(testtools.TestCase): utils.print_list.assert_called_once_with({}, ['ID', 'Name']) def test_do_image_show(self): - args = self._make_args({'id': 'pass', 'page_size': 18}) + args = self._make_args({'id': 'pass', 'page_size': 18, + 'max_column_width': 120}) with mock.patch.object(self.gc.images, 'get') as mocked_list: ignore_fields = ['self', 'access', 'file', 'schema'] expect_image = dict([(field, field) for field in ignore_fields]) @@ -100,7 +101,8 @@ class ShellV2Test(testtools.TestCase): test_shell.do_image_show(self.gc, args) mocked_list.assert_called_once_with('pass') - utils.print_dict.assert_called_once_with({'id': 'pass'}) + utils.print_dict.assert_called_once_with({'id': 'pass'}, + max_column_width=120) def test_do_image_create_no_user_props(self): args = self._make_args({'name': 'IMG-01', 'disk_format': 'vhd',