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