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
19import shutil
20import sys
21import os
22import time
23import threading
24from enum import Enum
25
26from containers.status import throw_exception
27from exceptions.ohos_exception import OHOSException
28from services.interface.build_file_generator_interface import BuildFileGeneratorInterface
29from containers.arg import Arg, ModuleType
30from util.system_util import SystemUtil
31from util.io_util import IoUtil
32from util.log_util import LogUtil
33from util.component_util import ComponentUtil
34from resources.global_var import CURRENT_OHOS_ROOT
35
36
37class CMDTYPE(Enum):
38    BUILD = 1
39    INSTALL = 2
40    PACKAGE = 3
41    PUBLISH = 4
42    UPDATE = 5
43
44
45class Hpm(BuildFileGeneratorInterface):
46
47    def __init__(self):
48        super().__init__()
49        self._regist_hpm_path()
50
51    def run(self):
52        self.execute_hpm_cmd(CMDTYPE.BUILD)
53
54    @throw_exception
55    def execute_hpm_cmd(self, cmd_type: int, **kwargs):
56        if cmd_type == CMDTYPE.BUILD:
57            return self._execute_hpm_build_cmd()
58        elif cmd_type == CMDTYPE.INSTALL:
59            return self._execute_hpm_install_cmd()
60        elif cmd_type == CMDTYPE.PACKAGE:
61            return self._execute_hpm_pack_cmd()
62        elif cmd_type == CMDTYPE.PUBLISH:
63            return self._execute_hpm_publish_cmd()
64        elif cmd_type == CMDTYPE.UPDATE:
65            return self._execute_hpm_update_cmd()
66        else:
67            raise OHOSException(
68                'You are tring to use an unsupported hpm cmd type "{}"'.format(cmd_type), '3001')
69
70    '''Description: Get hpm excutable path and regist it
71    @parameter: none
72    @return: Status
73    '''
74
75    @throw_exception
76    def _regist_hpm_path(self):
77        hpm_path = shutil.which("hpm")
78        if os.path.exists(hpm_path):
79            self.exec = hpm_path
80        elif os.path.exists(os.path.join(os.path.expanduser("~"), ".prebuilts_cache/hpm/node_modules/.bin/hpm")):
81            self.exec = os.path.join(os.path.expanduser("~"), ".prebuilts_cache/hpm/node_modules/.bin/hpm")
82        elif os.path.exists(os.path.join(CURRENT_OHOS_ROOT, ".prebuilts_cache/hpm/node_modules/.bin/hpm")):
83            self.exec = os.path.join(CURRENT_OHOS_ROOT, ".prebuilts_cache/hpm/node_modules/.bin/hpm")
84        else:
85            raise OHOSException(
86                'There is no hpm executable file at {}'.format(hpm_path), '0001')
87
88    @throw_exception
89    def _execute_hpm_build_cmd(self, **kwargs):
90        hpm_build_cmd = [self.exec, "build"] + self._convert_flags()
91        SystemUtil.exec_command(hpm_build_cmd)
92
93    @throw_exception
94    def _execute_hpm_install_cmd(self, **kwargs):
95        hpm_install_cmd = [self.exec, "install"] + self._convert_flags()
96        SystemUtil.exec_command(hpm_install_cmd)
97
98    @throw_exception
99    def _execute_hpm_pack_cmd(self, **kwargs):
100        hpm_pack_cmd = [self.exec, "pack", "-t"] + self._convert_flags()
101        SystemUtil.exec_command(hpm_pack_cmd)
102
103    @throw_exception
104    def _execute_hpm_publish_cmd(self, **kwargs):
105        hpm_publish_cmd = [self.exec, "publish", "-t"] + self._convert_flags()
106        SystemUtil.exec_command(hpm_publish_cmd)
107
108    @throw_exception
109    def _execute_hpm_update_cmd(self, **kwargs):
110        hpm_update_cmd = [self.exec, "update"] + self._convert_flags()
111        SystemUtil.exec_command(hpm_update_cmd)
112
113    '''Description: Convert all registed args into a list
114    @parameter: none
115    @return: list of all registed args
116    '''
117
118    def _convert_args(self) -> list:
119        args_list = []
120
121        for key, value in self.args_dict.items():
122            if isinstance(value, bool):
123                args_list.append('{}={}'.format(key, str(value).lower()))
124
125            elif isinstance(value, str):
126                args_list.append('{}="{}"'.format(key, value))
127
128            elif isinstance(value, int):
129                args_list.append('{}={}'.format(key, value))
130
131            elif isinstance(value, list):
132                args_list.append('{}="{}"'.format(key, "&&".join(value)))
133
134        return args_list
135
136    '''Description: Convert all registed flags into a list
137    @parameter: none
138    @return: list of all registed flags
139    '''
140
141    def _convert_flags(self) -> list:
142        flags_list = []
143
144        for key, value in self.flags_dict.items():
145            # 部件参数无需参数名
146            if key == "part_name":
147                flags_list.append(str(value))
148            else:
149                if value == '':
150                    flags_list.append('--{}'.format(key))
151                elif key == 'path':
152                    flags_list.extend(['--{}'.format(key), '{}'.format(str(value))])
153                else:
154                    flags_list.extend(['--{}'.format(key).lower(), '{}'.format(str(value)).lower()])
155
156        return flags_list
157
158    def _check_parts_validity(self, components: list):
159        illegal_components = []
160        for component in components:
161            if not ComponentUtil.search_bundle_file(component):
162                illegal_components.append(component)
163        if illegal_components:
164            raise OHOSException('ERROR argument "--parts": Invalid parts "{}". '.format(illegal_components))