build_depend.py 8.2 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 38 39 40
        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 {}

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

        if self._self_build == 0:
            code = self.build_depend(self.pkg_name_list)
            if None in self.result_dict:
                del self.result_dict[None]
            return code, self.result_dict, None

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

        return ResponseCode.PARAM_ERROR, None, None

    def build_depend(self, pkg_list):
        """
73 74 75 76 77 78
        Description: Compile dependency query
        Args:
             pkg_list:You need to find the dependent source package name
        Returns:
             ResponseCode: response code
        Raises:
79 80 81 82
        """
        res_status, build_list = self.search_db.get_build_depend(pkg_list)

        if not build_list:
83
            return res_status if res_status == ResponseCode.DIS_CONNECTION_DB else \
84
                ResponseCode.PACK_NAME_NOT_FOUND
85

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        # create root node and get next search list
        search_list = self._create_node_and_get_search_list(build_list, pkg_list)

        code, res_dict = \
            InstallDepend(self.db_list).query_install_depend(search_list,
                                                             self.history_dicts)
        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):
        """
109
        Description: To create root node in self.result_dict and
110
            return the name of the source package to be found next time
111 112 113 114 115 116
        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:
117 118 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
        """
        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,
156
                        self.search_db.binary_search_database_for_first_time(obj.bin_name),
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
                        [
                            [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):
        """
178 179 180 181 182
        Description: Using recursion to find compilation dependencies
        Args:
            pkg_name_li: Source package name list
        Returns:
        Raises:
183 184
        """
        if not pkg_name_li:
185
            return
186 187 188 189 190

        next_src_set = set()
        _, bin_info_lis = self.search_db.get_build_depend(pkg_name_li)

        if not bin_info_lis:
191
            return
192

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

197 198 199 200
            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]

201 202
            if not obj.bin_name:
                continue
203

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

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

231
        return