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, judge_indep 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 len(sys.argv) > 2 and 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 cwd = os.getcwd() 193 if not os.path.exists(os.path.join(cwd, 'build', 'indep_configs', 'build_indep.sh')): 194 print("ERROR: you are running hb build command in wrong dir!") 195 sys.exit() 196 self._set_path() 197 Arg.clean_args_file_by_type(ModuleType.INDEP_BUILD) 198 args_dict = Arg.parse_all_args(ModuleType.INDEP_BUILD) 199 hpm = Hpm() 200 indep_build_args_resolver = IndepBuildArgsResolver(args_dict) 201 return OHOSIndepBuildModule(args_dict, indep_build_args_resolver, hpm) 202 203 def _is_indep_build(self) -> bool: 204 if judge_indep(): 205 return True 206 env_args_dict = Arg.read_args_file(ModuleType.ENV) 207 return env_args_dict.get("indep_build").get("argDefault") 208 209 def _init_install_module(self) -> InstallModuleInterface: 210 self._set_path() 211 Arg.clean_args_file_by_type(ModuleType.INSTALL) 212 args_dict = Arg.parse_all_args(ModuleType.INSTALL) 213 hpm = Hpm() 214 install_args_resolver = InstallArgsResolver(args_dict) 215 return OHOSInstallModule(args_dict, install_args_resolver, hpm) 216 217 def _init_package_module(self) -> PackageModuleInterface: 218 self._set_path() 219 Arg.clean_args_file_by_type(ModuleType.PACKAGE) 220 args_dict = Arg.parse_all_args(ModuleType.PACKAGE) 221 hpm = Hpm() 222 package_args_resolver = PackageArgsResolver(args_dict) 223 return OHOSPackageModule(args_dict, package_args_resolver, hpm) 224 225 def _init_publish_module(self) -> PublishModuleInterface: 226 self._set_path() 227 args_dict = Arg.parse_all_args(ModuleType.PUBLISH) 228 hpm = Hpm() 229 publish_args_resolver = PublishArgsResolver(args_dict) 230 return OHOSPublishModule(args_dict, publish_args_resolver, hpm) 231 232 def _init_update_module(self) -> UpdateModuleInterface: 233 self._set_path() 234 Arg.clean_args_file_by_type(ModuleType.UPDATE) 235 args_dict = Arg.parse_all_args(ModuleType.UPDATE) 236 hpm = Hpm() 237 update_args_resolver = UpdateArgsResolver(args_dict) 238 return OHOSUpdateModule(args_dict, update_args_resolver, hpm) 239 240 def _init_push_module(self) -> PushModuleInterface: 241 args_dict = Arg.parse_all_args(ModuleType.PUSH) 242 hdc = Hdc() 243 update_args_resolver = PushArgsResolver(args_dict) 244 return OHOSPushModule(args_dict, update_args_resolver, hdc) 245 246 def _push_module(self): 247 if sys.argv[2] in ['-h', '-help', 'h', 'help']: 248 print('Please use the command "hb push" like this: hb push component_name -t device_num') 249 sys.exit() 250 check_hdc = subprocess.run(['hdc', '-v'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 251 if check_hdc.returncode != 0: 252 print("Error: Please make sure 'hdc' is installed and properly configured.") 253 sys.exit() 254 check_device = subprocess.run(['hdc', 'list', 'targets'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, 255 text=True) 256 if check_device.stdout.strip() == "[Empty]": 257 print("Error: Device is not connected.") 258 sys.exit() 259 if len(check_device.stdout.strip().split('\n')) == 1: 260 device = check_device.stdout.strip() 261 else: 262 device = sys.argv[4] 263 if device not in check_device.stdout: 264 print("Error: Wrong device number") 265 sys.exit() 266 subprocess.run(["hdc", "-t", str(device), "shell", "mount", "-o", "rw,remount", "/"], check=True, 267 stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 268 default = os.path.join(CURRENT_OHOS_ROOT, "out", "default") 269 with open(os.path.join(default, "build_configs", "component_mapping.json"), 'r') as r: 270 single_component_path = json.load(r).get("single_component_path") 271 part_path = next(iter(single_component_path.values())) 272 with open(os.path.join(CURRENT_OHOS_ROOT, part_path, "bundle.json"), 'r') as r: 273 bundle = json.load(r) 274 push_list = bundle.get("deployment") 275 if push_list: 276 if not isinstance(push_list, list): 277 print("Error: Deployment value format error, should be in list format!") 278 for one_push in push_list: 279 if one_push.get("src") and not os.path.exists(os.path.join(CURRENT_OHOS_ROOT, one_push.get("src"))): 280 print("Error: The path in src does not exist, please modify the src path!") 281 if one_push.get("src") and one_push.get("target"): 282 subprocess.run( 283 ["hdc", "-t", str(device), "file", "send", os.path.join(CURRENT_OHOS_ROOT, one_push.get("src")), 284 one_push.get("target")], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) 285 print("hb push success!") 286 sys.exit() 287 288 289if __name__ == "__main__": 290 sys.exit(Main.main()) 291