blob: 072f7d687ba74d7b8eb313e27a32ce01b9e10988 [file] [log] [blame]
Brad Bishopbf066a62016-10-19 08:09:44 -04001#!/usr/bin/env python
2
3import sys
4import os
5import re
6import argparse
7import yaml
Brad Bishopcfb3c892016-11-12 11:43:37 -05008import subprocess
Brad Bishop92665b22016-10-26 20:51:16 -05009from mako.template import Template
Brad Bishopbf066a62016-10-19 08:09:44 -040010
11valid_c_name_pattern = re.compile('[\W_]+')
Brad Bishopbf066a62016-10-19 08:09:44 -040012
13
Brad Bishop92665b22016-10-26 20:51:16 -050014def parse_event(e):
15 e['name'] = valid_c_name_pattern.sub('_', e['name']).lower()
16 if e.get('filter') is None:
17 e.setdefault('filter', {}).setdefault('type', 'none')
18 if e.get('action') is None:
19 e.setdefault('action', {}).setdefault('type', 'noop')
20 return e
Brad Bishopbf066a62016-10-19 08:09:44 -040021
Brad Bishopcfb3c892016-11-12 11:43:37 -050022
Brad Bishop14a9fe52016-11-12 12:51:26 -050023def get_interfaces(args):
24 interfaces_dir = os.path.join(args.inputdir, 'interfaces.d')
25 yaml_files = filter(
26 lambda x: x.endswith('.yaml'),
27 os.listdir(interfaces_dir))
28
29 interfaces = []
30 for x in yaml_files:
31 with open(os.path.join(interfaces_dir, x), 'r') as fd:
32 for i in yaml.load(fd.read()):
33 interfaces.append(i)
34
35 return interfaces
36
37
38def list_interfaces(args):
39 print ' '.join(get_interfaces(args))
40
41
Brad Bishop95dd98f2016-11-12 12:39:15 -050042def generate_cpp(args):
Brad Bishop3904cf42016-11-12 12:00:03 -050043 # Aggregate all the event YAML in the events.d directory
Brad Bishopcfb3c892016-11-12 11:43:37 -050044 # into a single list of events.
Brad Bishop3904cf42016-11-12 12:00:03 -050045 events_dir = os.path.join(args.inputdir, 'events.d')
Brad Bishopbf066a62016-10-19 08:09:44 -040046 yaml_files = filter(
47 lambda x: x.endswith('.yaml'),
Brad Bishopbbf13bd2016-11-09 22:29:09 -050048 os.listdir(events_dir))
Brad Bishopbf066a62016-10-19 08:09:44 -040049
Brad Bishop92665b22016-10-26 20:51:16 -050050 events = []
51 for x in yaml_files:
Brad Bishopbbf13bd2016-11-09 22:29:09 -050052 with open(os.path.join(events_dir, x), 'r') as fd:
Brad Bishop92665b22016-10-26 20:51:16 -050053 for e in yaml.load(fd.read()).get('events', {}):
54 events.append(parse_event(e))
Brad Bishopbf066a62016-10-19 08:09:44 -040055
Brad Bishop0a6a4792016-11-12 12:10:07 -050056 # Aggregate all the interface YAML in the interfaces.d
57 # directory into a single list of interfaces.
58 template = os.path.join(script_dir, 'generated.mako.cpp')
59 t = Template(filename=template)
60
Brad Bishop14a9fe52016-11-12 12:51:26 -050061 interfaces = get_interfaces(args)
Brad Bishop561a5652016-10-26 21:13:32 -050062
Brad Bishopcfb3c892016-11-12 11:43:37 -050063 # Render the template with the provided events and interfaces.
64 template = os.path.join(script_dir, 'generated.mako.cpp')
65 t = Template(filename=template)
Brad Bishop4d16b692016-11-12 11:45:35 -050066 with open(os.path.join(args.outputdir, 'generated.cpp'), 'w') as fd:
Brad Bishop92665b22016-10-26 20:51:16 -050067 fd.write(
68 t.render(
Brad Bishop561a5652016-10-26 21:13:32 -050069 interfaces=interfaces,
Brad Bishop92665b22016-10-26 20:51:16 -050070 events=events))
71
Brad Bishopcfb3c892016-11-12 11:43:37 -050072 # Invoke sdbus++ to generate any extra interface bindings for
73 # extra interfaces that aren't defined externally.
74 yaml_files = []
Brad Bishopea6d93a2016-11-12 12:02:24 -050075 extra_ifaces_dir = os.path.join(args.inputdir, 'extra_interfaces.d')
Brad Bishopcfb3c892016-11-12 11:43:37 -050076 if os.path.exists(extra_ifaces_dir):
77 for directory, _, files in os.walk(extra_ifaces_dir):
78 if not files:
79 continue
80
81 yaml_files += map(
82 lambda f: os.path.relpath(
83 os.path.join(directory, f),
84 extra_ifaces_dir),
85 filter(lambda f: f.endswith('.interface.yaml'), files))
86
87 genfiles = {
88 'server-cpp': lambda x: '%s.cpp' % (
89 x.replace(os.sep, '.')),
90 'server-header': lambda x: os.path.join(
91 os.path.join(
92 *x.split('.')), 'server.hpp')
93 }
94
95 for i in yaml_files:
96 iface = i.replace('.interface.yaml', '').replace(os.sep, '.')
97 for process, f in genfiles.iteritems():
98
99 dest = os.path.join(args.outputdir, f(iface))
100 parent = os.path.dirname(dest)
101 if parent and not os.path.exists(parent):
102 os.makedirs(parent)
103
104 with open(dest, 'w') as fd:
105 subprocess.call([
106 'sdbus++',
107 '-r',
108 extra_ifaces_dir,
109 'interface',
110 process,
111 iface],
112 stdout=fd)
Brad Bishopbf066a62016-10-19 08:09:44 -0400113
Brad Bishop95dd98f2016-11-12 12:39:15 -0500114
115if __name__ == '__main__':
116 script_dir = os.path.dirname(os.path.realpath(__file__))
Brad Bishop14a9fe52016-11-12 12:51:26 -0500117 valid_commands = {
118 'generate-cpp': 'generate_cpp',
119 'list-interfaces': 'list_interfaces'}
Brad Bishop95dd98f2016-11-12 12:39:15 -0500120
121 parser = argparse.ArgumentParser(
122 description='Phosphor Inventory Manager (PIM) YAML '
123 'scanner and code generator.')
124 parser.add_argument(
125 '-o', '--output-dir', dest='outputdir',
126 default='.', help='Output directory.')
127 parser.add_argument(
128 '-d', '--dir', dest='inputdir',
129 default=os.path.join(script_dir, 'example'),
130 help='Location of files to process.')
Brad Bishopf4666f52016-11-12 12:44:42 -0500131 parser.add_argument(
132 'command', metavar='COMMAND', type=str,
133 choices=valid_commands.keys(),
134 help='Command to run.')
Brad Bishop95dd98f2016-11-12 12:39:15 -0500135
136 args = parser.parse_args()
Brad Bishopf4666f52016-11-12 12:44:42 -0500137 function = getattr(sys.modules[__name__], valid_commands[args.command])
138 function(args)
Brad Bishop95dd98f2016-11-12 12:39:15 -0500139
140
Brad Bishopbf066a62016-10-19 08:09:44 -0400141# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4