build_depend.py 8.0 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 11 12
"""
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


class BuildDepend:
    """
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 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
        """
        res_status, build_list = self.search_db.get_build_depend(pkg_list)

        if not build_list:
            return res_status if res_status == \
                                 ResponseCode.DIS_CONNECTION_DB else \
                ResponseCode.PACK_NAME_NOT_FOUND
        # 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 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
        """
        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,
                        obj.db_name,
                        [
                            [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 195 196 197
        for obj in bin_info_lis:

            if not obj.bin_name:
                continue
198 199 200 201
            # for first loop, init the source_dict
            if not self.source_dict:
                for src_name in pkg_name_li:
                    self.source_dict[src_name] = [obj.db_name, obj.search_version]
202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217
            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,
                    obj.db_name if obj.db_name else "NOT_FOUND",
                    [
                        [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 \
218 219
                    obj.source_name not in self.source_dict and \
                        obj.source_name not in self.history_dicts:
220 221 222 223 224 225
                self.source_dict[obj.source_name] = [obj.db_name,
                                                     obj.version]
                next_src_set.add(obj.source_name)

        self.self_build(next_src_set)

226
        return