1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright (c) 2023 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import os 17 18from resources.config import Config 19from util.io_util import IoUtil 20from util.system_util import SystemUtil 21from exceptions.ohos_exception import OHOSException 22 23 24class Patch(): 25 """Patch class for hb_internal.build --patch parameter 26 Install the patch based on the configuration file. 27 """ 28 def __init__(self): 29 self.config = Config() 30 # Patch configuration file path 31 self.patch_cfg = os.path.join(self.config.product_path, 'patch.yml') 32 33 def patch_make(self, cmd_args=None, reverse=False): 34 """Patch installation entry function 35 36 Args: 37 reverse (bool, optional): True if the patch is rolled back, 38 else False. Defaults to False. 39 40 Raises: 41 OHOSException: if configuration file does not exist. 42 """ 43 patch_cfg = self.config.patch_cache 44 # Check whether the rollback is in progress 45 if not reverse: 46 # Try to update patch cache and check whether rollback is required 47 self.patch_cache_update() 48 patch_cfg = self.patch_cfg 49 50 if not os.path.isfile(patch_cfg): 51 raise OHOSException(f'{patch_cfg} not found, ' 52 'which "--patch" parameter needs', '0020') 53 54 patch_cfg_dict = IoUtil.read_yaml_file(patch_cfg) 55 for src_path, patch_list in patch_cfg_dict.items(): 56 self.patch_apply(src_path, patch_list, reverse) 57 58 def patch_apply(self, src_path, patch_list, reverse=False): 59 """Run the patch installation command. 60 61 Args: 62 src_path (string): Path to which the patch needs to be installed 63 patch_list (list): List of paths for storing patches 64 reverse (bool, optional): True if the patch is rolled back, 65 else False. Defaults to False. 66 67 Raises: 68 OHOSException: src_path or patch_path is invalid, 69 or the command fails to be executed. 70 """ 71 src_path = os.path.join(self.config.root_path, src_path) 72 if not os.path.exists(src_path): 73 raise OHOSException(f'{src_path} not exist, stop applying patch', '0021') 74 75 cmd = '' 76 for patch_item in patch_list: 77 patch_path = os.path.join(self.config.root_path, patch_item) 78 if not os.path.isfile(patch_path): 79 patch_path = os.path.join(self.config.root_path, 80 src_path, patch_item) 81 if not os.path.isfile(patch_path): 82 raise OHOSException(f'patch {patch_item} not exist for {src_path}, ' 83 'stop applying patch', '0022') 84 if reverse: 85 cmd = f'patch -p1 -R < {patch_path}' 86 else: 87 cmd = f'patch -p1 < {patch_path}' 88 try: 89 SystemUtil.exec_command(cmd, log_path=self.config.log_path, 90 cwd=src_path, shell=True) 91 except OHOSException as ohos_exception: 92 # Failed to roll back the patch, clear patch cache 93 self.config.patch_cache = None 94 raise ohos_exception 95 96 def patch_cache_update(self): 97 """Try to update patch cache and Check whether rollback is required 98 If patch_cache is None, no rollback is required, 99 otherwise roll back patch. 100 """ 101 # patch_cache stores the configuration file of the last patch. 102 if self.config.patch_cache is not None: 103 self.patch_make(reverse=True) 104 # Update patch cache to current path configuration file path 105 self.config.patch_cache = self.patch_cfg 106 107 108if __name__ == "__main__": 109 patch = Patch() 110 patch.patch_make() 111