blob: 9b5cc2978a717da2e3ef9530e7381906acb31bb3 [file] [log] [blame]
Matthew Barthdb440d42017-04-17 15:49:37 -05001#!/usr/bin/env python
2
Brad Bishop34a7acd2017-04-27 23:47:23 -04003'''Phosphor DBus Monitor YAML parser and code generator.
4
5The 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 Barthdb440d42017-04-17 15:49:37 -050018import os
19import sys
20import yaml
Brad Bishop34a7acd2017-04-27 23:47:23 -040021import mako.lookup
Matthew Barthdb440d42017-04-17 15:49:37 -050022from argparse import ArgumentParser
Brad Bishop34a7acd2017-04-27 23:47:23 -040023from sdbusplus.renderer import Renderer
Matthew Barthdb440d42017-04-17 15:49:37 -050024
25
Brad Bishop34a7acd2017-04-27 23:47:23 -040026class Indent(object):
27 '''Help templates be depth agnostic.'''
Matthew Barthdb440d42017-04-17 15:49:37 -050028
Brad Bishop34a7acd2017-04-27 23:47:23 -040029 def __init__(self, depth=0):
30 self.depth = depth
Matthew Barthdb440d42017-04-17 15:49:37 -050031
Brad Bishop34a7acd2017-04-27 23:47:23 -040032 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
40class 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.'''
64 with open(os.path.join(
65 args.output_dir,
66 'generated.cpp'), 'w') as fd:
67 fd.write(
68 self.render(
69 loader,
70 'generated.mako.cpp',
71 events={},
72 indent=Indent()))
Matthew Barthdb440d42017-04-17 15:49:37 -050073
74if __name__ == '__main__':
Brad Bishop34a7acd2017-04-27 23:47:23 -040075 script_dir = os.path.dirname(os.path.realpath(__file__))
76 valid_commands = {
77 'generate-cpp': 'generate_cpp',
78 }
79
80 parser = ArgumentParser(
81 description='Phosphor DBus Monitor (PDM) YAML '
82 'scanner and code generator.')
83
Matthew Barthdb440d42017-04-17 15:49:37 -050084 parser.add_argument(
85 "-o", "--outdir", dest="output_dir",
86 default=os.path.abspath('.'),
87 help="Output directory for source files generated")
Brad Bishop34a7acd2017-04-27 23:47:23 -040088 parser.add_argument(
89 '-d', '--dir', dest='inputdir',
90 default=os.path.join(script_dir, 'example'),
91 help='Location of files to process.')
92 parser.add_argument(
93 'command', metavar='COMMAND', type=str,
94 choices=valid_commands.keys(),
95 help='%s.' % " | ".join(valid_commands.keys()))
Matthew Barthdb440d42017-04-17 15:49:37 -050096
Brad Bishop34a7acd2017-04-27 23:47:23 -040097 args = parser.parse_args()
98
99 if sys.version_info < (3, 0):
100 lookup = mako.lookup.TemplateLookup(
101 directories=[script_dir],
102 disable_unicode=True)
103 else:
104 lookup = mako.lookup.TemplateLookup(
105 directories=[script_dir])
106
107 function = getattr(
108 Everything.load(args),
109 valid_commands[args.command])
110 function(lookup)