• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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