1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2021 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 sys 17import argparse 18import os 19import json 20import copy 21 22sys.path.append( 23 os.path.dirname(os.path.dirname(os.path.dirname( 24 os.path.abspath(__file__))))) 25from scripts.util import build_utils # noqa E402 26 27deps_metadta_cache = {} 28 29 30def get_all_deps(direct_deps): 31 if direct_deps == []: 32 return [] 33 deps = copy.deepcopy(direct_deps) 34 all_deps = set() 35 all_deps.update(deps) 36 while len(deps) > 0: 37 dep = deps.pop(0) 38 if dep not in deps_metadta_cache: 39 with open(dep) as dep_fp: 40 deps_metadta_cache[dep] = json.load(dep_fp).get('root') 41 for n in deps_metadta_cache[dep].get('metadata_deps'): 42 if n not in all_deps: 43 deps.append(n) 44 all_deps.add(n) 45 return sorted(list(all_deps)) 46 47 48def get_deps_metadata(deps): 49 return [deps_metadta_cache[d] for d in deps] 50 51 52def get_deps_of_type(deps_data, target_type): 53 return [d for d in deps_data if d['type'] == target_type] 54 55 56class Deps(object): 57 def __init__(self, direct_deps): 58 self.direct_deps = direct_deps 59 self.all_deps = get_all_deps(direct_deps) 60 self.all_deps_data = get_deps_metadata(self.all_deps) 61 62 def All(self, target_type): 63 return get_deps_of_type(self.all_deps_data, target_type) 64 65 66def write_meta_data(options, direct_deps): 67 meta_data = { 68 'root': { 69 'type': options.type, 70 'metadata_path': options.output, 71 'metadata_deps': direct_deps 72 } 73 } 74 root = meta_data['root'] 75 if options.type == 'app_profile': 76 root[options.type] = options.app_profile 77 root['resources'] = options.resources 78 if options.type == 'js_assets': 79 root[options.type] = options.js_assets 80 if options.type == 'ets_assets': 81 root[options.type] = options.ets_assets 82 if options.type == 'assets': 83 root[options.type] = options.raw_assets 84 if options.type == 'unresolved_assets': 85 root[options.type] = options.unresolved_assets 86 if options.type == 'resources': 87 deps = Deps(direct_deps) 88 root[options.type] = options.resources 89 package_name = options.package_name 90 root['package_name'] = package_name if package_name else "" 91 for target_type in ['app_profile']: 92 for dep in deps.All(target_type): 93 if root.get(target_type): 94 root.get(target_type).extend(dep[target_type]) 95 root.get('resources').extend(dep['resources']) 96 else: 97 root[target_type] = dep[target_type] 98 root['resources'] += dep['resources'] 99 if options.type == 'hap' or options.type == 'resources': 100 hap_profile = options.hap_profile 101 root['hap_profile'] = hap_profile if hap_profile else "" 102 if options.type == 'hap': 103 deps = Deps(direct_deps) 104 root['hap_path'] = options.hap_path 105 for target_type in ['js_assets', 'ets_assets', 'assets', 'resources']: 106 root[target_type] = [] 107 if options.js_assets: 108 root['js_assets'] = options.js_assets 109 if options.ets_assets: 110 root['ets_assets'] = options.ets_assets 111 if options.raw_assets: 112 root['assets'] = options.raw_assets 113 if options.resources: 114 root['resources'] = options.resources 115 for target_type in ['js_assets', 'ets_assets', 'assets', 'resources', 'app_profile']: 116 for dep in deps.All(target_type): 117 if root.get(target_type): 118 root.get(target_type).extend(dep[target_type]) 119 root.get('hap_profile').extend(dep['hap_profile']) 120 else: 121 root[target_type] = dep[target_type] 122 if dep.get('hap_profile'): 123 root['hap_profile'] = dep['hap_profile'] 124 target_type = 'unresolved_assets' 125 for dep in deps.All(target_type): 126 if options.js2abc: 127 if isinstance(dep[target_type], list): 128 for ability_path in dep[target_type]: 129 root.get('js_assets').append(ability_path) 130 else: 131 root.get('js_assets').append(dep[target_type]) 132 else: 133 if isinstance(dep[target_type], list): 134 for ability_path in dep[target_type]: 135 root.get('ets_assets').append(ability_path) 136 else: 137 root.get('ets_assets').append(dep[target_type]) 138 build_utils.write_json(meta_data, options.output, only_if_changed=True) 139 140 141def main(): 142 parser = argparse.ArgumentParser() 143 144 parser.add_argument('--output', 145 help='output meta data file', 146 required=True) 147 parser.add_argument('--type', help='type of module', required=True) 148 parser.add_argument('--raw-assets', nargs='+', help='raw assets directory') 149 parser.add_argument('--js-assets', nargs='+', help='js assets directory') 150 parser.add_argument('--ets-assets', nargs='+', help='ets assets directory') 151 parser.add_argument('--resources', nargs='+', help='resources directory') 152 parser.add_argument('--hap-path', help='path to output hap') 153 parser.add_argument('--depfile', help='path to .d file') 154 parser.add_argument('--deps-metadata', nargs="+", help='metadata deps') 155 parser.add_argument('--package-name', 156 help='package name for hap resources') 157 parser.add_argument('--hap-profile', help='path to hap profile') 158 parser.add_argument('--app-profile', help='path to app profile') 159 parser.add_argument('--unresolved-assets', help='unresolved assets directory') 160 parser.add_argument('--js2abc', 161 action='store_true', 162 default=False, 163 help='whether to transform js to ark bytecode') 164 options = parser.parse_args() 165 direct_deps = options.deps_metadata if options.deps_metadata else [] 166 167 if not options.app_profile and options.hap_profile and options.js_assets: 168 with open(options.hap_profile) as profile: 169 config = json.load(profile) 170 pre_path = options.js_assets[0] 171 options.js_assets = [] 172 if len(config['module']['abilities']) > 1 or config['module'].__contains__('testRunner'): 173 if config['module']['abilities'][0].get('srcLanguage') == 'js': 174 for ability in config['module']['abilities']: 175 options.js_assets.append(pre_path + '/' + ability['srcPath']) 176 if ability.__contains__('forms'): 177 options.js_assets.append(pre_path + '/' + ability['forms'][0]['name']) 178 else: 179 for ability in config['module']['abilities']: 180 if ability.__contains__('forms'): 181 options.js_assets.append(pre_path + '/' + ability['forms'][0]['name']) 182 else: 183 options.js_assets.append(pre_path) 184 if config['module'].__contains__('testRunner'): 185 options.js_assets.append(pre_path + '/' + config['module']['testRunner']['srcPath']) 186 187 if not options.app_profile and options.hap_profile and options.ets_assets: 188 with open(options.hap_profile) as profile: 189 config = json.load(profile) 190 pre_path = options.ets_assets[0] 191 options.ets_assets = [] 192 if len(config['module']['abilities']) > 1: 193 for ability in config['module']['abilities']: 194 options.ets_assets.append(pre_path + '/' + ability['srcPath']) 195 else: 196 options.ets_assets.append(pre_path) 197 198 if not options.app_profile and options.hap_profile and options.unresolved_assets: 199 with open(options.hap_profile) as profile: 200 config = json.load(profile) 201 pre_path = options.unresolved_assets 202 options.unresolved_assets = [] 203 if len(config['module']['abilities']) > 1: 204 for ability in config['module']['abilities']: 205 options.unresolved_assets.append(pre_path + '/' + ability['srcPath']) 206 else: 207 options.unresolved_assets.append(pre_path) 208 209 possible_input_strings = [ 210 options.type, options.raw_assets, options.js_assets, options.ets_assets, options.resources, 211 options.hap_path, options.hap_profile, options.package_name, options.app_profile 212 ] 213 input_strings = [x for x in possible_input_strings if x] 214 215 build_utils.call_and_write_depfile_if_stale( 216 lambda: write_meta_data(options, direct_deps), 217 options, 218 depfile_deps=direct_deps, 219 input_paths=direct_deps, 220 input_strings=input_strings, 221 output_paths=([options.output]), 222 force=False, 223 add_pydeps=False) 224 225 226if __name__ == '__main__': 227 sys.exit(main()) 228