Implement a yaml formatter in cliff

This change replaces the cliff-tablib yaml formatter with an internal
replacement. It differs from the tablib formatter in the following ways:
- always outputs with block formatting rather than the PyYAML default
  of deciding based on value content
- emit_one serialises a simple dict where the column name is the key
  and the data item is the value (rather than a list of dicts with
  'Field' and 'Value' keys)
- emit_one preserves column order by printing a single-item dict for
  each column_name

The cliff release which contains this change will need a corresponding
cliff-tablib release which removes the yaml formatter from its setup.py
entry_points.

Change-Id: I691dbab3dee7c5ec28b1083f87ab1f5c051d582b
Related-Bug: #1308744
This commit is contained in:
Steve Baker 2015-08-05 16:16:54 +12:00
parent 57650f6950
commit 0a8daff7bd
6 changed files with 114 additions and 2 deletions

View File

@ -0,0 +1,23 @@
"""Output formatters using PyYAML.
"""
import yaml
from .base import ListFormatter, SingleFormatter
class YAMLFormatter(ListFormatter, SingleFormatter):
def add_argument_group(self, parser):
pass
def emit_list(self, column_names, data, stdout, parsed_args):
items = []
for item in data:
items.append(dict(zip(column_names, item)))
yaml.safe_dump(items, stream=stdout, default_flow_style=False)
def emit_one(self, column_names, data, stdout, parsed_args):
for key, value in zip(column_names, data):
dict_data = {key: value}
yaml.safe_dump(dict_data, stream=stdout, default_flow_style=False)

View File

@ -0,0 +1,45 @@
#!/usr/bin/env python
from six import StringIO
import yaml
from cliff.formatters import yaml_format
import mock
def test_yaml_format_one():
sf = yaml_format.YAMLFormatter()
c = ('a', 'b', 'c', 'd')
d = ('A', 'B', 'C', '"escape me"')
expected = {
'a': 'A',
'b': 'B',
'c': 'C',
'd': '"escape me"'
}
output = StringIO()
args = mock.Mock()
sf.emit_one(c, d, output, args)
actual = yaml.safe_load(output.getvalue())
assert expected == actual
def test_yaml_format_list():
sf = yaml_format.YAMLFormatter()
c = ('a', 'b', 'c')
d = (
('A1', 'B1', 'C1'),
('A2', 'B2', 'C2'),
('A3', 'B3', 'C3')
)
expected = [
{'a': 'A1', 'b': 'B1', 'c': 'C1'},
{'a': 'A2', 'b': 'B2', 'c': 'C2'},
{'a': 'A3', 'b': 'B3', 'c': 'C3'}
]
output = StringIO()
args = mock.Mock()
sf.add_argument_group(args)
sf.emit_list(c, d, output, args)
actual = yaml.safe_load(output.getvalue())
assert expected == actual

View File

@ -90,10 +90,34 @@ a script.
Makefile is 5569 bytes
source is 408 bytes
yaml
----
The ``yaml`` formatter uses PyYAML_ to produce a YAML sequence of
mappings.
.. _PyYAML: http://pyyaml.org/
::
(.venv)$ cliffdemo files -f yaml
- Name: dist
Size: 4096
- Name: cliffdemo.egg-info
Size: 4096
- Name: README.rst
Size: 960
- Name: setup.py
Size: 1807
- Name: build
Size: 4096
- Name: cliffdemo
Size: 4096
Other Formatters
----------------
Formatters using tablib_ to produce JSON, YAML, and HTML are available
Formatters using tablib_ to produce JSON and HTML are available
as part of `cliff-tablib`_.
.. _cliff-tablib: https://github.com/dreamhost/cliff-tablib

View File

@ -83,10 +83,27 @@ value of the field or fields.
(.venv)$ echo $SIZE
5916
yaml
----
The ``yaml`` formatter uses PyYAML_ to produce a YAML mapping where
the field name is the key.
.. _PyYAML: http://pyyaml.org/
::
(.venv)$ cliffdemo file -f yaml setup.py
Name: setup.py
Size: 1807
UID: 1000
GID: 1000
Modified Time: 1393531476.9587486
Other Formatters
----------------
Formatters using tablib_ to produce JSON, YAML, and HTML are available
Formatters using tablib_ to produce JSON and HTML are available
as part of `cliff-tablib`_.
.. _cliff-tablib: https://github.com/dreamhost/cliff-tablib

View File

@ -9,3 +9,4 @@ pyparsing>=2.0.1
six>=1.9.0
stevedore>=1.5.0 # Apache-2.0
unicodecsv>=0.8.0
PyYAML>=3.1.0

View File

@ -30,11 +30,13 @@ cliff.formatter.list =
table = cliff.formatters.table:TableFormatter
csv = cliff.formatters.commaseparated:CSVLister
value = cliff.formatters.value:ValueFormatter
yaml = cliff.formatters.yaml_format:YAMLFormatter
cliff.formatter.show =
table = cliff.formatters.table:TableFormatter
shell = cliff.formatters.shell:ShellFormatter
value = cliff.formatters.value:ValueFormatter
yaml = cliff.formatters.yaml_format:YAMLFormatter
cliff.formatter.completion =
bash = cliff.complete:CompleteBash