blob: 8ae6044fd0cfa2ec64d823372ad46a618656e9c5 [file] [log] [blame]
Anna Mayzner896ce6d2022-12-12 13:03:43 +00001#!/usr/bin/env python3
2# Copyright (C) 2022 The Android Open Source Project
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
16import argparse
17import os
18import sys
19import json
Anna Mayzner896ce6d2022-12-12 13:03:43 +000020from collections import defaultdict
Anna Mayznerb2153902023-01-06 16:32:49 +000021from typing import Dict
Anna Mayzner896ce6d2022-12-12 13:03:43 +000022
Anna Mayznerb2153902023-01-06 16:32:49 +000023ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
24sys.path.append(os.path.join(ROOT_DIR))
Anna Mayzner896ce6d2022-12-12 13:03:43 +000025
Anna Mayzner1a84bf02023-08-16 09:56:21 +000026from python.generators.sql_processing.docs_parse import parse_file
Anna Mayzner896ce6d2022-12-12 13:03:43 +000027
28
29def main():
30 parser = argparse.ArgumentParser()
31 parser.add_argument('--json-out', required=True)
32 parser.add_argument('--input-list-file')
Anna Mayzner896ce6d2022-12-12 13:03:43 +000033 parser.add_argument('sql_files', nargs='*')
34 args = parser.parse_args()
35
36 if args.input_list_file and args.sql_files:
37 print("Only one of --input-list-file and list of SQL files expected")
38 return 1
39
40 sql_files = []
41 if args.input_list_file:
42 with open(args.input_list_file, 'r') as input_list_file:
43 for line in input_list_file.read().splitlines():
44 sql_files.append(line)
45 else:
46 sql_files = args.sql_files
47
Lalit Maganti9380b0a2023-01-12 10:51:13 +000048 # Unfortunately we cannot pass this in as an arg as soong does not provide
49 # us a way to get the path to the Perfetto source directory. This fails on
50 # empty path but it's a price worth paying to have to use gross hacks in
51 # Soong.
52 root_dir = os.path.commonpath(sql_files)
53
Anna Mayzner896ce6d2022-12-12 13:03:43 +000054 # Extract the SQL output from each file.
Anna Mayznerb2153902023-01-06 16:32:49 +000055 sql_outputs: Dict[str, str] = {}
Anna Mayzner896ce6d2022-12-12 13:03:43 +000056 for file_name in sql_files:
57 with open(file_name, 'r') as f:
Lalit Maganti9380b0a2023-01-12 10:51:13 +000058 relpath = os.path.relpath(file_name, root_dir)
59
60 # We've had bugs (e.g. b/264711057) when Soong's common path logic breaks
61 # and ends up with a bunch of ../ prefixing the path: disallow any ../
62 # as this should never be a valid in our C++ output.
63 assert '../' not in relpath
64
Anna Mayzner896ce6d2022-12-12 13:03:43 +000065 sql_outputs[relpath] = f.read()
66
67 modules = defaultdict(list)
Anna Mayzner896ce6d2022-12-12 13:03:43 +000068 # Add documentation from each file
69 for path, sql in sql_outputs.items():
70 module_name = path.split("/")[0]
Anna Mayzner896ce6d2022-12-12 13:03:43 +000071 import_key = path.split(".sql")[0].replace("/", ".")
Anna Mayzner896ce6d2022-12-12 13:03:43 +000072
Alexander Timin1948c312023-07-28 21:41:08 +010073 docs = parse_file(path, sql)
Anna Mayzner88df9ba2024-02-13 17:06:26 +000074
75 # Some modules (i.e `deprecated`) should not generate docs.
76 if not docs:
77 continue
78
Alexander Timin1948c312023-07-28 21:41:08 +010079 if len(docs.errors) > 0:
80 for e in docs.errors:
81 print(e)
Lalit Magantia7cc41a2023-06-19 17:11:09 +010082 return 1
83
Alexander Timin1948c312023-07-28 21:41:08 +010084 file_dict = {
85 'import_key':
86 import_key,
87 'imports': [{
88 'name': table.name,
89 'desc': table.desc,
Lalit Maganti82717f92024-01-30 13:57:09 +000090 'summary_desc': table.desc.split('\n\n')[0].replace('\n', ' '),
Alexander Timin1948c312023-07-28 21:41:08 +010091 'type': table.type,
Alexander Timin84948912023-10-26 18:05:02 +010092 'cols': {
93 col_name: {
94 'type': col.type,
95 'desc': col.description,
96 } for (col_name, col) in table.cols.items()
97 },
Alexander Timin1948c312023-07-28 21:41:08 +010098 } for table in docs.table_views],
99 'functions': [{
100 'name': function.name,
101 'desc': function.desc,
Lalit Maganti82717f92024-01-30 13:57:09 +0000102 'summary_desc': function.desc.split('\n\n')[0].replace('\n', ' '),
Alexander Timin84948912023-10-26 18:05:02 +0100103 'args': {
104 arg_name: {
105 'type': arg.type,
106 'desc': arg.description,
107 } for (arg_name, arg) in function.args.items()
108 },
Alexander Timin1948c312023-07-28 21:41:08 +0100109 'return_type': function.return_type,
110 'return_desc': function.return_desc,
111 } for function in docs.functions],
Lalit Maganti240a5c02023-09-25 19:24:26 +0100112 'table_functions': [{
Alexander Timin1948c312023-07-28 21:41:08 +0100113 'name': function.name,
114 'desc': function.desc,
Lalit Maganti82717f92024-01-30 13:57:09 +0000115 'summary_desc': function.desc.split('\n\n')[0].replace('\n', ' '),
Alexander Timin84948912023-10-26 18:05:02 +0100116 'args': {
117 arg_name: {
118 'type': arg.type,
119 'desc': arg.description,
120 } for (arg_name, arg) in function.args.items()
121 },
122 'cols': {
123 col_name: {
124 'type': col.type,
125 'desc': col.description,
126 } for (col_name, col) in function.cols.items()
127 },
Alexander Timin1948c312023-07-28 21:41:08 +0100128 } for function in docs.table_functions],
Lalit Maganti82717f92024-01-30 13:57:09 +0000129 'macros': [{
130 'name': macro.name,
131 'desc': macro.desc,
132 'summary_desc': macro.desc.split('\n\n')[0].replace('\n', ' '),
133 'return_desc': macro.return_desc,
134 'return_type': macro.return_type,
135 'args': {
136 arg_name: {
137 'type': arg.type,
138 'desc': arg.description,
139 } for (arg_name, arg) in macro.args.items()
140 },
141 } for macro in docs.macros],
Alexander Timin1948c312023-07-28 21:41:08 +0100142 }
Anna Mayzner896ce6d2022-12-12 13:03:43 +0000143 modules[module_name].append(file_dict)
144
145 with open(args.json_out, 'w+') as f:
146 json.dump(modules, f, indent=4)
147
148 return 0
149
150
151if __name__ == '__main__':
152 sys.exit(main())