ip: Router ID included in flow hash
[vpp.git] / docs / includes_renderer.py
1 #!/usr/bin/env python3
2 #  Copyright (c) 2020. Vinci Consulting Corp. All Rights Reserved.
3 #
4 #  Licensed under the Apache License, Version 2.0 (the "License");
5 #  you may not use this file except in compliance with the License.
6 #  You may obtain a copy of the License at
7 #
8 #      http://www.apache.org/licenses/LICENSE-2.0
9 #
10 #  Unless required by applicable law or agreed to in writing, software
11 #  distributed under the License is distributed on an "AS IS" BASIS,
12 #  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 #  See the License for the specific language governing permissions and
14 #  limitations under the License.
15
16 import glob
17 import inspect
18 import os.path
19 import re
20
21
22 class ContentRenderer:
23     name = ""
24     curr_path = os.path.abspath(inspect.getsourcefile(lambda: 0))
25     vpp_root = curr_path.rsplit("/", 2)[0]
26     output_dir = f"{vpp_root}/docs/dynamic_includes/"
27
28     def render(self):
29         raise NotImplementedError
30
31
32 class PluginRenderer(ContentRenderer):
33     name = "plugin_list.inc"
34
35     plugin_dir = f"{ContentRenderer.vpp_root}/src/plugins"
36
37     pattern = r'VLIB_PLUGIN_REGISTER\s?\(\)\s*=\s*{.*\.description\s?=\s?"([^"]*)".*};'  # noqa: 501
38     regex = re.compile(pattern, re.MULTILINE | re.DOTALL)
39
40     def render(self):
41         with open(f"{self.__class__.output_dir}{self.__class__.name}",
42                   "w") as output:
43             with os.scandir(self.__class__.plugin_dir) as pdir:
44                 for entry in sorted(pdir, key=lambda entry: entry.name):
45                     if not entry.name.startswith('.') and entry.is_dir():
46                         description = "<no-description-found>"
47                         # we use glob because a plugin can (ioam for now)
48                         # define the plugin definition in
49                         # a further subdirectory.
50                         for f in glob.iglob(f'{self.__class__.plugin_dir}/'
51                                             f'{entry.name}/**',
52                                             recursive=True):
53                             if f.endswith('.c'):
54                                 with open(f, "r", encoding="utf-8") \
55                                         as src:
56                                     for match in self.__class__.regex.finditer(
57                                             src.read()):
58                                         description = "%s" % (match.group(1))
59
60                         output.write(f"* {entry.name} - {description}\n")
61
62
63 # if this list grows substantially, we can move the classes to
64 # a folder and import them.
65 renderers = [PluginRenderer,
66              ]
67
68
69 def main():
70     print("rendering dynamic includes...")
71     for renderer in renderers:
72         renderer().render()
73     print("done.")
74
75
76 if __name__ == "__main__":
77     main()