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