1#!/usr/bin/env python3 2# coding: utf-8 3 4""" 5Copyright (c) 2024 Huawei Device Co., Ltd. 6Licensed under the Apache License, Version 2.0 (the "License"); 7you may not use this file except in compliance with the License. 8You may obtain a copy of the License at 9 10 http://www.apache.org/licenses/LICENSE-2.0 11 12Unless required by applicable law or agreed to in writing, software 13distributed under the License is distributed on an "AS IS" BASIS, 14WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15See the License for the specific language governing permissions and 16limitations under the License. 17""" 18 19import argparse 20import asyncio 21import json 22import os 23import shutil 24import sys 25 26import yaml 27 28 29def parse_configs(): 30 config_file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '../config.yaml') 31 with open(config_file_path, 'r', encoding='utf-8') as config_file: 32 configs = yaml.safe_load(config_file) 33 return configs 34 35 36def get_output_path_list(file_name): 37 configs = parse_configs() 38 download_list = configs['download_list'] 39 for item in download_list: 40 if item['name'] in file_name: 41 output_path_list = item['output_path_list'] 42 return output_path_list 43 44 45def is_mac(): 46 return sys.platform == 'darwin' 47 48 49def get_api_version(json_path): 50 with open(json_path, 'r') as uni: 51 uni_cont = uni.read() 52 uni_data = json.loads(uni_cont) 53 api_version = uni_data['apiVersion'] 54 return api_version 55 56 57def before_update_sdk(file_path): 58 pass 59 60 61def after_update_sdk(file_path, output_path): 62 if is_mac(): 63 add_executable_permission_for_mac(output_path) 64 # modify sdk version while api version is different from your download 65 modify_package_json(file_path, output_path) 66 67 68def add_executable_permission(file_path): 69 current_mode = os.stat(file_path).st_mode 70 new_mode = current_mode | 0o111 71 os.chmod(file_path, new_mode) 72 73 74def add_executable_permission_for_mac(sdk_path): 75 for item in os.listdir(sdk_path): 76 if item != '.DS_Store': 77 if item == 'toolchains': 78 add_executable_permission( 79 os.path.join(sdk_path, item, 'restool')) 80 add_executable_permission( 81 os.path.join(sdk_path, item, 'ark_disasm')) 82 elif item == 'ets': 83 add_executable_permission(os.path.join(sdk_path, item, 'build-tools', 84 'ets-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) 85 add_executable_permission(os.path.join(sdk_path, item, 'build-tools', 86 'ets-loader', 'bin', 'ark', 'build-mac', 'legacy_api8', 87 'bin', 'js2abc')) 88 elif item == 'js': 89 add_executable_permission(os.path.join(sdk_path, item, 'build-tools', 90 'ace-loader', 'bin', 'ark', 'build-mac', 'bin', 'es2abc')) 91 add_executable_permission(os.path.join(sdk_path, item, 'build-tools', 92 'ace-loader', 'bin', 'ark', 'build-mac', 'legacy_api8', 93 'bin', 'js2abc')) 94 95 96def get_output_path_api_version(output_path): 97 api_version = os.path.basename(output_path) 98 if api_version == 'openharmony': 99 parts = output_path.split(os.sep) 100 if len(parts) >= 2: 101 filename = parts[-2] 102 configs = parse_configs() 103 download_list = configs.get('download_list') 104 sdk_item = next((item for item in download_list if item.get('name') == 'sdk'), None) 105 api_version_file_map = sdk_item.get('api_version_file_name_map') if sdk_item else {} 106 api_version = api_version_file_map.get(filename) 107 else: 108 api_version = None 109 110 return api_version 111 112 113def modify_package_json(file_path, output_path): 114 output_path_version = get_output_path_api_version(output_path) 115 if output_path_version is None: 116 print('Modify package json failed, Please check your configuration file' 117 ' to ensure the mapping between API and file names is correct.') 118 return 119 api_version = get_api_version(os.path.join( 120 *[file_path, 'ets', 'oh-uni-package.json'])) 121 if output_path_version != api_version: 122 for file_name in os.listdir(output_path): 123 if file_name == '.DS_Store': 124 continue 125 package_json_path = os.path.join(output_path, rf'{file_name}/oh-uni-package.json') 126 with open(package_json_path, 'r+') as json_file: 127 json_file.seek(0) 128 data = json.load(json_file) 129 data['apiVersion'] = get_output_path_api_version(output_path) 130 json_file.seek(0) 131 json.dump(data, json_file, indent=2) 132 json_file.truncate() 133 134 135async def update_sdk_to_output_path(file_path, output_path): 136 before_update_sdk(file_path) 137 await copy_image_async(file_path, output_path) 138 after_update_sdk(file_path, output_path) 139 140 141async def update_dayu_to_output_path(file_path, output_path): 142 await copy_image_async(file_path, output_path) 143 144 145async def copy_image_async(file_path, output_path): 146 if os.path.exists(output_path): 147 loop = asyncio.get_event_loop() 148 await loop.run_in_executor(None, shutil.rmtree, output_path) 149 print(f'Copy from {file_path} to {output_path}, please wait!!!') 150 loop = asyncio.get_event_loop() 151 await loop.run_in_executor(None, shutil.copytree, file_path, output_path) 152 153 154async def update_image_async(file_path, output_path, semaphore): 155 await semaphore.acquire() 156 try: 157 update_task_mapping = { 158 "sdk": update_sdk_to_output_path, 159 "dayu": update_dayu_to_output_path 160 } 161 for task in update_task_mapping: 162 if task in file_path: 163 await update_task_mapping[task](file_path, output_path) 164 await asyncio.sleep(1) 165 print(f'File copied to {output_path} successfully') 166 break 167 finally: 168 semaphore.release() 169 170 171def parse_args(): 172 parser = argparse.ArgumentParser() 173 parser.add_argument('--sdkFilePath', type=str, dest='sdk_file_path', default=None, 174 help='specify which sdk image you want to copy') 175 parser.add_argument('--sdkOutputPath', type=str, dest='sdk_output_path', default=None, 176 nargs='+', 177 help='specify where you want to store the file') 178 parser.add_argument('--dayuFilePath', type=str, dest='dayu_file_path', default=None, 179 help='specify which dayu image you want to copy') 180 parser.add_argument('--dayuOutputPath', type=str, dest='dayu_output_path', default=None, 181 nargs='+', 182 help='specify where you want to store the file') 183 184 return parser.parse_args() 185 186 187async def start_update_image_task(file_path, output_path_list, max_async_tasks=3): 188 if output_path_list is None: 189 output_path_list = get_output_path_list(file_path) 190 semaphore = asyncio.Semaphore(max_async_tasks) 191 tasks = [asyncio.create_task(update_image_async(file_path, output_path, semaphore)) 192 for output_path in output_path_list] 193 194 await asyncio.gather(*tasks) 195 196 197async def run(): 198 arguments = parse_args() 199 200 if arguments.sdk_file_path is not None: 201 await start_update_image_task(arguments.sdk_file_path, arguments.sdk_output_path) 202 if arguments.dayu_file_path is not None: 203 await start_update_image_task(arguments.dayu_file_path, arguments.dayu_output_path) 204 if arguments.sdk_file_path is None and arguments.dayu_file_path is None: 205 print('please input which image you want to copy') 206 return 207 208 209if __name__ == '__main__': 210 asyncio.run(run()) 211