Merge "Added reStructuredText model printer"

This commit is contained in:
Zuul 2017-12-07 10:07:14 +00:00 committed by Gerrit Code Review
commit 414c14811d
3 changed files with 86 additions and 2 deletions

View File

@ -79,12 +79,14 @@ supported sub-commands.
This utility will allow to print a representation of the DragonFlow model in
different formats. Currently supported formats are: text, PlantUML and
different formats. Currently supported formats are: text, PlantUML, rst and
JsonSchema (OpenApiSchema 3.0). The output may be sent to the stdout or to a
file.
* PlantUML output can be visualized using the PlantUML Server [#]_
* rst output can be visualized using Online reStructuredText editor [#]_
Use the *df-model --help* command to get a detailed usage instructions.
.. [#] https://gist.github.com/omeranson/5c731955edcf0517bfb0ce0ce511cc9b
.. [#] http://www.plantuml.com/plantuml/uml/
.. [#] http://rst.ninjs.org/?theme=nature

View File

@ -20,6 +20,7 @@ import sys
from jsonmodels import fields
from oslo_serialization import jsonutils
import prettytable
from dragonflow.db import field_types
from dragonflow.db import model_framework
@ -391,6 +392,80 @@ class OASPrinter(ModelsPrinter):
pass
class RstPrinter(ModelsPrinter):
"""ModelPrinter that prints to reStructuredText format.
This printer prints output that can be reused and included in rst files
for documentation purposes.
"""
def __init__(self, fh):
super(RstPrinter, self).__init__(fh)
self._model_fields_table = prettytable.PrettyTable(
['Field', 'Type', 'Restrictions', 'Required', 'Embedded', 'List'])
# The empty column was added as a patch, as rst does not accept
# single column tables
self._model_indexes_table = prettytable.PrettyTable(['Index', ''])
self._model_events_table = prettytable.PrettyTable(['Event', ''])
self._set_rst_tables_style()
self._model_printed = False
def _set_rst_tables_style(self):
for table in (self._model_fields_table,
self._model_indexes_table,
self._model_events_table):
table.horizontal_char = '='
table.vertical_char = ' '
table.junction_char = ' '
table.header_style = 'cap'
table.align = 'l'
def model_start(self, model_name):
# Print separator, anchor and title
if self._model_printed:
self._print('\n----\n')
_title = '{}'.format(model_name)
_surround_line = '-' * len(_title)
self._print(_surround_line)
self._print(_title)
self._print(_surround_line)
def model_end(self, model_name):
self._model_printed = True
def fields_end(self):
self._print(self._model_fields_table)
self._model_fields_table.clear_rows()
def handle_field(self, field_name, field_type, is_required, is_embedded,
is_single, restrictions):
restriction_str = '{}'.format(restrictions) if restrictions else ''
if field_type in BASIC_TYPES:
type_str = field_type
else:
type_str = '`{}`_'.format(field_type, field_type)
self._model_fields_table.add_row([field_name, type_str,
restriction_str, is_required,
is_embedded, not is_single])
def indexes_end(self):
self._print('\n|\n')
self._print(self._model_indexes_table)
self._model_indexes_table.clear_rows()
def handle_index(self, index_name):
self._model_indexes_table.add_row([index_name, ''])
def events_end(self):
self._print('')
self._print('|')
self._print('')
self._print(self._model_events_table)
self._model_events_table.clear_rows()
def handle_event(self, event_name):
self._model_events_table.add_row([event_name, ''])
class DfModelsParser(object):
"""Parser for the Dragonflow models schema
@ -540,12 +615,16 @@ def smart_open(filename=None):
def main():
parser = argparse.ArgumentParser(description='Print Dragonflow schema')
group = parser.add_mutually_exclusive_group()
group.add_argument('--plaintext', help='Plaintext output (default)',
group.add_argument('--plaintext',
help='Plaintext output (default)',
action='store_true')
group.add_argument('--uml', help='PlantUML format output',
action='store_true')
group.add_argument('--json', help='OpenApiSchema JSON format output',
action='store_true')
group.add_argument('--rst',
help='reStructuredText output',
action='store_true')
parser.add_argument('-o', '--outfile',
help='Output to file (instead of stdout)')
args = parser.parse_args()
@ -554,6 +633,8 @@ def main():
printer = UMLPrinter(fh)
elif args.json:
printer = OASPrinter(fh)
elif args.rst:
printer = RstPrinter(fh)
else:
printer = PlaintextPrinter(fh)
parser = DfModelsParser(printer)

View File

@ -19,3 +19,4 @@ testtools>=2.2.0 # MIT
redis>=2.10.0 # MIT
hiredis>=0.2.0 # BSD
reno>=2.5.0 # Apache-2.0
PrettyTable>=0.7.1,<0.8 # BSD