xref: /build/hb/util/component_util.py (revision 5f9996aa)
15f9996aaSopenharmony_ci#!/usr/bin/env python
25f9996aaSopenharmony_ci# -*- coding: utf-8 -*-
35f9996aaSopenharmony_ci
45f9996aaSopenharmony_ci#
55f9996aaSopenharmony_ci# Copyright (c) 2023 Huawei Device Co., Ltd.
65f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License");
75f9996aaSopenharmony_ci# you may not use this file except in compliance with the License.
85f9996aaSopenharmony_ci# You may obtain a copy of the License at
95f9996aaSopenharmony_ci#
105f9996aaSopenharmony_ci#     http://www.apache.org/licenses/LICENSE-2.0
115f9996aaSopenharmony_ci#
125f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software
135f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS,
145f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
155f9996aaSopenharmony_ci# See the License for the specific language governing permissions and
165f9996aaSopenharmony_ci# limitations under the License.
175f9996aaSopenharmony_ci
185f9996aaSopenharmony_ciimport os
195f9996aaSopenharmony_ciimport re
205f9996aaSopenharmony_ciimport sys
215f9996aaSopenharmony_ci
225f9996aaSopenharmony_cifrom resources.global_var import CURRENT_OHOS_ROOT
235f9996aaSopenharmony_cifrom resources.global_var import COMPONENTS_PATH_DIR
245f9996aaSopenharmony_cifrom exceptions.ohos_exception import OHOSException
255f9996aaSopenharmony_cifrom util.io_util import IoUtil
265f9996aaSopenharmony_cifrom containers.status import throw_exception
275f9996aaSopenharmony_ci
285f9996aaSopenharmony_ci
295f9996aaSopenharmony_cidef get_part_name():
305f9996aaSopenharmony_ci    part_name_list = []
315f9996aaSopenharmony_ci    if len(sys.argv) > 2 and not sys.argv[2].startswith("-"):
325f9996aaSopenharmony_ci        for name in sys.argv[2:]:
335f9996aaSopenharmony_ci            if not name.startswith('-'):
345f9996aaSopenharmony_ci                part_name_list.append(name)
355f9996aaSopenharmony_ci            else:
365f9996aaSopenharmony_ci                break
375f9996aaSopenharmony_ci    return part_name_list
385f9996aaSopenharmony_ci
395f9996aaSopenharmony_ci
405f9996aaSopenharmony_ciclass ComponentUtil():
415f9996aaSopenharmony_ci
425f9996aaSopenharmony_ci    @staticmethod
435f9996aaSopenharmony_ci    def is_in_component_dir(path: str) -> bool:
445f9996aaSopenharmony_ci        return _recurrent_search_bundle_file(path)[0]
455f9996aaSopenharmony_ci
465f9996aaSopenharmony_ci    @staticmethod
475f9996aaSopenharmony_ci    def is_component_in_product(component_name: str, product_name: str) -> bool:
485f9996aaSopenharmony_ci        build_configs_path = os.path.join(
495f9996aaSopenharmony_ci            CURRENT_OHOS_ROOT, 'out', product_name, 'build_configs')
505f9996aaSopenharmony_ci        if os.path.exists(build_configs_path):
515f9996aaSopenharmony_ci            for root, dirs, files in os.walk(build_configs_path, topdown=True, followlinks=False):
525f9996aaSopenharmony_ci                if component_name in dirs:
535f9996aaSopenharmony_ci                    return True
545f9996aaSopenharmony_ci        return False
555f9996aaSopenharmony_ci
565f9996aaSopenharmony_ci    @staticmethod
575f9996aaSopenharmony_ci    def get_component_name(path: str) -> str:
585f9996aaSopenharmony_ci        found_bundle_file, bundle_path = _recurrent_search_bundle_file(path)
595f9996aaSopenharmony_ci        if found_bundle_file:
605f9996aaSopenharmony_ci            data = IoUtil.read_json_file(bundle_path)
615f9996aaSopenharmony_ci            return data['component']['name']
625f9996aaSopenharmony_ci
635f9996aaSopenharmony_ci        return ''
645f9996aaSopenharmony_ci
655f9996aaSopenharmony_ci    @staticmethod
665f9996aaSopenharmony_ci    def get_component(path: str) -> str:
675f9996aaSopenharmony_ci        found_bundle_file, bundle_path = _recurrent_search_bundle_file(path)
685f9996aaSopenharmony_ci        if found_bundle_file:
695f9996aaSopenharmony_ci            data = IoUtil.read_json_file(bundle_path)
705f9996aaSopenharmony_ci            return data['component']['name'], os.path.dirname(bundle_path)
715f9996aaSopenharmony_ci
725f9996aaSopenharmony_ci        return '', ''
735f9996aaSopenharmony_ci
745f9996aaSopenharmony_ci    @staticmethod
755f9996aaSopenharmony_ci    def get_default_deps(variant: str) -> str:
765f9996aaSopenharmony_ci        gen_default_deps_json(variant, CURRENT_OHOS_ROOT)
775f9996aaSopenharmony_ci        default_deps_path = os.path.join(
785f9996aaSopenharmony_ci            CURRENT_OHOS_ROOT, 'out', 'preloader', 'default_deps.json')
795f9996aaSopenharmony_ci        return default_deps_path
805f9996aaSopenharmony_ci
815f9996aaSopenharmony_ci    @staticmethod
825f9996aaSopenharmony_ci    @throw_exception
835f9996aaSopenharmony_ci    def get_component_module_full_name(out_path: str, component_name: str, module_name: str) -> str:
845f9996aaSopenharmony_ci        root_path = os.path.join(out_path, "build_configs")
855f9996aaSopenharmony_ci        target_info = ""
865f9996aaSopenharmony_ci        module_list = []
875f9996aaSopenharmony_ci        for file in os.listdir(root_path):
885f9996aaSopenharmony_ci            if len(target_info):
895f9996aaSopenharmony_ci                break
905f9996aaSopenharmony_ci            file_path = os.path.join(root_path, file)
915f9996aaSopenharmony_ci            if not os.path.isdir(file_path):
925f9996aaSopenharmony_ci                continue
935f9996aaSopenharmony_ci            for component in os.listdir(file_path):
945f9996aaSopenharmony_ci                if os.path.isdir(os.path.join(file_path, component)) and component == component_name:
955f9996aaSopenharmony_ci                    target_info = IoUtil.read_file(
965f9996aaSopenharmony_ci                        os.path.join(file_path, component, "BUILD.gn"))
975f9996aaSopenharmony_ci                    break
985f9996aaSopenharmony_ci        pattern = re.compile(r'(?<=module_list = )\[([^\[\]]*)\]')
995f9996aaSopenharmony_ci        results = pattern.findall(target_info)
1005f9996aaSopenharmony_ci        for each_tuple in results:
1015f9996aaSopenharmony_ci            module_list = each_tuple.replace('\n', '').replace(
1025f9996aaSopenharmony_ci                ' ', '').replace('\"', '').split(',')
1035f9996aaSopenharmony_ci        for target_path in module_list:
1045f9996aaSopenharmony_ci            if target_path != '':
1055f9996aaSopenharmony_ci                path, target = target_path.split(":")
1065f9996aaSopenharmony_ci                if target == module_name:
1075f9996aaSopenharmony_ci                    return target_path
1085f9996aaSopenharmony_ci
1095f9996aaSopenharmony_ci        raise OHOSException('You are trying to compile a module {} which do not exists in {} while compiling {}'.format(
1105f9996aaSopenharmony_ci            module_name, component_name, out_path), "4001")
1115f9996aaSopenharmony_ci
1125f9996aaSopenharmony_ci    @staticmethod
1135f9996aaSopenharmony_ci    def search_bundle_file(component_name: str):
1145f9996aaSopenharmony_ci        all_bundle_path = get_all_bundle_path(CURRENT_OHOS_ROOT)
1155f9996aaSopenharmony_ci        return all_bundle_path.get(component_name)
1165f9996aaSopenharmony_ci
1175f9996aaSopenharmony_ci
1185f9996aaSopenharmony_cidef _recurrent_search_bundle_file(path: str):
1195f9996aaSopenharmony_ci    cur_dir = path
1205f9996aaSopenharmony_ci    while cur_dir != CURRENT_OHOS_ROOT:
1215f9996aaSopenharmony_ci        bundle_json = os.path.join(
1225f9996aaSopenharmony_ci            cur_dir, 'bundle.json')
1235f9996aaSopenharmony_ci        if os.path.exists(bundle_json):
1245f9996aaSopenharmony_ci            return True, bundle_json
1255f9996aaSopenharmony_ci        cur_dir = os.path.dirname(cur_dir)
1265f9996aaSopenharmony_ci    return False, ''
1275f9996aaSopenharmony_ci
1285f9996aaSopenharmony_ci
1295f9996aaSopenharmony_cidef get_all_bundle_path(path):
1305f9996aaSopenharmony_ci    bundles_path = {}
1315f9996aaSopenharmony_ci    for root, dirnames, filenames in os.walk(path):
1325f9996aaSopenharmony_ci        if root == os.path.join(path, "out") or root == os.path.join(path, ".repo"):
1335f9996aaSopenharmony_ci            continue
1345f9996aaSopenharmony_ci        for filename in filenames:
1355f9996aaSopenharmony_ci            if filename == "bundle.json":
1365f9996aaSopenharmony_ci                bundle_json = os.path.join(root, filename)
1375f9996aaSopenharmony_ci                data = IoUtil.read_json_file(bundle_json)
1385f9996aaSopenharmony_ci                bundles_path = process_bundle_path(bundle_json, bundles_path, data)
1395f9996aaSopenharmony_ci    IoUtil.dump_json_file(COMPONENTS_PATH_DIR, bundles_path)
1405f9996aaSopenharmony_ci    return bundles_path
1415f9996aaSopenharmony_ci
1425f9996aaSopenharmony_ci
1435f9996aaSopenharmony_cidef process_bundle_path(bundle_json, bundles_path, data):
1445f9996aaSopenharmony_ci    if data.get("component") and data.get("component").get("name"):
1455f9996aaSopenharmony_ci        bundles_path[data["component"]["name"]] = os.path.dirname(bundle_json)
1465f9996aaSopenharmony_ci    return bundles_path
1475f9996aaSopenharmony_ci
1485f9996aaSopenharmony_ci
1495f9996aaSopenharmony_cidef gen_default_deps_json(variant, root_path):
1505f9996aaSopenharmony_ci    part_name_list = get_part_name()
1515f9996aaSopenharmony_ci    default_deps_out_file = os.path.join(root_path, "out", "preloader", "default_deps.json")
1525f9996aaSopenharmony_ci    default_deps_file = os.path.join(root_path, "build", "indep_configs", "variants", "common", 'default_deps.json')
1535f9996aaSopenharmony_ci    default_deps_json = IoUtil.read_json_file(default_deps_file)
1545f9996aaSopenharmony_ci    default_deps_json.append("variants_" + variant)
1555f9996aaSopenharmony_ci
1565f9996aaSopenharmony_ci    part_white_list_path = os.path.join(root_path, "build", "indep_configs", "config",
1575f9996aaSopenharmony_ci                                        "rust_download_part_whitelist.json")
1585f9996aaSopenharmony_ci    part_white_list = IoUtil.read_json_file(part_white_list_path)
1595f9996aaSopenharmony_ci    for part_name in part_name_list:
1605f9996aaSopenharmony_ci        if part_name in part_white_list and 'rust' not in default_deps_json:
1615f9996aaSopenharmony_ci            default_deps_json.append('rust')
1625f9996aaSopenharmony_ci
1635f9996aaSopenharmony_ci    preloader_path = os.path.join(root_path, "out", "preloader")
1645f9996aaSopenharmony_ci    os.makedirs(preloader_path, exist_ok=True)
1655f9996aaSopenharmony_ci    IoUtil.dump_json_file(default_deps_out_file, default_deps_json)
166