1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4# 5# Copyright (c) 2023 Huawei Device Co., Ltd. 6# Licensed under the Apache License, Version 2.0 (the "License"); 7# you may not use this file except in compliance with the License. 8# You may obtain a copy of the License at 9# 10# http://www.apache.org/licenses/LICENSE-2.0 11# 12# Unless required by applicable law or agreed to in writing, software 13# distributed under the License is distributed on an "AS IS" BASIS, 14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15# See the License for the specific language governing permissions and 16# limitations under the License. 17# 18 19 20import os 21import sys 22import subprocess 23import json 24import time 25 26sys.path.append(os.path.dirname(os.path.abspath(__file__))) # ohos/build/hb dir 27sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) # ohos/build dir 28sys.path.append( 29 os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'lite')) # ohos/build/lite dir 30 31from containers.arg import Arg, ModuleType 32from containers.status import throw_exception 33from resources.global_var import ARGS_DIR 34from resources.global_var import CURRENT_OHOS_ROOT 35from exceptions.ohos_exception import OHOSException 36 37from services.preloader import OHOSPreloader 38from services.loader import OHOSLoader 39from services.gn import Gn 40from services.ninja import Ninja 41from services.hpm import Hpm 42from services.hdc import Hdc 43 44from resolver.build_args_resolver import BuildArgsResolver 45from resolver.set_args_resolver import SetArgsResolver 46from resolver.clean_args_resolver import CleanArgsResolver 47from resolver.env_args_resolver import EnvArgsResolver 48from resolver.tool_args_resolver import ToolArgsResolver 49from resolver.indep_build_args_resolver import IndepBuildArgsResolver 50from resolver.install_args_resolver import InstallArgsResolver 51from resolver.package_args_resolver import PackageArgsResolver 52from resolver.publish_args_resolver import PublishArgsResolver 53from resolver.update_args_resolver import UpdateArgsResolver 54from resolver.push_args_resolver import PushArgsResolver 55 56from modules.interface.module_interface import ModuleInterface 57from modules.interface.build_module_interface import BuildModuleInterface 58from modules.interface.set_module_interface import SetModuleInterface 59from modules.interface.env_module_interface import EnvModuleInterface 60from modules.interface.clean_module_interface import CleanModuleInterface 61from modules.interface.tool_module_interface import ToolModuleInterface 62from modules.interface.indep_build_module_interface import IndepBuildModuleInterface 63from modules.interface.install_module_interface import InstallModuleInterface 64from modules.interface.package_module_interface import PackageModuleInterface 65from modules.interface.publish_module_interface import PublishModuleInterface 66from modules.interface.update_module_interface import UpdateModuleInterface 67from modules.interface.push_module_interface import PushModuleInterface 68 69from modules.ohos_build_module import OHOSBuildModule 70from modules.ohos_set_module import OHOSSetModule 71from modules.ohos_clean_module import OHOSCleanModule 72from modules.ohos_env_module import OHOSEnvModule 73from modules.ohos_tool_module import OHOSToolModule 74from modules.ohos_indep_build_module import OHOSIndepBuildModule 75from modules.ohos_install_module import OHOSInstallModule 76from modules.ohos_package_module import OHOSPackageModule 77from modules.ohos_publish_module import OHOSPublishModule 78from modules.ohos_update_module import OHOSUpdateModule 79from modules.ohos_push_module import OHOSPushModule 80 81from helper.separator import Separator 82from util.log_util import LogUtil 83from util.system_util import SystemUtil 84 85 86class Main(): 87 @staticmethod 88 @throw_exception 89 def main(): 90 main = Main() 91 module_initializers = { 92 'build': main._init_indep_build_module if main._is_indep_build() else main._init_build_module, 93 'init': main._init_hb_init_module, 94 'indep_build': main._init_indep_build_module, 95 'set': main._init_set_module, 96 'env': main._init_env_module, 97 'clean': main._init_clean_module, 98 'tool': main._init_tool_module, 99 'install': main._init_install_module, 100 'package': main._init_package_module, 101 'publish': main._init_publish_module, 102 'update': main._init_update_module, 103 'push': main._push_module 104 } 105 106 module_type = sys.argv[1] 107 if module_type == 'help': 108 for all_module_type in ModuleType: 109 LogUtil.hb_info(Separator.long_line) 110 LogUtil.hb_info(Arg.get_help(all_module_type)) 111 exit() 112 113 if module_type not in module_initializers: 114 raise OHOSException(f'There is no such option {module_type}', '0018') 115 116 start_time = SystemUtil.get_current_time() 117 module = module_initializers[module_type]() 118 try: 119 module.run() 120 if module_type == 'build': 121 LogUtil.hb_info('Cost Time: {}'.format(SystemUtil.get_current_time() - start_time)) 122 except KeyboardInterrupt: 123 for file in os.listdir(ARGS_DIR): 124 if file.endswith('.json') and os.path.exists(os.path.join(ARGS_DIR, file)): 125 os.remove(os.path.join(ARGS_DIR, file)) 126 print('User abort') 127 return -1 128 else: 129 return 0 130 131 def _set_path(self): 132 user_home = os.path.expanduser("~") 133 prebuilts_cache_path = os.path.join(user_home, '.prebuilts_cache', 'hpm', 'node_modules', '.bin') 134 nodejs_bin_path = os.path.join(CURRENT_OHOS_ROOT, 'prebuilts', 'build-tools', 'common', 'nodejs', 'current', 135 'bin') 136 os.environ['PATH'] = prebuilts_cache_path + os.pathsep + nodejs_bin_path + os.pathsep + os.environ['PATH'] 137 138 def _init_build_module(self) -> BuildModuleInterface: 139 args_dict = Arg.parse_all_args(ModuleType.BUILD) 140 141 if args_dict.get("product_name").arg_value != '': 142 set_args_dict = Arg.parse_all_args(ModuleType.SET) 143 set_args_resolver = SetArgsResolver(set_args_dict) 144 ohos_set_module = OHOSSetModule(set_args_dict, set_args_resolver, "") 145 ohos_set_module.set_product() 146 147 preloader = OHOSPreloader() 148 loader = OHOSLoader() 149 generate_ninja = Gn() 150 ninja = Ninja() 151 build_args_resolver = BuildArgsResolver(args_dict) 152 153 return OHOSBuildModule(args_dict, build_args_resolver, preloader, loader, generate_ninja, ninja) 154 155 def _init_hb_init_module(self): 156 subprocess.run([os.path.join(CURRENT_OHOS_ROOT, 'build', 'prebuilts_config.sh')]) 157 sys.exit() 158 159 def _init_set_module(self) -> SetModuleInterface: 160 Arg.clean_args_file() 161 args_dict = Arg.parse_all_args(ModuleType.SET) 162 set_args_resolver = SetArgsResolver(args_dict) 163 from services.menu import Menu 164 menu = Menu() 165 return OHOSSetModule(args_dict, set_args_resolver, menu) 166 167 def _init_env_module(self) -> EnvModuleInterface: 168 if sys.argv[2] in ['--sshkey', '-s']: 169 self._set_path() 170 subprocess.run(['hpm', 'config', 'set', 'loginUser', str(sys.argv[3])]) 171 subprocess.run(['hpm', 'gen-keys']) 172 key_path = os.path.join(os.path.expanduser("~"), '.hpm', 'key', 'publicKey_' + sys.argv[3] + '.pem') 173 print(f'Please add the content of {key_path} to https://repo.harmonyos.com/#/cn/profile/sshkeys') 174 sys.exit() 175 args_dict = Arg.parse_all_args(ModuleType.ENV) 176 env_args_resolver = EnvArgsResolver(args_dict) 177 return OHOSEnvModule(args_dict, env_args_resolver) 178 179 def _init_clean_module(self) -> CleanModuleInterface: 180 args_dict = Arg.parse_all_args(ModuleType.CLEAN) 181 clean_args_resolever = CleanArgsResolver(args_dict) 182 return OHOSCleanModule(args_dict, clean_args_resolever) 183 184 def _init_tool_module(self) -> ToolModuleInterface: 185 Arg.clean_args_file() 186 args_dict = Arg.parse_all_args(ModuleType.TOOL) 187 generate_ninja = Gn() 188 tool_args_resolever = ToolArgsResolver(args_dict) 189 return OHOSToolModule(args_dict, tool_args_resolever, generate_ninja) 190 191 def _init_indep_build_module(self) -> IndepBuildModuleInterface: 192 self._set_path() 193 Arg.clean_args_file_by_type(ModuleType.INDEP_BUILD) 194 args_dict = Arg.parse_all_args(ModuleType.INDEP_BUILD) 195 hpm = Hpm() 196 indep_build_args_resolver = IndepBuildArgsResolver(args_dict) 197 return OHOSIndepBuildModule(args_dict, indep_build_args_resolver, hpm) 198 199 def _is_indep_build(self) -> bool: 200 if "--indep-build" in sys.argv[2:] or "-i" in sys.argv[2:] or (len(sys.argv) == 4 and sys.argv[-1] == "-t"): 201 return True 202 env_args_dict = Arg.read_args_file(ModuleType.ENV) 203 return env_args_dict.get("indep_build").get("argDefault") 204 205 def _init_install_module(self) -> InstallModuleInterface: 206 self._set_path() 207 Arg.clean_args_file_by_type(ModuleType.INSTALL) 208 args_dict = Arg.parse_all_args(ModuleType.INSTALL) 209 hpm = Hpm() 210 install_args_resolver = InstallArgsResolver(args_dict) 211 return OHOSInstallModule(args_dict, install_args_resolver, hpm) 212 213 def _init_package_module(self) -> PackageModuleInterface: 214 self._set_path() 215 Arg.clean_args_file_by_type(ModuleType.PACKAGE) 216 args_dict = Arg.parse_all_args(ModuleType.PACKAGE) 217 hpm = Hpm() 218 package_args_resolver = PackageArgsResolver(args_dict) 219 return OHOSPackageModule(args_dict, package_args_resolver, hpm) 220 221 def _init_publish_module(self) -> PublishModuleInterface: 222 self._set_path() 223 args_dict = Arg.parse_all_args(ModuleType.PUBLISH) 224 hpm = Hpm() 225 publish_args_resolver = PublishArgsResolver(args_dict) 226 return OHOSPublishModule(args_dict, publish_args_resolver, hpm) 227 228 def _init_update_module(self) -> UpdateModuleInterface: 229 self._set_path() 230 Arg.clean_args_file_by_type(ModuleType.UPDATE) 231 args_dict = Arg.parse_all_args(ModuleType.UPDATE) 232 hpm = Hpm() 233 update_args_resolver = UpdateArgsResolver(args_dict) 234 return OHOSUpdateModule(args_dict, update_args_resolver, hpm) 235 236 def _init_push_module(self) -> PushModuleInterface: 237 args_dict = Arg.parse_all_args(ModuleType.PUSH) 238 hdc = Hdc() 239 update_args_resolver = PushArgsResolver(args_dict) 240 return OHOSPushModule(args_dict, update_args_resolver, hdc) 241 242 def _push_module(self): 243 if sys.argv[2] in ['-h', '-help', 'h', 'help']: 244 print('Please use the command "hb push" like this: hb push component_name -t device_num') 245 sys.exit() 246 check_hdc = subprocess.run(['hdc', '-v'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 247 if check_hdc.returncode != 0: 248 print("Error: Please make sure 'hdc' is installed and properly configured.") 249 sys.exit() 250 check_device = subprocess.run(['hdc', 'list', 'targets'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, 251 text=True) 252 if check_device.stdout.strip() == "[Empty]": 253 print("Error: Device is not connected.") 254 sys.exit() 255 if len(check_device.stdout.strip().split('\n')) == 1: 256 device = check_device.stdout.strip() 257 else: 258 device = sys.argv[4] 259 if device not in check_device.stdout: 260 print("Error: Wrong device number") 261 sys.exit() 262 subprocess.run(["hdc", "-t", str(device), "shell", "mount", "-o", "rw,remount", "/"], check=True, 263 stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 264 default = os.path.join(CURRENT_OHOS_ROOT, "out", "default") 265 with open(os.path.join(default, "build_configs", "component_mapping.json"), 'r') as r: 266 single_component_path = json.load(r).get("single_component_path") 267 part_path = next(iter(single_component_path.values())) 268 with open(os.path.join(CURRENT_OHOS_ROOT, part_path, "bundle.json"), 'r') as r: 269 bundle = json.load(r) 270 push_list = bundle.get("deployment") 271 if push_list: 272 if not isinstance(push_list, list): 273 print("Error: Deployment value format error, should be in list format!") 274 for one_push in push_list: 275 if one_push.get("src") and not os.path.exists(os.path.join(CURRENT_OHOS_ROOT, one_push.get("src"))): 276 print("Error: The path in src does not exist, please modify the src path!") 277 if one_push.get("src") and one_push.get("target"): 278 subprocess.run( 279 ["hdc", "-t", str(device), "file", "send", os.path.join(CURRENT_OHOS_ROOT, one_push.get("src")), 280 one_push.get("target")], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 281 print("hb push success!") 282 sys.exit() 283 284 285if __name__ == "__main__": 286 sys.exit(Main.main()) 287