build_depend.py 8.5 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 23 24
    """

    def __init__(self, pkg_name_list, db_list, self_build=0, history_dict=None):
25 26 27
        """
        init class
        """
28 29 30 31 32 33 34 35 36 37
        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 {}
38
        self.not_found_components = set()
39 40 41

    def build_depend_main(self):
        """
42 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
        Raises:
49 50
        """
        if not self.search_db.db_object_dict:
51
            return ResponseCode.DIS_CONNECTION_DB, None, None, set()
52 53 54 55 56

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

        if self._self_build == 1:
            self.self_build(self.pkg_name_list)
            if None in self.result_dict:
                del self.result_dict[None]
63 64 65 66 67
            # 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
68
            return ResponseCode.SUCCESS, self.result_dict, self.source_dict, self.not_found_components
69

70
        return ResponseCode.PARAM_ERROR, None, None,set()
71 72 73

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

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

90
        code, res_dict, not_fd_install = \
91 92
            InstallDepend(self.db_list).query_install_depend(search_list,
                                                             self.history_dicts)
93
        self.not_found_components.update(not_fd_install)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
        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):
        """
111
        Description: To create root node in self.result_dict and
112
            return the name of the source package to be found next time
113 114 115 116 117 118
        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:
119 120 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
        """
        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,
158
                        self.search_db.binary_search_database_for_first_time(obj.bin_name),
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
                        [
                            [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):
        """
180 181 182 183 184
        Description: Using recursion to find compilation dependencies
        Args:
            pkg_name_li: Source package name list
        Returns:
        Raises:
185 186
        """
        if not pkg_name_li:
187
            return
188 189

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

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

199 200 201 202
            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]

203 204
            if not obj.bin_name:
                continue
205

206 207 208 209
            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,
210
                    self.search_db.binary_search_database_for_first_time(obj.bin_name),
211 212 213 214 215 216 217 218 219 220 221
                    [
                        [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 \
222
                    obj.source_name not in self.source_dict and \
223
                    obj.source_name not in self.history_dicts:
224 225
                next_src_set.add(obj.source_name)

226 227 228 229 230
        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()
231 232
        self.self_build(next_src_set)

233
        return