build_depend.py 8.7 KB
Newer Older
1
#!/usr/bin/python3
2
"""
3 4
Description: Find compilation dependency of source package
class: BuildDepend
5 6 7 8 9 10
"""
from packageship.application.apps.package.function.searchdb import SearchDB
from packageship.application.apps.package.function.install_depend import InstallDepend
from packageship.application.apps.package.function.constants import ResponseCode, ListNode


11
class BuildDepend():
12
    """
13 14 15 16 17 18 19 20 21
    Description: Find compilation dependency of source package
    Attributes:
        pkg_name_list: List of package names
        db_list: List of database names
        self_build: Compile dependency conditions
        history_dict: Query history dict
        search_db:Query an instance of a database class
        result_dict:A dictionary to store the data that needs to be echoed
        source_dict:A dictionary to store the searched source code package name
22
        not_found_components: Contain the package not found components
23 24 25
    """

    def __init__(self, pkg_name_list, db_list, self_build=0, history_dict=None):
26 27 28
        """
        init class
        """
29 30 31 32 33 34 35 36 37 38
        self.pkg_name_list = pkg_name_list
        self._self_build = self_build

        self.db_list = db_list
        self.search_db = SearchDB(db_list)

        self.result_dict = dict()
        self.source_dict = dict()

        self.history_dicts = history_dict if history_dict else {}
39
        self.not_found_components = set()
40 41 42

    def build_depend_main(self):
        """
43 44 45 46 47 48
        Description: Entry function
        Args:
        Returns:
            ResponseCode: response code
            result_dict: Dictionary of query results
            source_dict: Dictionary of source code package
49
            not_found_components: Set of package not found components
50
        Raises:
51 52
        """
        if not self.search_db.db_object_dict:
53
            return ResponseCode.DIS_CONNECTION_DB, None, None, set()
54 55 56 57 58

        if self._self_build == 0:
            code = self.build_depend(self.pkg_name_list)
            if None in self.result_dict:
                del self.result_dict[None]
59
            return code, self.result_dict, None, self.not_found_components
60 61 62 63 64

        if self._self_build == 1:
            self.self_build(self.pkg_name_list)
            if None in self.result_dict:
                del self.result_dict[None]
65 66 67 68 69
            # There are two reasons for the current status code to return SUCCESS
            # 1, Other branches return three return values.
            #    Here, a place holder is needed to prevent unpacking errors during call
            # 2, This function is an auxiliary function of other modules.
            #    The status code is not the final display status code
70
            return ResponseCode.SUCCESS, self.result_dict, self.source_dict, self.not_found_components
71

72
        return ResponseCode.PARAM_ERROR, None, None, set()
73 74 75

    def build_depend(self, pkg_list):
        """
76 77 78 79 80 81
        Description: Compile dependency query
        Args:
             pkg_list:You need to find the dependent source package name
        Returns:
             ResponseCode: response code
        Raises:
82
        """
Z
zt 已提交
83 84
        res_status, build_list, not_fd_com_build = self.search_db.get_build_depend(pkg_list)
        self.not_found_components.update(not_fd_com_build)
85
        if not build_list:
86
            return res_status if res_status == ResponseCode.DIS_CONNECTION_DB else \
87
                ResponseCode.PACK_NAME_NOT_FOUND
88

89 90 91
        # create root node and get next search list
        search_list = self._create_node_and_get_search_list(build_list, pkg_list)

Z
zt 已提交
92
        code, res_dict, not_fd_com_install = \
93 94
            InstallDepend(self.db_list).query_install_depend(search_list,
                                                             self.history_dicts)
Z
zt 已提交
95
        self.not_found_components.update(not_fd_com_install)
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112
        if not res_dict:
            return code

        for k, values in res_dict.items():
            if k in self.result_dict:
                if ['root', None] in values[ListNode.PARENT_LIST]:
                    index = values[ListNode.PARENT_LIST].index(['root', None])
                    del values[ListNode.PARENT_LIST][index]

                self.result_dict[k][ListNode.PARENT_LIST].extend(values[ListNode.PARENT_LIST])
            else:
                self.result_dict[k] = values

        return ResponseCode.SUCCESS

    def _create_node_and_get_search_list(self, build_list, pkg_list):
        """
113
        Description: To create root node in self.result_dict and
114
            return the name of the source package to be found next time
115 116 117 118 119 120
        Args:
            build_list:List of binary package names
            pkg_list: List of binary package names
        Returns:
             the name of the source package to be found next time
        Raises:
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
        """
        search_set = set()
        search_list = []
        for obj in build_list:
            if not obj.search_name:
                continue

            if obj.search_name + "_src" not in self.result_dict:
                self.result_dict[obj.search_name + "_src"] = [
                    'source',
                    obj.search_version,
                    obj.db_name,
                    [
                        ['root', None]
                    ]
                ]
                search_set.add(obj.search_name)

            if not obj.bin_name:
                continue

            if obj.bin_name in self.history_dicts:
                self.result_dict[obj.bin_name] = [
                    self.history_dicts[obj.bin_name][ListNode.SOURCE_NAME],
                    self.history_dicts[obj.bin_name][ListNode.VERSION],
                    self.history_dicts[obj.bin_name][ListNode.DBNAME],
                    [
                        [obj.search_name, 'build']
                    ]
                ]
            else:
                if obj.bin_name in search_list:
                    self.result_dict[obj.bin_name][ListNode.PARENT_LIST].append([
                        obj.search_name, 'build'
                    ])
                else:
                    self.result_dict[obj.bin_name] = [
                        obj.source_name,
                        obj.version,
160
                        self.search_db.binary_search_database_for_first_time(obj.bin_name),
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
                        [
                            [obj.search_name, 'build']
                        ]
                    ]
                    search_list.append(obj.bin_name)

        if search_set and len(search_set) != len(pkg_list):
            temp_set = set(pkg_list) - search_set
            for name in temp_set:
                self.result_dict[name + "_src"] = [
                    None,
                    None,
                    'NOT_FOUND',
                    [
                        ['root', None]
                    ]
                ]
        return search_list

    def self_build(self, pkg_name_li):
        """
182 183 184 185 186
        Description: Using recursion to find compilation dependencies
        Args:
            pkg_name_li: Source package name list
        Returns:
        Raises:
187 188
        """
        if not pkg_name_li:
189
            return
190 191

        next_src_set = set()
192 193
        _, bin_info_lis, not_fd_com = self.search_db.get_build_depend(pkg_name_li)
        self.not_found_components.update(not_fd_com)
194
        if not bin_info_lis:
195
            return
196

197
            # generate data content
198
        search_name_set = set()
199 200
        for obj in bin_info_lis:

201 202 203 204
            search_name_set.add(obj.search_name)
            if obj.search_name not in self.source_dict:
                self.source_dict[obj.search_name] = [obj.db_name, obj.search_version]

205 206
            if not obj.bin_name:
                continue
207

208 209 210 211
            if obj.bin_name not in self.result_dict:
                self.result_dict[obj.bin_name] = [
                    obj.source_name if obj.source_name else None,
                    obj.version if obj.version else None,
212
                    self.search_db.binary_search_database_for_first_time(obj.bin_name),
213 214 215 216 217 218 219 220 221 222 223
                    [
                        [obj.search_name, "build"]
                    ]
                ]
            else:
                node = [obj.search_name, "build"]
                node_list = self.result_dict[obj.bin_name][-1]
                if node not in node_list:
                    node_list.append(node)

            if obj.source_name and \
224
                    obj.source_name not in self.source_dict and \
225
                    obj.source_name not in self.history_dicts:
226 227
                next_src_set.add(obj.source_name)

228 229 230 231 232
        not_found_pkg = set(pkg_name_li) - search_name_set
        for pkg_name in not_found_pkg:
            if pkg_name not in self.source_dict:
                self.source_dict[pkg_name] = ['NOT FOUND', 'NOT FOUND']
        not_found_pkg.clear()
233 234
        self.self_build(next_src_set)

235
        return