From da80e4fcaaa9bbeac8df8bbd548391b3d38cbfbe Mon Sep 17 00:00:00 2001 From: René 'Necoro' Neumann Date: Tue, 4 Mar 2008 21:08:28 +0100 Subject: No more dict-hackery for the dependencies --- portato/backend/portage/package.py | 34 ++++----- portato/dependency.py | 151 +++++++++++++++++++++++++++++++++++++ 2 files changed, 167 insertions(+), 18 deletions(-) create mode 100644 portato/dependency.py (limited to 'portato') diff --git a/portato/backend/portage/package.py b/portato/backend/portage/package.py index 6ac34ba..e54d1cd 100644 --- a/portato/backend/portage/package.py +++ b/portato/backend/portage/package.py @@ -17,6 +17,7 @@ from .. import flags from .. import system from ..exceptions import BlockedException, PackageNotFoundException, DependencyCalcError from ...helper import debug, error, unique_array +from ...dependency import DependencyTree import portage, portage_dep @@ -305,33 +306,30 @@ class PortagePackage (Package): def get_dependencies (self): deps = " ".join(map(self.get_package_settings, ("RDEPEND", "PDEPEND", "DEPEND"))) deps = portage_dep.paren_reduce(deps) - depdir = {"global": set()} + + tree = DependencyTree() - def add (dir, deps): + def add (tree, deps): iter = (x for x in deps) for dep in iter: if dep.endswith("?"): - dep = dep[:-1] - if dep not in dir: - dir[dep] = {"global": set()} + ntree = tree.add_flag(dep[:-1]) n = iter.next() - if isinstance(n, list): - add(dir[dep], n) - else: - dir[dep]["global"].add(n) - elif dep == "||": - if not dep in dir: - dir[dep] = set() - + if not hasattr(n, "__iter__"): + n = (n,) + add(ntree, n) + + elif dep == "||": n = iter.next() # skip - if not isinstance(n, list): + if not hasattr(n, "__iter__"): n = tuple(n,) else: n = tuple(n) - dir[dep].add(n) + tree.add_or(n) + else: - dir["global"].add(dep) + tree.add(dep) - add(depdir, deps) - return depdir + add(tree, deps) + return tree diff --git a/portato/dependency.py b/portato/dependency.py new file mode 100644 index 0000000..718906f --- /dev/null +++ b/portato/dependency.py @@ -0,0 +1,151 @@ +# -*- coding: utf-8 -*- +# +# File: portato/dependency.py +# This file is part of the Portato-Project, a graphical portage-frontend. +# +# Copyright (C) 2008 René 'Necoro' Neumann +# This is free software. You may redistribute copies of it under the terms of +# the GNU General Public License version 2. +# There is NO WARRANTY, to the extent permitted by law. +# +# Written by René 'Necoro' Neumann + +from __future__ import absolute_import, with_statement + +from .helper import debug + +""" +Provides classes for the presentation of dependencies. +""" +__docformat__ = "restructuredtext" + +class Dependency (object): + + """ + A simple dependency as it also is noted inside ebuilds. + + :IVariables: + + dep : string + The dependency string. It is immutable. + """ + + def __init__ (self, dep): + """ + Creates a dependency out of a dep string. + + :param dep: dependency string + :type dep: string + """ + self.__dep = dep + + def __cmp__ (self, b): + return cmp(self.dep, b.dep) + + def __hash__ (self): + return hash(self.dep) + + def __str__ (self): + return "" % self.dep + + __repr__ = __str__ + + def __get_dep (self): + return self.__dep + + dep = property(__get_dep) + +class OrDependency (Dependency): + + """ + Dependency representing an "or". + + :note: Order is important. ``|| ( a b )`` != ``|| ( b a )`` + + :IVariables: + + dep : tuple(string,...) + The dependency strings. The tuple and the strings are immutable. + """ + + def __init__ (self, deps): + """ + Creates an or-dependency out of a list (or tuple) of deps. + + :param deps: The or'ed dependencies. + :type deps: iter + """ + + self.__dep = tuple(Dependency(dep) for dep in deps) + + def __str__ (self): + return "<|| %s>" % str(self.dep) + + __repr__ = __str__ + +class DependencyTree (object): + + """ + The DependencyTree shows all dependencies for a package and shows which useflags want which dependencies. + + :IVariables: + + deps : set(`Dependency`) + The list of dependencies which are not dependent on a useflag. + + flags : dict(string -> `DependencyTree`) + Holds the additional dependency trees per useflag. + """ + + def __init__ (self): + + self.deps = set() + self.flags = {} + + def add (self, dep, *moredeps): + """ + Adds one or more normal dependencies to the tree. + + :Parameters: + + dep : string + A dependency string. + + moredeps + More parameters are allowed :) + """ + self.deps.add(Dependency(dep)) + + for dep in moredeps: + self.deps.add(Dependency(dep)) + + def add_or (self, orlist): + """ + Adds a list of dependencies, which are or'ed. + + :param orlist: the dependency list + :type orlist: iter + """ + self.deps.add(OrDependency(orlist)) + + def add_flag (self, flag): + """ + Adds a new useflag to this tree. + For convenience the newly created sub-tree is returned. + + :param flag: the new flag + :rtype: `DependencyTree` + """ + if not flag in self.flags: + self.flags[flag] = DependencyTree() + + return self.get_flag_tree(flag) + + def get_flag_tree (self, flag): + """ + Returns the sub-tree of a specific tree. + + :raises KeyError: if the flag is not (yet) in this tree + :rtype: `DependencyTree` + """ + return self.flags[flag] -- cgit v1.2.3-54-g00ecf