• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-
3
4#
5# Copyright (c) 2020 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 os
20
21from hb_internal.common.utils import OHOSException
22from hb_internal.common.utils import exec_command
23from hb_internal.common.utils import read_yaml_file
24from hb_internal.common.config import Config
25
26
27class Patch():
28    """Patch class for hb_internal.build --patch parameter
29    Install the patch based on the configuration file.
30    """
31    def __init__(self):
32        self.config = Config()
33        # Patch configuration file path
34        self.patch_cfg = os.path.join(self.config.product_path, 'patch.yml')
35
36    def patch_make(self, cmd_args=None, reverse=False):
37        """Patch installation entry function
38
39        Args:
40            reverse (bool, optional): True if the patch is rolled back,
41                                      else False. Defaults to False.
42
43        Raises:
44            OHOSException: if configuration file does not exist.
45        """
46        patch_cfg = self.config.patch_cache
47        # Check whether the rollback is in progress
48        if not reverse:
49            # Try to update patch cache and check whether rollback is required
50            self.patch_cache_update()
51            patch_cfg = self.patch_cfg
52
53        if not os.path.isfile(patch_cfg):
54            raise OHOSException(f'{patch_cfg} not found, '
55                                'which "--patch" parameter needs')
56
57        patch_cfg_dict = read_yaml_file(patch_cfg)
58        for src_path, patch_list in patch_cfg_dict.items():
59            self.patch_apply(src_path, patch_list, reverse)
60
61    def patch_apply(self, src_path, patch_list, reverse=False):
62        """Run the patch installation command.
63
64        Args:
65            src_path (string): Path to which the patch needs to be installed
66            patch_list (list): List of paths for storing patches
67            reverse (bool, optional): True if the patch is rolled back,
68                                      else False. Defaults to False.
69
70        Raises:
71            OHOSException: src_path or patch_path is invalid,
72                           or the command fails to be executed.
73        """
74        src_path = os.path.join(self.config.root_path, src_path)
75        if not os.path.exists(src_path):
76            raise OHOSException(f'{src_path} not exist, stop applying patch')
77
78        cmd = ''
79        for patch in patch_list:
80            patch_path = os.path.join(self.config.root_path, patch)
81            if not os.path.isfile(patch_path):
82                patch_path = os.path.join(self.config.root_path,
83                                          src_path, patch)
84                if not os.path.isfile(patch_path):
85                    raise OHOSException(f'patch {patch} not exist for '
86                                        f'{src_path}, stop applying patch')
87            if reverse:
88                cmd = f'patch -p1 -R < {patch_path}'
89            else:
90                cmd = f'patch -p1 < {patch_path}'
91            try:
92                exec_command(cmd, log_path=self.config.log_path,
93                             cwd=src_path, shell=True)
94            except OHOSException as ohos_exception:
95                # Failed to roll back the patch, clear patch cache
96                self.config.patch_cache = None
97                raise ohos_exception
98
99    def patch_cache_update(self):
100        """Try to update patch cache and Check whether rollback is required
101        If patch_cache is None, no rollback is required,
102        otherwise roll back patch.
103        """
104        # patch_cache stores the configuration file of the last patch.
105        if self.config.patch_cache is not None:
106            self.patch_make(reverse=True)
107        # Update patch cache to current path configuration file path
108        self.config.patch_cache = self.patch_cfg
109
110
111if __name__ == "__main__":
112    patch = Patch()
113    patch.patch_make()
114