Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 1 | #!/usr/bin/env python |
| 2 | |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 3 | '''Phosphor DBus Monitor YAML parser and code generator. |
| 4 | |
| 5 | The parser workflow is broken down as follows: |
| 6 | 1 - Import YAML files as native python type(s) instance(s). |
| 7 | 2 - Create an instance of the Everything class from the |
| 8 | native python type instance(s) with the Everything.load |
| 9 | method. |
| 10 | 3 - The Everything class constructor orchestrates conversion of the |
| 11 | native python type(s) instances(s) to render helper types. |
| 12 | Each render helper type constructor imports its attributes |
| 13 | from the native python type(s) instances(s). |
| 14 | 4 - Present the converted YAML to the command processing method |
| 15 | requested by the script user. |
| 16 | ''' |
| 17 | |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 18 | import os |
| 19 | import sys |
| 20 | import yaml |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 21 | import mako.lookup |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 22 | from argparse import ArgumentParser |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 23 | from sdbusplus.renderer import Renderer |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 24 | |
| 25 | |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 26 | class Indent(object): |
| 27 | '''Help templates be depth agnostic.''' |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 28 | |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 29 | def __init__(self, depth=0): |
| 30 | self.depth = depth |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 31 | |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 32 | def __add__(self, depth): |
| 33 | return Indent(self.depth + depth) |
| 34 | |
| 35 | def __call__(self, depth): |
| 36 | '''Render an indent at the current depth plus depth.''' |
| 37 | return 4*' '*(depth + self.depth) |
| 38 | |
| 39 | |
| 40 | class Everything(Renderer): |
| 41 | '''Parse/render entry point.''' |
| 42 | |
| 43 | @staticmethod |
| 44 | def load(args): |
| 45 | '''Aggregate all the YAML in the input directory |
| 46 | into a single aggregate.''' |
| 47 | |
| 48 | if os.path.exists(args.inputdir): |
| 49 | yaml_files = filter( |
| 50 | lambda x: x.endswith('.yaml'), |
| 51 | os.listdir(args.inputdir)) |
| 52 | |
| 53 | for x in yaml_files: |
| 54 | with open(os.path.join(args.inputdir, x), 'r') as fd: |
| 55 | yaml.safe_load(fd.read()) |
| 56 | |
| 57 | return Everything() |
| 58 | |
| 59 | def __init__(self, *a, **kw): |
| 60 | super(Everything, self).__init__(**kw) |
| 61 | |
| 62 | def generate_cpp(self, loader): |
| 63 | '''Render the template with the provided data.''' |
Brad Bishop | e3a01af | 2017-05-15 17:09:04 -0400 | [diff] [blame] | 64 | with open(args.output, 'w') as fd: |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 65 | fd.write( |
| 66 | self.render( |
| 67 | loader, |
Brad Bishop | e3a01af | 2017-05-15 17:09:04 -0400 | [diff] [blame] | 68 | args.template, |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 69 | events={}, |
| 70 | indent=Indent())) |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 71 | |
| 72 | if __name__ == '__main__': |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 73 | script_dir = os.path.dirname(os.path.realpath(__file__)) |
| 74 | valid_commands = { |
| 75 | 'generate-cpp': 'generate_cpp', |
| 76 | } |
| 77 | |
| 78 | parser = ArgumentParser( |
| 79 | description='Phosphor DBus Monitor (PDM) YAML ' |
| 80 | 'scanner and code generator.') |
| 81 | |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 82 | parser.add_argument( |
Brad Bishop | e3a01af | 2017-05-15 17:09:04 -0400 | [diff] [blame] | 83 | "-o", "--out", dest="output", |
| 84 | default='generated.cpp', |
| 85 | help="Generated output file name and path.") |
| 86 | parser.add_argument( |
| 87 | '-t', '--template', dest='template', |
Brad Bishop | 870c3fc | 2017-05-22 23:23:13 -0400 | [diff] [blame] | 88 | default='generated.mako.hpp', |
Brad Bishop | e3a01af | 2017-05-15 17:09:04 -0400 | [diff] [blame] | 89 | help='The top level template to render.') |
| 90 | parser.add_argument( |
| 91 | '-p', '--template-path', dest='template_search', |
| 92 | default=script_dir, |
| 93 | help='The space delimited mako template search path.') |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 94 | parser.add_argument( |
| 95 | '-d', '--dir', dest='inputdir', |
| 96 | default=os.path.join(script_dir, 'example'), |
| 97 | help='Location of files to process.') |
| 98 | parser.add_argument( |
| 99 | 'command', metavar='COMMAND', type=str, |
| 100 | choices=valid_commands.keys(), |
| 101 | help='%s.' % " | ".join(valid_commands.keys())) |
Matthew Barth | db440d4 | 2017-04-17 15:49:37 -0500 | [diff] [blame] | 102 | |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 103 | args = parser.parse_args() |
| 104 | |
| 105 | if sys.version_info < (3, 0): |
| 106 | lookup = mako.lookup.TemplateLookup( |
Brad Bishop | e3a01af | 2017-05-15 17:09:04 -0400 | [diff] [blame] | 107 | directories=args.template_search.split(), |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 108 | disable_unicode=True) |
| 109 | else: |
| 110 | lookup = mako.lookup.TemplateLookup( |
Brad Bishop | e3a01af | 2017-05-15 17:09:04 -0400 | [diff] [blame] | 111 | directories=args.template_search.split()) |
Brad Bishop | 34a7acd | 2017-04-27 23:47:23 -0400 | [diff] [blame] | 112 | |
| 113 | function = getattr( |
| 114 | Everything.load(args), |
| 115 | valid_commands[args.command]) |
| 116 | function(lookup) |