• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3# Copyright (c) 2024 Huawei Device Co., Ltd.
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 json
18import os
19import time
20import stat
21import utils
22
23
24def _get_args():
25    parser = argparse.ArgumentParser(add_help=True)
26    parser.add_argument(
27        "-p", "--input_path",
28        default=r"./", type=str,
29        help="Path of source code",
30    )
31    parser.add_argument(
32        "-rp", "--root_path",
33        default=r"./", type=str,
34        help="Path of root",
35    )
36    parser.add_argument(
37        "-t", "--test",
38        default=1, type=int,
39        help="whether the target contains test type. default 0 , choices: 0 or 1 2",
40    )
41    args = parser.parse_args()
42    return args
43
44
45def _judge_type(element, deps_list: list):
46    if isinstance(element, dict):
47        for k, v in element.items():
48            _judge_type(v, deps_list)
49    elif isinstance(element, list):
50        for v in element:
51            _judge_type(v, deps_list)
52    elif isinstance(element, str):
53        deps_list.append(element)
54
55
56def _inner_kits_name(inner_kits_list, deps_list):
57    if inner_kits_list:
58        for k in inner_kits_list:
59            deps_list.append(k['name'])
60
61
62def _output_build_gn(deps_list, output_path, _test_check):
63    file_name = os.path.join(output_path, 'BUILD.gn')
64    if os.path.exists(file_name):
65        os.remove(file_name)
66    flags = os.O_WRONLY | os.O_CREAT
67    modes = stat.S_IWUSR | stat.S_IRUSR
68    with os.fdopen(os.open(file_name, flags, modes), 'w') as f:
69        f.write('import("//build/ohos_var.gni")\n')
70        f.write('\n')
71        f.write('group("default") {\n')
72        if _test_check:
73            f.write('    testonly = true\n')
74        f.write('    deps = [\n')
75        for i in deps_list:
76            f.write(f"        \"{i}\",\n")
77        f.write('    ]\n')
78        f.write('}\n')
79
80
81def _get_bundle_path(source_code_path):
82    bundle_paths = dict()
83    for root, dirs, files in os.walk(source_code_path):
84        for file in files:
85            if file == "bundle.json":
86                bundle_paths.update({os.path.join(root, file): root})
87    return bundle_paths
88
89
90def _get_src_part_name(src_bundle_paths):
91    _name = ''
92    _path = ''
93    _bundle_path = ''
94    for src_bundle_path, v_path in src_bundle_paths.items():
95        src_bundle_json = utils.get_json(src_bundle_path)
96        part_name = ''
97        try:
98            part_name = src_bundle_json['component']['name']
99        except KeyError:
100            print(f'--get bundle json component name error--')
101        if part_name.endswith('_lite'):
102            pass
103        else:
104            _name = part_name
105            _bundle_path = src_bundle_path
106            _path = v_path
107    return _bundle_path, _path
108
109
110def _target_handle(ele, build_data, deps_list, _test_check):
111    if ele not in ['inner_kits', 'test', 'inner_api']:
112        _judge_type(build_data[ele], deps_list)
113    elif ele in ['inner_kits', 'inner_api']:
114        inner_kits_list = build_data[ele]
115        _inner_kits_name(inner_kits_list, deps_list)
116
117    if _test_check == 1 and ele == 'test':
118        inner_kits_list = build_data[ele]
119        for k in inner_kits_list:
120            deps_list.append(k)
121
122
123def process_build_data(build_data, _test_check, deps_list):
124    for ele in build_data:
125        _target_handle(ele, build_data, deps_list, _test_check)
126
127
128def handle_test_check(build_data, _test_check, deps_list):
129    if _test_check == 2:
130        inner_kits_list = build_data.get('test', [])
131        if inner_kits_list:
132            for k in inner_kits_list:
133                deps_list.append(k)
134
135
136def process_bundle_path(_bundle_path, _test_check, deps_list):
137    bundle_json = utils.get_json(_bundle_path)
138    build_data = bundle_json.get("component", {}).get("build", {})
139    if _test_check == 0:
140        process_build_data(build_data, _test_check, deps_list)
141    elif _test_check == 1:
142        process_build_data(build_data, _test_check, deps_list)
143        handle_test_check(build_data, _test_check, deps_list)
144    elif _test_check == 2:
145        handle_test_check(build_data, _test_check, deps_list)
146    else:
147        print("Error: Please pass the correct test parameters")
148
149
150def process_inner_fields(module_to_path, all_target_list):
151    # 检查并处理可能的字段名称
152    for item in all_target_list:
153        fullpath = item
154        module = fullpath.split(":")[-1]
155        module_to_path[module] = fullpath
156
157
158def target_args_handle(_bundle_path, build_target_list, deps_list):
159    bundle_json = utils.get_json(_bundle_path)
160    build_data = bundle_json.get("component", {}).get("build", {})
161
162    all_target_list = []
163    module_to_path = {}
164
165    # 获取所有目标列表和module到全路径的映射
166    process_target_data(build_data, all_target_list, module_to_path)
167
168    # 处理构建目标列表,返回依赖列表
169    return process_build_target_list(build_target_list, module_to_path, deps_list)
170
171
172def process_target_data(build_data, all_target_list, module_to_path):
173    # 获取所有目标列表
174    process_build_data(build_data, 1, all_target_list)
175    # 获取module到全路径的映射
176    process_inner_fields(module_to_path, all_target_list)
177
178
179def process_build_target_list(build_target_list, module_to_path, deps_list):
180    for item in build_target_list:
181        if item.startswith("//"):
182            # 如果是全路径,直接添加
183            add_to_deps_list(deps_list, item)
184        else:
185            # 如果不是全路径,查找对应的module
186            fullpath = module_to_path.get(item)
187            if fullpath:
188                add_to_deps_list(deps_list, fullpath)
189    return deps_list
190
191
192def add_to_deps_list(deps_list, item):
193    if item not in deps_list:
194        deps_list.append(item)
195
196
197def main():
198    args = _get_args()
199    source_code_paths = args.input_path.split(',')
200    _test_check = args.test
201    output_path = os.path.join(args.root_path, 'out')
202    deps_list = []
203    build_target_list = utils.get_build_target()
204
205    for source_code_path in source_code_paths:
206        bundle_paths = _get_bundle_path(source_code_path)
207        for _bundle_path in bundle_paths:
208            if build_target_list:
209                deps_list = target_args_handle(_bundle_path, build_target_list, deps_list)
210            else:
211                process_bundle_path(_bundle_path, _test_check, deps_list)
212    _output_build_gn(deps_list, output_path, _test_check)
213
214
215if __name__ == '__main__':
216    main()
217