15f9996aaSopenharmony_ci#!/usr/bin/env python 25f9996aaSopenharmony_ci# -*- coding: utf-8 -*- 35f9996aaSopenharmony_ci# Copyright (c) 2021 Huawei Device Co., Ltd. 45f9996aaSopenharmony_ci# Licensed under the Apache License, Version 2.0 (the "License"); 55f9996aaSopenharmony_ci# you may not use this file except in compliance with the License. 65f9996aaSopenharmony_ci# You may obtain a copy of the License at 75f9996aaSopenharmony_ci# 85f9996aaSopenharmony_ci# http://www.apache.org/licenses/LICENSE-2.0 95f9996aaSopenharmony_ci# 105f9996aaSopenharmony_ci# Unless required by applicable law or agreed to in writing, software 115f9996aaSopenharmony_ci# distributed under the License is distributed on an "AS IS" BASIS, 125f9996aaSopenharmony_ci# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f9996aaSopenharmony_ci# See the License for the specific language governing permissions and 145f9996aaSopenharmony_ci# limitations under the License. 155f9996aaSopenharmony_ci 165f9996aaSopenharmony_ciimport sys 175f9996aaSopenharmony_ciimport argparse 185f9996aaSopenharmony_ciimport os 195f9996aaSopenharmony_ciimport json 205f9996aaSopenharmony_ciimport copy 215f9996aaSopenharmony_ci 225f9996aaSopenharmony_cisys.path.append( 235f9996aaSopenharmony_ci os.path.dirname(os.path.dirname(os.path.dirname( 245f9996aaSopenharmony_ci os.path.abspath(__file__))))) 255f9996aaSopenharmony_cifrom scripts.util import build_utils # noqa E402 265f9996aaSopenharmony_ci 275f9996aaSopenharmony_cideps_metadta_cache = {} 285f9996aaSopenharmony_ci 295f9996aaSopenharmony_ci 305f9996aaSopenharmony_cidef get_all_deps(direct_deps): 315f9996aaSopenharmony_ci if direct_deps == []: 325f9996aaSopenharmony_ci return [] 335f9996aaSopenharmony_ci deps = copy.deepcopy(direct_deps) 345f9996aaSopenharmony_ci all_deps = set() 355f9996aaSopenharmony_ci all_deps.update(deps) 365f9996aaSopenharmony_ci while len(deps) > 0: 375f9996aaSopenharmony_ci dep = deps.pop(0) 385f9996aaSopenharmony_ci if dep not in deps_metadta_cache: 395f9996aaSopenharmony_ci with open(dep) as dep_fp: 405f9996aaSopenharmony_ci deps_metadta_cache[dep] = json.load(dep_fp).get('root') 415f9996aaSopenharmony_ci for n in deps_metadta_cache[dep].get('metadata_deps'): 425f9996aaSopenharmony_ci if n not in all_deps: 435f9996aaSopenharmony_ci deps.append(n) 445f9996aaSopenharmony_ci all_deps.add(n) 455f9996aaSopenharmony_ci return sorted(list(all_deps)) 465f9996aaSopenharmony_ci 475f9996aaSopenharmony_ci 485f9996aaSopenharmony_cidef get_deps_metadata(deps): 495f9996aaSopenharmony_ci return [deps_metadta_cache.get(d) for d in deps] 505f9996aaSopenharmony_ci 515f9996aaSopenharmony_ci 525f9996aaSopenharmony_cidef get_deps_of_type(deps_data, target_type): 535f9996aaSopenharmony_ci return [d for d in deps_data if d.get('type') == target_type] 545f9996aaSopenharmony_ci 555f9996aaSopenharmony_ci 565f9996aaSopenharmony_ciclass Deps(object): 575f9996aaSopenharmony_ci def __init__(self, direct_deps): 585f9996aaSopenharmony_ci self.direct_deps = direct_deps 595f9996aaSopenharmony_ci self.all_deps = get_all_deps(direct_deps) 605f9996aaSopenharmony_ci self.all_deps_data = get_deps_metadata(self.all_deps) 615f9996aaSopenharmony_ci 625f9996aaSopenharmony_ci def all(self, target_type): 635f9996aaSopenharmony_ci return get_deps_of_type(self.all_deps_data, target_type) 645f9996aaSopenharmony_ci 655f9996aaSopenharmony_ci 665f9996aaSopenharmony_cidef write_meta_data(options, direct_deps): 675f9996aaSopenharmony_ci meta_data = { 685f9996aaSopenharmony_ci 'root': { 695f9996aaSopenharmony_ci 'type': options.type, 705f9996aaSopenharmony_ci 'metadata_path': options.output, 715f9996aaSopenharmony_ci 'metadata_deps': direct_deps 725f9996aaSopenharmony_ci } 735f9996aaSopenharmony_ci } 745f9996aaSopenharmony_ci root = meta_data['root'] 755f9996aaSopenharmony_ci if options.type == 'app_profile': 765f9996aaSopenharmony_ci root[options.type] = options.app_profile 775f9996aaSopenharmony_ci root['resources'] = options.resources 785f9996aaSopenharmony_ci if options.type == 'js_assets': 795f9996aaSopenharmony_ci root[options.type] = options.js_assets 805f9996aaSopenharmony_ci if options.js_forms: 815f9996aaSopenharmony_ci root['js_forms'] = options.js_forms 825f9996aaSopenharmony_ci if options.testrunner: 835f9996aaSopenharmony_ci root['testrunner'] = options.testrunner 845f9996aaSopenharmony_ci if options.type == 'ets_assets': 855f9996aaSopenharmony_ci root[options.type] = options.ets_assets 865f9996aaSopenharmony_ci if options.type == 'assets': 875f9996aaSopenharmony_ci root[options.type] = options.raw_assets 885f9996aaSopenharmony_ci if options.type == 'unresolved_assets': 895f9996aaSopenharmony_ci root[options.type] = options.unresolved_assets 905f9996aaSopenharmony_ci if options.type == 'resources': 915f9996aaSopenharmony_ci deps = Deps(direct_deps) 925f9996aaSopenharmony_ci root[options.type] = options.resources 935f9996aaSopenharmony_ci package_name = options.package_name 945f9996aaSopenharmony_ci root['package_name'] = package_name if package_name else "" 955f9996aaSopenharmony_ci for target_type in ['app_profile']: 965f9996aaSopenharmony_ci for dep in deps.all(target_type): 975f9996aaSopenharmony_ci if root.get(target_type): 985f9996aaSopenharmony_ci root.get(target_type).extend(dep[target_type]) 995f9996aaSopenharmony_ci root.get('resources').extend(dep['resources']) 1005f9996aaSopenharmony_ci else: 1015f9996aaSopenharmony_ci root[target_type] = dep[target_type] 1025f9996aaSopenharmony_ci root['resources'] += dep['resources'] 1035f9996aaSopenharmony_ci if options.type == 'hap' or options.type == 'resources': 1045f9996aaSopenharmony_ci hap_profile = options.hap_profile 1055f9996aaSopenharmony_ci root['hap_profile'] = hap_profile if hap_profile else "" 1065f9996aaSopenharmony_ci 1075f9996aaSopenharmony_ci # Merge all metadata 1085f9996aaSopenharmony_ci if options.type == 'hap': 1095f9996aaSopenharmony_ci deps = Deps(direct_deps) 1105f9996aaSopenharmony_ci root['hap_path'] = options.hap_path 1115f9996aaSopenharmony_ci for target_type in ['js_assets', 'ets_assets', 'assets', 'resources']: 1125f9996aaSopenharmony_ci root[target_type] = [] 1135f9996aaSopenharmony_ci if options.js_assets: 1145f9996aaSopenharmony_ci root['js_assets'] = options.js_assets 1155f9996aaSopenharmony_ci if options.ets_assets: 1165f9996aaSopenharmony_ci root['ets_assets'] = options.ets_assets 1175f9996aaSopenharmony_ci if options.raw_assets: 1185f9996aaSopenharmony_ci root['assets'] = options.raw_assets 1195f9996aaSopenharmony_ci if options.resources: 1205f9996aaSopenharmony_ci root['resources'] = options.resources 1215f9996aaSopenharmony_ci for target_type in ['js_assets', 'ets_assets', 'assets', 'resources', 'app_profile']: 1225f9996aaSopenharmony_ci for dep in deps.all(target_type): 1235f9996aaSopenharmony_ci if root.get(target_type): 1245f9996aaSopenharmony_ci root.get(target_type).extend(dep[target_type]) 1255f9996aaSopenharmony_ci root.get('hap_profile').extend(dep['hap_profile']) 1265f9996aaSopenharmony_ci else: 1275f9996aaSopenharmony_ci root[target_type] = dep[target_type] 1285f9996aaSopenharmony_ci if dep.get('hap_profile'): 1295f9996aaSopenharmony_ci root['hap_profile'] = dep['hap_profile'] 1305f9996aaSopenharmony_ci if dep.get('js_forms'): 1315f9996aaSopenharmony_ci root['js_forms'] = dep['js_forms'] 1325f9996aaSopenharmony_ci if dep.get('testrunner'): 1335f9996aaSopenharmony_ci root['testrunner'] = dep['testrunner'] 1345f9996aaSopenharmony_ci target_type = 'unresolved_assets' 1355f9996aaSopenharmony_ci for dep in deps.all(target_type): 1365f9996aaSopenharmony_ci if options.js2abc: 1375f9996aaSopenharmony_ci if isinstance(dep[target_type], list): 1385f9996aaSopenharmony_ci for ability_path in dep[target_type]: 1395f9996aaSopenharmony_ci root.get('js_assets').append(ability_path) 1405f9996aaSopenharmony_ci else: 1415f9996aaSopenharmony_ci root.get('js_assets').append(dep[target_type]) 1425f9996aaSopenharmony_ci else: 1435f9996aaSopenharmony_ci if isinstance(dep[target_type], list): 1445f9996aaSopenharmony_ci for ability_path in dep[target_type]: 1455f9996aaSopenharmony_ci root.get('ets_assets').append(ability_path) 1465f9996aaSopenharmony_ci else: 1475f9996aaSopenharmony_ci root.get('ets_assets').append(dep[target_type]) 1485f9996aaSopenharmony_ci build_utils.write_json(meta_data, options.output, only_if_changed=True) 1495f9996aaSopenharmony_ci 1505f9996aaSopenharmony_ci 1515f9996aaSopenharmony_ci# Collect assets entry according to config.json 1525f9996aaSopenharmony_cidef load_assets(options, assets, assets_type): 1535f9996aaSopenharmony_ci pre_path = assets[0] 1545f9996aaSopenharmony_ci pre_path = pre_path.rstrip('/') 1555f9996aaSopenharmony_ci with open(options.hap_profile) as profile: 1565f9996aaSopenharmony_ci config = json.load(profile) 1575f9996aaSopenharmony_ci 1585f9996aaSopenharmony_ci # In multi-ability cases, load the assets entry according to "srcPath" in config.json 1595f9996aaSopenharmony_ci if os.path.basename(pre_path) == 'js' or os.path.basename(pre_path) == 'ets': 1605f9996aaSopenharmony_ci assets = [] 1615f9996aaSopenharmony_ci for ability in config['module']['abilities']: 1625f9996aaSopenharmony_ci if assets_type == 'js': 1635f9996aaSopenharmony_ci if ability.__contains__('srcPath') and ability.get('srcLanguage') == assets_type: 1645f9996aaSopenharmony_ci assets.append(os.path.join(pre_path, ability['srcPath'])) 1655f9996aaSopenharmony_ci 1665f9996aaSopenharmony_ci # Load js form entry according to "jsComponentName" in config.json 1675f9996aaSopenharmony_ci if ability.__contains__('forms'): 1685f9996aaSopenharmony_ci for form in ability['forms']: 1695f9996aaSopenharmony_ci if form.__contains__('jsComponentName'): 1705f9996aaSopenharmony_ci options.js_forms.append(os.path.join(pre_path, form['jsComponentName'])) 1715f9996aaSopenharmony_ci else: 1725f9996aaSopenharmony_ci raise Exception('"module.abilities.ability.forms.form.jsComponentName" is required') 1735f9996aaSopenharmony_ci else: 1745f9996aaSopenharmony_ci if ability.__contains__('srcPath'): 1755f9996aaSopenharmony_ci assets.append(os.path.join(pre_path, ability['srcPath'])) 1765f9996aaSopenharmony_ci else: 1775f9996aaSopenharmony_ci pre_path = os.path.dirname(pre_path) 1785f9996aaSopenharmony_ci 1795f9996aaSopenharmony_ci # Load testrunner entry 1805f9996aaSopenharmony_ci if config['module'].__contains__('testRunner') and assets_type == 'js': 1815f9996aaSopenharmony_ci options.testrunner.append(os.path.join(pre_path, config['module']['testRunner']['srcPath'])) 1825f9996aaSopenharmony_ci if not assets: 1835f9996aaSopenharmony_ci assets.append(pre_path) 1845f9996aaSopenharmony_ci return assets 1855f9996aaSopenharmony_ci 1865f9996aaSopenharmony_ci 1875f9996aaSopenharmony_cidef main(): 1885f9996aaSopenharmony_ci parser = argparse.ArgumentParser() 1895f9996aaSopenharmony_ci 1905f9996aaSopenharmony_ci parser.add_argument('--output', 1915f9996aaSopenharmony_ci help='output meta data file', 1925f9996aaSopenharmony_ci required=True) 1935f9996aaSopenharmony_ci parser.add_argument('--type', help='type of module', required=True) 1945f9996aaSopenharmony_ci parser.add_argument('--raw-assets', nargs='+', help='raw assets directory') 1955f9996aaSopenharmony_ci parser.add_argument('--js-assets', nargs='+', help='js assets directory') 1965f9996aaSopenharmony_ci parser.add_argument('--ets-assets', nargs='+', help='ets assets directory') 1975f9996aaSopenharmony_ci parser.add_argument('--resources', nargs='+', help='resources directory') 1985f9996aaSopenharmony_ci parser.add_argument('--hap-path', help='path to output hap') 1995f9996aaSopenharmony_ci parser.add_argument('--depfile', help='path to .d file') 2005f9996aaSopenharmony_ci parser.add_argument('--deps-metadata', nargs="+", help='metadata deps') 2015f9996aaSopenharmony_ci parser.add_argument('--package-name', 2025f9996aaSopenharmony_ci help='package name for hap resources') 2035f9996aaSopenharmony_ci parser.add_argument('--hap-profile', help='path to hap profile') 2045f9996aaSopenharmony_ci parser.add_argument('--app-profile', help='path to app profile') 2055f9996aaSopenharmony_ci parser.add_argument('--unresolved-assets', nargs='+', help='unresolved assets directory') 2065f9996aaSopenharmony_ci parser.add_argument('--js2abc', 2075f9996aaSopenharmony_ci action='store_true', 2085f9996aaSopenharmony_ci default=False, 2095f9996aaSopenharmony_ci help='whether to transform js to ark bytecode') 2105f9996aaSopenharmony_ci options = parser.parse_args() 2115f9996aaSopenharmony_ci direct_deps = options.deps_metadata if options.deps_metadata else [] 2125f9996aaSopenharmony_ci 2135f9996aaSopenharmony_ci # js forms entry list 2145f9996aaSopenharmony_ci options.js_forms = [] 2155f9996aaSopenharmony_ci 2165f9996aaSopenharmony_ci # testrunner entry list 2175f9996aaSopenharmony_ci options.testrunner = [] 2185f9996aaSopenharmony_ci 2195f9996aaSopenharmony_ci if options.hap_profile: 2205f9996aaSopenharmony_ci if options.js_assets: 2215f9996aaSopenharmony_ci options.js_assets = load_assets(options, options.js_assets, 'js') 2225f9996aaSopenharmony_ci if options.ets_assets: 2235f9996aaSopenharmony_ci options.ets_assets = load_assets(options, options.ets_assets, 'ets') 2245f9996aaSopenharmony_ci if options.unresolved_assets: 2255f9996aaSopenharmony_ci options.unresolved_assets = load_assets(options, options.unresolved_assets, 'unresolved') 2265f9996aaSopenharmony_ci 2275f9996aaSopenharmony_ci possible_input_strings = [ 2285f9996aaSopenharmony_ci options.type, options.raw_assets, options.js_assets, options.ets_assets, options.resources, 2295f9996aaSopenharmony_ci options.hap_path, options.hap_profile, options.package_name, options.app_profile 2305f9996aaSopenharmony_ci ] 2315f9996aaSopenharmony_ci input_strings = [x for x in possible_input_strings if x] 2325f9996aaSopenharmony_ci 2335f9996aaSopenharmony_ci build_utils.call_and_write_depfile_if_stale( 2345f9996aaSopenharmony_ci lambda: write_meta_data(options, direct_deps), 2355f9996aaSopenharmony_ci options, 2365f9996aaSopenharmony_ci depfile_deps=direct_deps, 2375f9996aaSopenharmony_ci input_paths=direct_deps, 2385f9996aaSopenharmony_ci input_strings=input_strings, 2395f9996aaSopenharmony_ci output_paths=([options.output]), 2405f9996aaSopenharmony_ci force=False, 2415f9996aaSopenharmony_ci add_pydeps=False) 2425f9996aaSopenharmony_ci 2435f9996aaSopenharmony_ci 2445f9996aaSopenharmony_ciif __name__ == '__main__': 2455f9996aaSopenharmony_ci sys.exit(main()) 246