示例#1
0
    def check_list_needs(self, pkg):
        """
        Check the needs from list against pkg

        @param pkg the plugin to check
        @return [] if everything is OK or a list of not used needs
                (name, op, version)
        """

        # Clone the list and drops out pkg
        lst = self.pkg_lst[:]
        lst.remove(pkg)

        conflicts_lst = []

        for provide in pkg.provides:
            p_name, p_op, p_ver = Version.extract_version(provide)

            for n_pkg in lst:
                for need in n_pkg.needs:
                    n_name, n_op, n_ver = Version.extract_version(need)

                    if n_name != p_name:
                        continue

                    # It's our need and we have a dep! :D
                    if n_op(p_ver, n_ver) is True:
                        conflicts_lst.append((n_pkg, n_op, n_ver))

        return conflicts_lst
示例#2
0
    def add_plugin_to_cache(self, pkg):
        """
        Exports the needs/provides/conflicts to the global dicts
        """

        for attr in ('conflicts', 'provides', 'needs'):
            for dep in getattr(pkg, attr, []):
                try:
                    name, op, ver = Version.extract_version(dep)
                    d = getattr(self, "who_%s" % attr)
                    d[name] = (op, ver, pkg)
                except Exception, err:
                    log.warning(err)
                    log.warning("Ignoring %s entry" % dep)
示例#3
0
    def check_conflicts(self, pkg):
        """
        Check the conflicts between pkg and global list of provides or
        loaded plugins.

        The return list contains entry like:
            (phase-number:int,
                (p_name:str, p_op:Operator, p_ver:Version) -> Provider
                (c_name:str, c_op:Operator, c_ver:Version) -> Conflicter
            )

        @param pkg the plugin to check
        @return [] if everything is OK or a list of plugins
                conflicting with pkg
        """

        lst = []

        #
        # 1) We should check the cache conflicts agains pkg

        for provide in pkg.provides:
            try:
                name, op, ver = Version.extract_version(provide)

                if not name in self.who_conflicts:
                    continue

                for c_op, c_ver, c_pkg in self.who_conflicts[name]:

                    # We could have
                    # c_op, c_ver >=, 2.0.0
                    # ver = 3.0.0

                    # We could have a None if a conflict entry didn't provide
                    # any version or operator

                    if c_op.op_str == '.' or c_op(ver, c_ver) is True:
                        lst.append(
                            (1,
                             (name, op, ver),	# Provider
                             (c_pkg, c_op, c_ver)	# Conflicter
                             )
                        )
            except Exception, err:
                log.error(err)
                log.error("1) Ignoring conflict entry ...")

                continue
示例#4
0
    def check_needs(self, pkg):
        """
        Check the needs between pkg and global list of provides.

        The return list contains entry like:
            (name:str, op:Operator, ver:Version) -> need not found

        @param pkg the plugin to check
        @return [] if everything is OK or a list of not resolved needs
        """

        # We have passed the conflict stage
        # so check for needs

        lst = []

        for need in pkg.needs:
            try:
                found = False
                name, op, ver = Version.extract_version(need)

                if not name in self.who_provides:
                    lst.append((name, op, ver))
                    continue

                for n_op, n_ver, n_pkg in self.who_provides[name]:
                    # for example we could have
                    # name, op, ver = dummy, >=, 2.0.0
                    # n_ver = 2.0.3

                    # TODO: check me
                    if op(n_ver, ver) is True or op(n_ver, ver) is None:
                        found = True
                        break

                # If we are here not applicable deps were found so add
                if not found:
                    lst.append((name, op, ver))

            except Exception, err:
                log.error(err)
                log.error("Ignoring need entry ...")

                continue
示例#5
0
    def get_need(self, reader, needstr, classname=None, need_module=False):
        """
        Usefull function to return an instance of needstr:classname

        @param reader a PluginReader object or None
        """
        lst = []

        if reader:
            # We create a list of needs for the same package
            for need in reader.needs:
                name, op, ver = Version.extract_version(need)

                if name == needstr:
                    lst.append((op, ver, name))

        from umit.pm.gui.plugins.engine import PluginEngine
        ret = PluginEngine().tree.get_provide(needstr, lst, need_module)

        log.debug(">>> Core.get_need() -> %s (module: %s)" %
                  (ret, need_module))

        if not ret:
            return None

        if not need_module:
            if not classname:
                log.debug(">>> Core.get_need(): No classname specified. " \
                          "Returning first instance")
                return ret[0]

            for instance in ret:
                if instance.__class__.__name__ == classname:
                    return instance
        else:
            # We need a module

            if len(ret) > 1:
                log.debug(">>> Core.get_need(): Returning the first module")

            return ret[0]

        return None
示例#6
0
    def get_need(self, reader, needstr, classname=None, need_module=False):
        """
        Usefull function to return an instance of needstr:classname

        @param reader a PluginReader object or None
        """
        lst = []

        if reader:
            # We create a list of needs for the same package
            for need in reader.needs:
                name, op, ver = Version.extract_version(need)

                if name == needstr:
                    lst.append((op, ver, name))

        from umit.pm.gui.plugins.engine import PluginEngine
        ret = PluginEngine().tree.get_provide(needstr, lst, need_module)

        log.debug(">>> Core.get_need() -> %s (module: %s)" % (ret, need_module))

        if not ret:
            return None

        if not need_module:
            if not classname:
                log.debug(">>> Core.get_need(): No classname specified. " \
                          "Returning first instance")
                return ret[0]

            for instance in ret:
                if instance.__class__.__name__ == classname:
                    return instance
        else:
            # We need a module

            if len(ret) > 1:
                log.debug(">>> Core.get_need(): Returning the first module")

            return ret[0]

        return None
示例#7
0
    def remove_plugin_from_cache(self, pkg):
        for attr in ('conflicts', 'provides', 'needs'):
            for dep in getattr(pkg, attr, []):
                try:
                    name, op, ver = Version.extract_version(dep)
                    d = getattr(self, "who_%s" % attr)

                    # It's more probably that the entry is in the last

                    for i in xrange(len(d[name]) - 1, -1, -1):
                        _op, _ver, _pkg = d[name][i]

                        if pkg == _pkg and \
                           ver == _ver and \
                           op == _op:
                            del d[name][i]

                    # Remove unused keys.
                    if not d[name]:
                        del d[name]

                except Exception, err:
                    log.warning(err)
                    log.warning("Ignoring %s entry" % dep)
示例#8
0
class PluginsTree(object):
    """
    Manages and tracks the loads/unloads of plugins objects
    """

    def __init__(self):
        """
        Create a new PluginsTree

        @param parent a PluginEngine instance
        """

        # A dict to trace plugin instances
        self.instances = {}
        self.modules = {}

        self.who_conflicts, \
            self.who_provides, \
            self.who_needs = DepDict(), DepDict(), DepDict()
        self.pkg_lst = list()

    def dump(self):
        log.info(">>> dump(): conflicts/provides/needs: %d / %d / %d" % \
              (
                  len(self.who_conflicts),
                  len(self.who_provides),
                  len(self.who_needs)
              )
        )

    def check_conflicts(self, pkg):
        """
        Check the conflicts between pkg and global list of provides or
        loaded plugins.

        The return list contains entry like:
            (phase-number:int,
                (p_name:str, p_op:Operator, p_ver:Version) -> Provider
                (c_name:str, c_op:Operator, c_ver:Version) -> Conflicter
            )

        @param pkg the plugin to check
        @return [] if everything is OK or a list of plugins
                conflicting with pkg
        """

        lst = []

        #
        # 1) We should check the cache conflicts agains pkg

        for provide in pkg.provides:
            try:
                name, op, ver = Version.extract_version(provide)

                if not name in self.who_conflicts:
                    continue

                for c_op, c_ver, c_pkg in self.who_conflicts[name]:

                    # We could have
                    # c_op, c_ver >=, 2.0.0
                    # ver = 3.0.0

                    # We could have a None if a conflict entry didn't provide
                    # any version or operator

                    if c_op.op_str == '.' or c_op(ver, c_ver) is True:
                        lst.append(
                            (1,
                             (name, op, ver),	# Provider
                             (c_pkg, c_op, c_ver)	# Conflicter
                             )
                        )
            except Exception, err:
                log.error(err)
                log.error("1) Ignoring conflict entry ...")

                continue

        #
        # 2) We should check the package conflicts against cache provides

        for conflict in pkg.conflicts:
            try:
                name, op, ver = Version.extract_version(conflict)

                if not name in self.who_provides:
                    continue

                # Only '=' operator presents:
                # providers['woot'] = [('=', '2.0', pkg1), ('=', '2.1', pkg2)]

                for p_op, p_ver, p_pkg in self.who_provides[name]:
                    # for example we could have
                    # name, op, ver = dummy, >=, 2.0.0
                    # p_ver = 2.0.3

                    # strict checking for avoid false results
                    # if None was returned
                    if op(p_ver, ver) is True:
                        # So we have a conflict. Just add to the list
                        lst.append(
                            (2,
                             (p_pkg, p_op, p_ver),   # Provider
                             (name, op, ver)	# Conflicter
                             )
                        )

            except Exception, err:
                log.error(err)
                log.error("2) Ignoring conflict entry ...")

                continue